中国佛山营销网站建设,网站 代理 备案 费用吗,郑州贸网站建设公司,常见的网页编辑工具Lisp-1 vs Lisp-2[1]Scheme的求值模型非常简单#xff1a;只是用一个名字空间#xff0c;所有表达式中相应位置的值应该是明确的。Common Lisp和Scheme最大的不同是#xff0c;函数名字空间和数据的名字空间是分离的。操作函数名字空间的语句包括#xff0c;defun#xff…Lisp-1 vs Lisp-2[1]Scheme的求值模型非常简单只是用一个名字空间所有表达式中相应位置的值应该是明确的。Common Lisp和Scheme最大的不同是函数名字空间和数据的名字空间是分离的。操作函数名字空间的语句包括defunfletlabelsdefmethod和defgeneric等方法。要用函数名作为另一个函数的参数来传递函数时需要使用function特殊操作符或者使用# 。我们称Scheme的变量模型为Lisp-1Common Lisp的变量模型是Lisp-2.绑定在编程语言中绑定是变量名变量标识符和对象保存于内存中的存储单元数据或代码的映射关系。在这个绑定过程中是作用域有密不可分的关系作用域决定了哪个变量绑定了哪个存储单元。为变量建立绑定之后就可以通过变量名来引用其所绑定的值。绑定的具体含义可以参考下图词法作用域lexical scoping词法作用域又叫静态作用域static scope。顾名思义词法变量即是使用词法作用域的变量。在词法作用域里一个变量的变量名只能在一个函数或一段代码区域 block 内存在此时变量名才会绑定到变量的值。词法变量拥有不确定的生存期即从时间上来讲一个词法变量可以在任意的时间里持续存在取决于该变量需要被使用(reference)多久。 词法作用域里对于函数体中的一个符号不会逐层检查函数的调用链而是检查函数定义时的外部环境即捕捉的是函数定义时该符号的绑定。动态作用域dynamic scoping使用动态作用域的变量叫做动态(dynamic)变量有时也叫做特殊(special)变量。动态作用域里每个变量名变量标识符都拥有一个全局的绑定栈。引入一个与动态变量同名的局部变量会为此变量名创建一个新的变量绑定并将其压入此变量名的全局绑定栈中一个全局的变量名变量标识符总是引用当前其栈顶的绑定当使用该变量绑定的代码执行完毕即程序控制流离开了此变量的作用域该变量绑定就会从此变量名的全局绑定栈中被弹出该变量绑定就失效。 动态作用域表示的范围是不确定的可从任何位置访问一个动态变量取决于它们在什么地方被绑定。动态变量拥有动态的生存期。因容易引起误会而需要注意的是不确定的作用域和动态生存期的组合经常被错误地称为动态作用域dynamic scope。 动态作用域里函数执行遇到一个符号会由内向外逐层检查函数的调用链并打印第一次遇到的那个绑定的值。最外层的绑定即是全局状态下的那个值。 Common Lisp的例子请看下面的代码(let ((y 7))(defun foo (x)(print x)(print y)))(let ((y 5))(foo 1))我们通过SLIM执行后可以得到输出1和7这说明Common Lisp使用的是词法作用域。在foo中寻找y的绑定时它检查函数foo的词法上下文。再请看下面代码(let ((y 7))(defun foo (x)(print x)(print y)(setq y ( y 2))))(let ((y 5))(foo 1)(foo 1))(let ((y 5))(foo 2))我们通过SLIM执行后我们会看到17192和11。在例子中的第一个let表里定义了一个变量符号名为y并绑定了值7那么这个y的作用域就是这个let表区域。 foo函数定义在这个区域内其内部会使用到一个符号名为y的变量。 那么在词法作用域的情况下当foo被调用时其会查找其定义的环境有没有符号名y的变量可以绑定如果有则把foo中符号y的值绑定在这里就是7。 并且这里foo中的y和外部let中的y共享一个值都是对这个值的引用并不是拷贝了一个新值。参考^https://en.wikipedia.org/wiki/Common_Lisp#The_function_namespace