Lisp如何动态分配符号? Lisp符号的基础数据结构/机制?

时间:2012-03-30 18:00:04

标签: list dynamic lisp runtime symbols

Lisp允许您在类似

的列表中定义诸如A和B之类的符号
(setf mylist '(+ 1 2 A))

然后您可以随时返回并将A设置为值,例如。 (set 'A 100)。此时,您可以执行(eval mylist)并返回103.然后,您可以反复将A重新分配给任何新值。

似乎Lisp正在保存文字“A”(符号名称)和它的指定值。这允许动态变量分配/重新分配。它有点像查找列表。允许这种情况的基础数据结构或机制是什么?

编辑:具体来说,这是如何在内部(或外部,因为包看起来直接参与)完成的?寻找深入的技术答案,重点关注如何在 Lisp-2 中实施。

2 个答案:

答案 0 :(得分:5)

请注意,'(+ 1 2 A)不是变量,而是形式(引用(+ 1 2 A)),它评估对象。列表中的A是符号,但它不是变量。

变量是由符号表示的存储位置。

Re:像Lisp这样的语言在运行时如何进行这种评估?

(Common)Lisp有两种变量:动态和词法。动态变量可以在运行时进行评估,因为您可以获取符号并确定它是否具有动态变量绑定,并检索或分配该绑定。

词法变量是在编译时被“烘焙”的变量:没有可移植的方式来反映它们的名称。

这两种变量对不同的目的都有用。

动态变量可以存储在与符号关联的位置,称为值单元格。 (这个术语实际上出现在ANSI Common Lisp中)。该符号用作检索单元格的一种键(如果有的话)。例如,值单元可以是某个cons单元的cdr字段,其存储在哈希表中,其中键是符号。各种实现都是可能的。

有一个复杂的问题,Lisp支持动态变量的本地重新绑定:即,您可以使用let或其他绑定结构为隐藏任何现有绑定的动态变量创建本地绑定。当构造退出时(以任何方式:通过throw包括非本地出口等),隐藏的绑定将被恢复。这个动态范围必须以某种方式实现,这意味着动态变量查找不一定只是追逐从符号到值单元格的指针。

更复杂的是,多线程Lisps的用户希望对动态变量进行每线程绑定。

这里可能会有更多信息:http://en.wikipedia.org/wiki/Scope_%28computer_science%29#Dynamic_scoping

答案 1 :(得分:2)

在Common Lisp中,符号本身就是对象,能够使用与之关联的值来命名属性。在读取时创建符号( interned 在当前包中),如下所示:

> 'a
A

您可以使用(describe 'a)(inspect 'a)(使用此处的CLISP)检查它们。您可以使用(set 'a 1)设置此symol。但您也可以在此之后致电(defun a (x) (+ 1 x))。现在检查符号'a表明它同时包含值和函数定义。这反映了Common Lisp具有变量值和函数的单独名称空间。符号将这些额外信息存储在其属性列表中:

[19]> (symbol-value 'a)
1
[20]> (symbol-function 'a)
#<FUNCTION A (X) (DECLARE (SYSTEM::IN-DEFUN A)) (BLOCK A (+ X 1))>
[21]> (symbol-plist 'a)
(SYSTEM::DEFINITION
 ((DEFUN A (X) (+ X 1)) .
  #(NIL NIL NIL NIL ((DECLARATION OPTIMIZE DECLARATION)))))

[44]> (setf (get 'a 'prop1) 12)
12
[45]> (symbol-plist 'a)
(PROP1 12 SYSTEM::DEFINITION
 ((DEFUN A (X) (+ X 1)) .
  #(NIL NIL NIL NIL ((DECLARATION OPTIMIZE DECLARATION)))))

另见

http://www.lispworks.com/documentation/HyperSpec/Body/f_get.htm#get   http://www.lispworks.com/documentation/HyperSpec/Body/f_intern.htm#intern