我已阅读 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.
如果绑定(bind)符号本质上被编译为闭包环境中的指针,您如何将符号传递给已编译的函数,并且该函数能够以某种方式比较符号?
我一直在搞乱 clisp 中的 pantest
示例,我可以看到我能够同时更改 acc
和 this
在 pantest
中。我可以编译和反汇编 pantest
,但所有符号都显示在环境中。如果我有一个编译成汇编的 lisp,我可能会获得更多的直觉,但代码已经足够复杂,如果不加以解释,可能很难理解。
最佳答案
我不熟悉 Let Over Lambda。
Lisp in Small Pieces 一书解释了词法绑定(bind)如何编译成非常有效的变量引用。由于对变量的所有已知引用都在有限的范围内,您可以使用数组来存储绑定(bind)并通过数字索引引用它们,而不是使用符号来查找事物或使用符号的属性来获取值(value)。
传递给函数的符号只是一个符号,一种数据。将其与函数中的其他内容进行比较与访问有关特定范围内词法绑定(bind)的信息不同。
有一种说教式的 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
的词法绑定(bind)。所有更改都通过同一词法位置中的代码进行调解。
关于closures - Pandoric Macro 中的符号如何编译出来?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42604338/