如何编译Pandoric宏中的符号?

时间:2017-03-05 03:54:55

标签: closures lisp common-lisp lisp-macros let-over-lambda

我现在已经阅读了LOL的第6.7节,我仍然无法绕过以下内容。

  

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

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

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

2 个答案:

答案 0 :(得分: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的词法绑定而无需从外部访问它。所有更改都通过相同词汇位置的代码进行调解。

答案 1 :(得分:1)

(我稍后会再回来,稍后再填写一些信息)

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

生成此额外代码的函数是function init(){ var xobj = new XMLHttpRequest(); xobj.open("GET","data.json"); xobj.onload = function(){ if(xobj.status===200 && xobj.readyState ===4){ person = JSON.parse(xobj.responseText); if(person){//not sure if this check helps for(var i=0;i<person.things.length;i++){ place.insertAdjacentHTML('beforeend',"<p>"+ person.things[i].text +"</p>"); } } }else{ console.log("error getting data"); } } xobj.send(); } function sendDataToFile(data){ console.log(data); //write to data.json var xobj = new XMLHttpRequest(); xobj.open("POST","data.json",true); xobj.setRequestHeader("Content-type", "application/json"); xobj.onload = function(){ if(xobj.status===200 && xobj.readyState ===4){ }else{ console.log("error getting data"); } } person.things.push({text:data}); //pushing new data var sendString = JSON.stringify(person);//convert to json object console.log(sendString); xobj.send(sendString); //send } pandoriclet-get,两者都很难阅读,因为它们返回的代码取决于符号pandoriclet-setsym它们在val宏本身中提供。