alpha变换
首先alpha变换引出了绑定变量和自由变量的概念。一个函数体内使用的变量有几种,第一种是函数的参数,第二种是函数内部定义的局部变量,第三种是既不是函数的参数也不是函数内部定义的局部变量的的变量。第一种和第二种被称为绑定变量,第三种称为自由变量。
其次alpha变换引出了两个函数相同的概念,如果对于所有的相同的输入,两个函数给出的输出都是一样的。那么两个函数被认为是相同的。
alpha变化有两点:
1. 可以给函数的参数给任意的名字,如果要改变函数参数的名字那么对应的把函数内部的该变量的所有出现都改变为新的变量名。
比如
function f(x) { return x+2}
function h(y) {return y+2}
f(-2)==h(-2)
f和h是一样的函数。后面的一个函数的定义只不过把第一个函数中的使用的参数x全部替换成了y。
2. 函数内部的实现部分调用的函数的定义如果使用了和调用它的函数的参数一样的名字,那么他们的意义是相互独立的,改变两者的参数的名字需要独立进行。
比如
//A,h函数在f函数内部定义。
function f(x){
function h(x){ return x*2;}
return h(2)+x(-3);
}
function f'(y){
function h(x){return x*2;}
return h(2)+y(-3);
}
f(Math.abs)==f'(Math.abs);
//B,h函数在f函数外部定义
function h(x){ return x*2;}
function f(x){ return h(2)+x(-3); }
function f'(y){ return h(2)+y(-3); }
也就是说h函数的参数x和内部h函数的参数x不是同一个x,做替换的时候你可以独立的替换f函数中的x的使用,或者h函数中x的使用。A代码实例中我们把函数定义在f函数体之内,但是这里仅仅是为了更好的说明问题。也可以定义在f之外(B代码实例),不过恰好它也使用了和f函数一样的参数的名字x。
对于alpha变化,第一眼看过去感觉怎么都是废话,感觉这不都是明摆着的嘛。对于程序员使用编程语言来说,的确是这样的。但是如果要去写语言的解释器编译器的时候,上面的定义就很重要了,因为对于替换求值模型来说,最后可以说是名值对应的关系,那么名字作为键值就尤其重要了。