LISP语言中的绑定概念

LISP语言中的绑定概念,lisp,Lisp,在LISP程序语言上投标的概念是什么? 是动态的还是静态的??或者没有人 任何人都可以在这方面提供支持。在Lisp中,“变量”被描述为名称->值关联,称为“绑定”;绑定的集合名为“环境” 例如,当您有一个函数时 (defun square (x) (* x x)) 然后用 (square 12) 在函数输入时,将建立一个新的“环境”,其中包含“绑定”x->12 在类似C++的语言中,这些概念通常称为“堆栈框架”(环境)和“局部变量”(绑定)。但是,请注意,“堆栈帧”概念无法正确描述L

在LISP程序语言上投标的概念是什么?

是动态的还是静态的??或者没有人

任何人都可以在这方面提供支持。

在Lisp中,“变量”被描述为名称->值关联,称为“绑定”;绑定的集合名为“环境”

例如,当您有一个函数时

(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