LISP编程语言的绑定概念

时间:2016-11-26 09:14:22

标签: lisp

  

双语LISP程序语言的概念是什么?

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

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

4 个答案:

答案 0 :(得分:2)

Common Lisp中的LISP同时具有这两者。所有全局变量都是动态绑定的,或者在CL术语中是特殊的。

(defparameter *par* 5)
(defvar *var* 10)

(defun test ()
  (+ *par* *var*))

(test) ; ==> 15

(let ((*par* 9) (*var* 21))
  (test)) ; ==> 30

现在,如果变量是静态的,那么对test的两次调用都应该有相同的结果,但事实并非如此。

如果你巧合地命名了一个与全局同名的本地绑定,你可能会从使用这些的其他调用中得到奇怪的结果,并且它们很难被发现。为了不将全局变量与词法变量混淆,使用*earmuffs*的命名约定可能是CL中最重要的约定。

其他所有东西都是静态的(或词汇)。

但是还有其他类型的LISP。例如。 Scheme只有静态绑定。因此,上面转换为Scheme的示例每次都会产生15。关于静态绑定的一个特殊之处是闭包:

(define (get-proc proc initial-arg)
  (lambda args
    (apply proc initial-arg args)))

(define add10 (get-proc + 10)) ; the + and 10 are bound in the result
(define div10 (get-proc / 10)) ; the - and 10 are bound in the result

(add10 2) ; ==> 12
(div10 2) ; ==> 5

PicoLisp只有动态绑定,因此不存在闭包因此procinitial-arg如果您尝试与方案相同的话,我们调用生成的过程时将无法定义glMapBufferglBufferData例。只要不混合静态和动态变量名称,它就可以在CL中工作。

答案 1 :(得分:1)

在Lisp中,“变量”被描述为名称 - >值关联,称为“绑定”;一组绑定被命名为“environment”。

例如,您有一个功能

(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

此处的kmul输入将包含一个包含绑定k -> 12的环境,并将返回一个未命名的函数,该函数将“捕获”此绑定。当调用返回的未命名函数时,绑定将仍然存在,使用简单的“堆栈帧”无法实现。

答案 2 :(得分:1)

静态绑定,这是大多数语言中的规范,这意味着变量的值仅由声明该变量的程序的部分(函数,过程,块等)确定,并且该变量为该部分之外无法访问。动态绑定意味着变量的值取决于程序执行的整个历史记录,并且变量可以在程序中的任何位置访问,但是可以在进入程序的一部分及其所调用的所有内容时设置该值并在该部分退出时恢复。

从历史上看,Lips在解释器中具有动态绑定,在编译器中具有静态和动态绑定,并具有声明来解决此问题。 Scheme和Common Lisp消除了这种差异,使静态绑定成为默认设置,但仍保留了动态绑定。 Perl还从使用let进行动态绑定开始,但现在也具有与my进行静态绑定。现在只有少数Lisps将动态绑定设置为默认或唯一选择,尤其是Elisp,Picolisp和newLisp。但是,Picolisp does provide closures提供了词法绑定,而newLisp通过大量使用命名空间来解决动态绑定的问题(原则上,如果每个函数都有自己的变量命名空间,则动态和静态绑定是等效的。) >

答案 3 :(得分:0)

Lisp中有两个主要的绑定概念。我将任意调用第一个传统的,可能是错误的,第二个是ANSI Lisp。

第一个传统概念是绑定是在某些环境的上下文中,在符号和保存值的位置之间的关联。这正是Kent Pitman在论文"Technical Issues of Separation in Lisp Function Cells and Value Cells"中描述的内容,其中 binding 的定义在这些词中给出:

  

绑定是标识符与可以放置Lisp对象的位置的配对。

当我们评估一个符号时,我们会通过适当的环境来查看绑定(从词汇环境开始,如果有这样的事情,则回到动态环境中)。在环境中,我们发现一些与符号相关联的单元格,并且在该单元格内部是一个保存值的存储盒。这很清楚。例如,当在评估期间输入新的词法范围时,会创建一些框并通过新环境中的条目与符号相关联,这就是我们如何获得“新鲜绑定”。

在ANSI Common Lisp中,上述术语被 synecdoche 取代,其中ANSI CL术语绑定仅指上述绑定的一个组件:它是一个符号与其之间的关联。也就是说,只是放入存储箱的东西。或者,您可能认为它不是 synecdoche ,而是更高级别的视图:将变量连接到框(如果有的话)并从那里到值的整个机制是“绑定” “:

  

绑定 n。 name name 表示的关联。 “词汇绑定是名称与其价值之间的词汇关联。”当术语绑定命名空间的名称限定时,例如“变量”或“函数”,它会限制对指定的命名空间的绑定,如:“let建立变量绑定。”或“let建立变量的绑定。” [ANSI CL词汇表条目]

ANSI CL并不否认存在存储箱。例如,ANSI CL中的所有符号都有一个“值单元格”:

  

值单元格 n。繁体(符号 place ,其中包含由此命名的动态变量(如果有) 符号符号值 访问。请参阅单元格。 [ANSI CL词汇表条目]

只是符号和盒子之间的关联不是所谓的绑定。

即使未绑定为动态变量的符号仍然具有值单元格(TNIL和关键字符号除外),不言而喻:但请注意关键字支持函数绑定)。对于动态变量 unbound (由于从未被绑定或受makunbound影响)并不意味着“没有值单元格”。

动态绑定的Common Lisp模型是值单元格保存值,或者以某种方式表示缺少值。例如,实现可以将值单元格表示为具有两个槽的对象:一个保持值,一个布尔槽,如果值单元格当前绑定则为true,如果未绑定则为false。或者值单元格只能有一个插槽,并且某些特殊对象(只有实现知道,而不是用户代码)可以存储为值单元格中的值,以指示“此单元格未绑定”。

因此,这些是绑定的两个主要概念:与环境中的位置的关联,以及“绑定”的synecdochal使用仅仅是这样一个位置的值。这产生了两种可能的“未绑定”含义:不与某个位置建立关联(在环境中没有条目),或者不与某个值建立关联(尽管与环境中的位置有关联) )。

如果你正在进行Lisp对话,那么明确是有帮助的,因为这些区别可能会导致误解,因为各方使用的定义略有不同。

相关问题