LISP语言中的绑定概念
在LISP程序语言上投标的概念是什么? 是动态的还是静态的??或者没有人 任何人都可以在这方面提供支持。在Lisp中,“变量”被描述为名称->值关联,称为“绑定”;绑定的集合名为“环境” 例如,当您有一个函数时LISP语言中的绑定概念,lisp,Lisp,在LISP程序语言上投标的概念是什么? 是动态的还是静态的??或者没有人 任何人都可以在这方面提供支持。在Lisp中,“变量”被描述为名称->值关联,称为“绑定”;绑定的集合名为“环境” 例如,当您有一个函数时 (defun square (x) (* x x)) 然后用 (square 12) 在函数输入时,将建立一个新的“环境”,其中包含“绑定”x->12 在类似C++的语言中,这些概念通常称为“堆栈框架”(环境)和“局部变量”(绑定)。但是,请注意,“堆栈帧”概念无法正确描述L
(defun square (x)
(* x x))
然后用
(square 12)
在函数输入时,将建立一个新的“环境”,其中包含“绑定”x->12
在类似C++的语言中,这些概念通常称为“堆栈框架”(环境)和“局部变量”(绑定)。但是,请注意,“堆栈帧”概念无法正确描述Lisp中发生的情况,例如在捕获过程中:
(defun kmul (k)
;; returns a function that multiplies by k its argument
(lambda (x) (* x k)))
(let ((k12 (kmul 12)))
(print (funcall k12 3))) ; --> 36
此处,enter上的kmul
将有一个包含绑定的环境k->12
,并将返回一个将“捕获”此绑定的未命名函数。调用返回的未命名函数时,绑定仍将处于活动状态,这是使用简单的“堆栈帧”无法实现的;绑定的集合名为“环境”
例如,当您有一个函数时
(defun square (x)
(* x x))
然后用
(square 12)
在函数输入时,将建立一个新的“环境”,其中包含“绑定”x->12
在类似C++的语言中,这些概念通常称为“堆栈框架”(环境)和“局部变量”(绑定)。但是,请注意,“堆栈帧”概念无法正确描述Lisp中发生的情况,例如在捕获过程中:
(defun kmul (k)
;; returns a function that multiplies by k its argument
(lambda (x) (* x k)))
(let ((k12 (kmul 12)))
(print (funcall k12 3))) ; --> 36
此处,enter上的
kmul
将有一个包含绑定的环境k->12
,并将返回一个将“捕获”此绑定的未命名函数。调用返回的未命名函数时,绑定仍将处于活动状态,这是使用简单的“堆栈帧”无法实现的。LISP在公共LISP中同时具有这两种功能。所有全局变量都是动态绑定的,或者在CL术语中是特殊的
(defparameter*par*5)
(defvar*var*10)
(defun测试()
(+*par**var*))
(测试);==>15
(let((*par*9)(*var*21))
(测试));==>30
现在,如果变量是静态的,那么对test
的两个调用的结果应该是相同的,但事实并非如此
如果您同时命名了一个与全局绑定同名的本地绑定,那么您可能会从使用这些名称的其他调用中得到奇怪的结果,并且很难发现它们。为了避免将全局变量与词汇变量混淆,有一种使用*耳罩*
的命名约定,这可能是CL中最重要的约定
其他任何事物都是静态的(或词法的)
不过还有其他类型的LISP。Scheme只有静态绑定。因此,上述转换为Scheme的示例每次将产生15
。静态绑定的一个特殊之处是闭包:
(定义(获取过程初始参数)
(λargs)
(应用过程初始参数(参数)))
(定义add10(get proc+10));+和10在结果中绑定
(定义div10(get proc/10));-和10在结果中是绑定的
(添加10 2);==>12
(div10 2);==>5.
PicoLisp只有动态绑定,因此闭包在中不存在,因此如果您尝试与Scheme示例相同的方法,则在调用生成的过程时,
proc
和initial arg
不会被定义。只要不混合使用静态变量名和动态变量名,它就可以在CL中工作。LISP和普通的LISP一样,两者都有。所有全局变量都是动态绑定的,或者在CL术语中是特殊的
(defparameter*par*5)
(defvar*var*10)
(defun测试()
(+*par**var*))
(测试);==>15
(let((*par*9)(*var*21))
(测试));==>30
现在,如果变量是静态的,那么对test
的两个调用的结果应该是相同的,但事实并非如此
如果您同时命名了一个与全局绑定同名的本地绑定,那么您可能会从使用这些名称的其他调用中得到奇怪的结果,并且很难发现它们。为了避免将全局变量与词汇变量混淆,有一种使用*耳罩*
的命名约定,这可能是CL中最重要的约定
其他任何事物都是静态的(或词法的)
不过还有其他类型的LISP。Scheme只有静态绑定。因此,上述转换为Scheme的示例每次将产生15
。静态绑定的一个特殊之处是闭包:
(定义(获取过程初始参数)
(λargs)
(应用过程初始参数(参数)))
(定义add10(get proc+10));+和10在结果中绑定
(定义div10(get proc/10));-和10在结果中是绑定的
(添加10 2);==>12
(div10 2);==>5.
PicoLisp只有动态绑定,因此闭包在中不存在,因此如果您尝试与Scheme示例相同的方法,则在调用生成的过程时,
proc
和initial arg
不会被定义。只要不混合使用静态变量名和动态变量名,它就可以在CL中工作。Lisp中有两个主要的绑定概念。我会任意地称第一个为传统的,也许是错误的,而第二个为ANSI Lisp
第一个传统概念是,绑定是在某个环境的上下文中,符号和保存值的位置之间的关联。这正是Kent Pitman在论文中所描述的内容,文中给出了绑定的定义:
绑定是标识符与可放置Lisp对象的位置的配对
当我们评估一个符号时,我们会查看适当的绑定环境(从词法环境开始,如果存在这样的情况,则返回到动态环境)。在环境中我们发现了一些c