2017-03-05 58 views
0

我已经几次阅读了LOL的第6.7部分,但我仍然无法完全理解以下内容。如何编译Pandoric宏中的符号?

以前对外部代码关闭的绑定现在已经公开供我们修改,即使这些绑定已编译为某种效率并早已将其存取符号遗忘了。

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

我已经与pantest例子搞乱CLISP中,我可以看到我能够改变这两个accthispantest。我可以编译和反汇编pantest,但所有符号都显示在环境中。如果我的lisp被编译成汇编,我可能会获得更多的直觉,但是代码很复杂,以至于如果没有解释就可能太难了。

+1

我会说,pandoric let让他们能否不问他们是否应该(以及评估的顺序是......)但是可以肯定的是,您可以在'pandoric-let'中添加一个案例s'dlambda',它返回其中的所有变量名称。 – acelent

回答

1

(我会回来后,在这里后来在一些更多的信息填写)

总之(略过于简单化),该pandoric,让宏一些额外的代码添加到处理的试图让的情况下或者设置它引入的每个不同的变量。这些额外的代码会在代码编译完成后记住这些变量的符号,但由于它是唯一需要这些信息的代码,所有其他代码都会被编译为非常高效的指针操作。

能产生这种额外的代码的功能是pandoriclet-getpandoriclet-set,这两者都是棘手的阅读,因为它们返回的代码取决于其在pandoriclet宏本身提供的符号symval

+0

那么你是否认为作者的陈述对于Pandoric宏而言在技术上不正确?导出到其他词汇环境的符号不仅仅是一个索引或指针? – Todd

+1

恩......我想我看到了这种误解。词汇环境不会引入符号,它会引入变量并将现有符号与这些变量相关联。通常情况下,编译器可以看到所有通过其符号引用该变量的位置,并且可以完全优化符号。 pandoric-let所做的是在运行时添加一些代码以查找每个变量的符号,以便可以在词法范围外访问这些变量。 – djeis

+0

我*认为*我明白。这些符号确实在编译后的闭包中(加入)。你仍然需要做一些比较(我假设一个字符串比较)。作者提到的绑定大概只是指向变量的指针,而不是编译的额外代码。 – Todd

2

我不喜欢放弃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的词汇绑定,而无需从外部访问它。所有更改都通过相同词汇位置中的代码进行调解。

+0

大声笑还引用小件的Lisp。我需要将它添加到我的阅读列表中。不过,关键在于,使用Pandoric宏,您可以*外部*访问任何其他词汇环境中尚未绑定或定义的值和任何其他数量不受限制的符号(请参阅plambda)。这是我不明白的。 – Todd

+0

听起来可能是“一旦你足够了解这一点,你就会知道不要这样做”的情况。 – Xach

+0

我不是一个lisp程序员。我想我已经开始阅读本书,因为我想了解一些关于如何使用宏来制作DSL的知识。同意过量的宏观使用看起来非常危险。至少,很难理解发生了什么。 – Todd