1

我已经阅读了LOL的第 6.7 节几次,但我仍然无法理解以下内容。

以前对外部代码关闭的绑定现在对我们开放供我们修改,即使这些绑定被编译为有效的东西并且早已忘记了它们的访问器符号。

如果绑定符号本质上被编译为闭包环境中的指针,那么如何将符号传递给已经编译的函数,并且函数能够以某种方式比较符号?

我一直在搞乱pantestclisp 中的示例,我可以看到我能够同时更改accthisinside pantest。我可以编译和反汇编pantest,但所有符号都显示在环境中。如果我有一个可以编译成汇编的 lisp,我可能会获得更多的直觉,但代码足够复杂,如果没有解释可能很难理解。

4

2 回答 2

2

我不熟悉 Let Over Lambda。

Lisp in Small Pieces 一书解释了词法绑定如何编译成非常有效的变量引用。由于对变量的所有已知引用都在有限范围内,因此您可以使用数组来存储绑定并通过数字索引引用它们,而不是使用符号来查找事物或使用符号的属性来获取价值。

传递给函数的符号只是一个符号,一种数据。将其与函数中的其他内容进行比较与访问特定范围内的词法绑定信息不同。

有一种教学 Lisp 伪 OO 技术,它展示了如何通过传入一个符号来访问和修改词法状态来更改函数行为,但它是从一组固定的已知事物中进行选择进行比较,而不是基于词法信息的任意查找在一个符号上。

(defun make-incrementor (initial-value)
  (let ((value initial-value))
    (lambda (action)
      (ecase action
        (:value
         value)
        (:increment
         (incf value))
        (:reset
         (setf value initial-value))))))

> (defvar *inc* (make-incrementor 10))
*INC*

> (funcall *inc* :increment)
11

> (funcall *inc* :increment)
12

> (funcall *inc* :increment)
13

> (funcall *inc* :reset)
10

value这是在不从外部访问它的情况下操纵 的词法绑定。所有更改都通过同一词汇位置中的代码进行调解。

于 2017-03-05T14:01:31.550 回答
1

(稍后我会回来并在此处填写更多信息)

简而言之(有点过于简单化了),pandoric-let 宏添加了一些额外的代码来处理尝试获取或设置它引入的每个不同变量的情况。这个额外的代码会在代码编译后记住变量的符号,但因为它是唯一需要该信息的代码,所以其他所有代码都被编译为非常有效的指针操作。

生成这个额外代码的函数是pandoriclet-getpandoriclet-set,这两个函数都很难阅读,因为它们返回的代码取决于符号sym并且valpandoriclet宏本身中提供。

于 2017-03-06T03:39:29.133 回答