Pandoric Macro 中的符号如何编译出来?

How can the symbols in a Pandoric Macro be compiled out?

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

Bindings that were previously closed to outside code are now wide open for us to tinker with, even if those bindings were compiled to something efficient and have long since had their accessor symbols forgotten.

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

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

我不熟悉 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 的词法绑定。所有更改都通过同一词法位置的代码进行调解。

(待会儿再回来这里补充一些信息)

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

生成此额外代码的函数是 pandoriclet-getpandoriclet-set,这两个函数都难以阅读,因为它们 return 代码依赖于符号 symval,它们在 pandoriclet 宏本身中提供。