词汇与动态范围,形式,声明形式

时间:2016-07-19 12:53:30

标签: common-lisp

动态与词汇范围。

; One expects lexical scope.    
(let (( a '(a))) 
  (defun func1 (x)
    (setq a (cons x (cons (func2 x) a))))
  (defun func2 (y) 
    (setq a (cons y a))))

(func1 'b)
=> (B (B A) B A)

在词汇上做,人们会期待 以下。

  1. (a)替换为a
  2. 中的func2 使用func2调用
  3. x,即值b
  4. func2还附加a(a)的值。
  5. 因此(cons y a)评估为(b a)
  6. (setq a (cons y a)))(b a)
  7. 因此func1(b a)(a)合作。
  8. x然后被分配(b (b a) a))
  9. 最终结果(b (b a) a)?这是矛盾吗?
  10. 让我们尝试动态版本。     ;动态范围

    (defparameter a '(a)) 
    
    (defun func1 (x)
      (setq a (cons x (cons (func2 x) a))))
    
    (defun func2 (y) 
      (setq a (cons y a)))
    
    (func1 'b)
    =>(B (B A) B A)
    

    这是预期的,但与词法范围相同?

    但完全不接受以下内容。

    ; This won't work.
    (let (( a '(a))) 
      (defun func1 (x)
        (declare (special a)) 
        (setq a (cons x (cons (func2 x) a))))
      (defun func2 (y) 
        (declare (special a))
        (setq a (cons y a))))
    
    (func1 'b)
    Error: Attempt to take the value of the unbound variable `A'.   
    

    发生了什么事?

1 个答案:

答案 0 :(得分:1)

感谢敏锐的目光。这个例子来自31年前印刷的Lisp教科书,直接出自“动态与词汇范围”一章。这个解释也直接来自那本书。我猜词法范围没有被检查,因为作者明确警告读者词汇范围没有在Lisp中完成。我很高兴这个问题得到了解决。我盯着它看了一段时间,却没有理解真正发生的事情。这似乎是一个奇怪的矛盾。