简体   繁体   English

什么是自由变量和绑定变量?

[英]What are Free and Bound variables?

I've been programming for a long time (too long, actually), but I'm really struggling to get a handle on the terms "Free Variables" and "Bound Variables".我已经编程了很长时间(实际上太久了),但我真的很难掌握术语“自由变量”和“绑定变量”。

Most of the "explanations" I've found online start by talking about topics like Lambda calculus and Formal logic, or Axiomatic Semantics.我在网上找到的大多数“解释”都是从讨论 Lambda 演算和形式逻辑或公理语义等主题开始的。 which makes me want to reach for my revolver .这让我想伸手去拿我的左轮手枪

Can someone explain these two terms, ideally from an implementation perspective.有人可以从实现的角度解释这两个术语吗? Can they exist in compiled languages, and what low-level code do they translate to?它们可以存在于编译语言中吗,它们翻译成什么样的低级代码?

A free variable is a variable used in some function that its value depends on the context where the function is invoked , called or used.自由变量是在某些函数中使用的变量,其值取决于调用、调用或使用函数的上下文。 For example, in math terms, z is a free variable because is not bounded to any parameter.例如,在数学术语中, z是一个自由变量,因为它不受任何参数的限制。 x is a bounded variable : x是一个有界变量

f(x) = x * z

In programming languages terms, a free variable is determined dynamically at run time searching the name of the variable backwards on the function call stack .编程语言术语中,自由变量是在运行时动态确定的,在函数调用堆栈上向后搜索变量的名称。

A bounded variable evaluation does not depend on the context of the function call.界变量评估不依赖于函数调用的上下文。 This is the most common modern programming languages variable type.这是现代编程语言中最常见的变量类型。 Local variables, global variables and parameters are all bounded variables.局部变量、全局变量和参数都是有界变量。

A free variable is somewhat similar to the " pass by name " convention of some ancient programming languages.自由变量有点类似于一些古代编程语言的“ 按名称传递”约定。

Let's say you have a function f that just prints some variable:假设您有一个函数f只打印一些变量:

def f():
    print(X)

This is Python.这是 Python。 While X is not a local variable, its value follows the Python convention: it searches upwards on the chain of the blocks where the function is defined until it reaches the top level module.虽然X不是局部变量,但它的值遵循 Python 约定:它在定义函数的块链上向上搜索,直到它到达顶级模块。

Since in Python the value of X is determined by the function declaration context, we say that X is a bounded variable.因为在 Python 中X的值是由函数声明上下文决定的,所以我们说X是一个有界变量。

Hypothetically, if X were a free variable, this should print 10:假设,如果X是一个自由变量,这应该打印 10:

X = 2

def f():
    print(X)

def g():
    # X is a local variable to g, shadowing the global X
    X = 10
    f()

In Python, this code prints 2 because both X variables are bounded.在 Python 中,此代码打印 2,因为两个X变量都是有界的。 The local X variable on g is bounded as a local variable, and the one on f is bounded to the global X . g上的局部X变量作为局部变量有界, f上的局部变量有界于全局X

Implementation执行

The implementation of a programming language with free variables needs to take care the context on where each function is called, and for every free variable use some reflection to find which variable to use.具有自由变量的编程语言的实现需要注意调用每个函数的上下文,并且对于每个自由变量使用一些反射来查找要使用的变量。

The value of a free variable can not be generally determined at compile time, since is heavily determined by the run time flow and the call stack.自由变量的值通常不能在编译时确定,因为在很大程度上取决于运行时流程和调用堆栈。

Whether a variable is free or bound is relative;变量是自由变量还是绑定变量是相对的; it depends on the fragment of code you are looking at.这取决于您正在查看的代码片段。

In this fragment, x is bound:在这个片段中, x被绑定:

function(x) {return x + x;};

And here, x occurs free:在这里, x自由出现:

return x + x;

In other words, freeness is a property of the context.换句话说,自由度是上下文的属性。 You don't say " x is a free variable" or " x is a bound variable," but instead identify the context you are talking about: " x is free in the expression E ."您不会说“ x是一个自由变量”或“ x是一个绑定变量”,而是指出您正在谈论的上下文:“ x在表达式E 中是自由的”。 For this reason, the same variable x can be either free or bound depending on which fragment of code you are talking about.出于这个原因,同一个变量x可以是自由的,也可以是绑定的,这取决于您所谈论的代码片段。 If the fragment contains the variable's binding site (for example, it is listed in the function arguments) then it is bound, if not, it is free.如果片段包含变量的绑定站点(例如,它在函数参数中列出),则它是绑定的,否则,它是免费的。

Where the free/bound distinction is important from an implementation perspective is when you are implementing how variable substitution works (eg what happens when you apply arguments to a function.) Consider the evaluation steps:从实现的角度来看,自由/绑定区别很重要的地方是当您实现变量替换的工作方式时(例如,当您将参数应用于函数时会发生什么。)考虑评估步骤:

(function(x) {return x + x;})(3);
=> 3 + 3
=> 6

This works fine because x is free in the body of the function.这很好用,因为x在函数体中是自由的。 If x was bound in the body of the function, however, our evaluation would need to be careful:但是,如果x绑定在函数体中,我们的评估就需要小心了:

(function(x) {return (function(x){return x * 2;})(x + x);})(3);
=> (function(x){return x * 2;})(3 + 3); // careful to leave this x alone for now!
=> (function(x){return x * 2;})(6);
=> 6 * 2
=> 12

If our implementation didn't check for bound occurrences, it could have replaced the bound x for 3 and given us the wrong answer:如果我们的实现没有检查绑定出现,它可能已经将绑定 x 替换为3并给了我们错误的答案:

(function(x) {return (function(x){return x * 2;})(x + x);})(3);
=> (function(x){return 3 * 2;})(3 + 3); // Bad! We substituted for a bound x!
=> (function(x){return 3 * 2;})(6);
=> 3 * 2
=> 6

Also, it should be clarified that free vs. bound is a property of the syntax (ie the code itself), not a property of how a the code is evaluated at run-time.此外,应该澄清的是,free 与 bound 是语法的属性(即代码本身),而不是在运行时如何评估代码的属性。 vz0 talks about dynamically scoped variables, which are somewhat related to, but not synonymous with, free variables. vz0 谈论动态范围的变量,它们与自由变量有些相关,但不是同义词。 As vz0 correctly describes, dynamic variable scope is a language feature that allows expressions that contains free variables to be evaluated by looking at the run-time call-stack to find the value of a variable that shares the same name.正如 vz0 正确描述的那样,动态变量范围是一种语言功能,它允许通过查看运行时调用堆栈来评估包含自由变量的表达式,以查找共享相同名称的变量的值。 However, It still makes sense to talk about free occurrences of variables in languages that don't allow dynamic scope: you would just get an error (like " x is not defined") if you were to try to evaluate an such expression in these languages.但是,在不允许动态作用域的语言中讨论变量的自由出现仍然有意义:如果您尝试在这些表达式中计算这样的表达式,您只会得到一个错误(如“ x未定义”)语言。

And I can't restrain myself: I hope one day you can find the strength to put your revolvers away when people mention lambda calculus!我无法克制自己:我希望有一天当人们提到 lambda 演算时,你能找到力量把你的左轮手枪收起来! Lambda calculus is a good tool for thinking about variables and bindings because it is an extremely minimal programming language that supports variables and substitution and nothing else .演算是对有关变量和绑定思维的好工具,因为它是一个极小的编程语言支持变量和替代而已 Real-world programming languages contain a lot of other junk (like dynamic scope, for example) that obscures the essence.现实世界的编程语言包含许多其他混淆了本质的垃圾(例如动态范围)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM