Common Lisp中环境和环境的目的是什么?

时间:2014-05-29 23:46:40

标签: common-lisp environment

我对常见的lisp中的& environment参数感到困惑。特别是,它有什么用处,为什么它是一个参数,而不是一个特殊的变量?

编辑:看一下如何在代码中使用&environment的具体示例也很高兴。

3 个答案:

答案 0 :(得分:4)

文档

Macro Lambda Lists

  

&environment后跟一个绑定到的变量   环境代表宏观的词汇环境   呼叫是要解释的。应该使用此环境   macro-functionget-setf-expansioncompiler-macro-function和   {(1}}(例如)在计算宏的扩展时,到   确保在中建立任何词汇绑定或定义   编译环境被考虑在内。

说明

定义宏(本地或全局)的运算符必须在评估或编译之前定义代码的扩展方式,因此可能需要扩展现有的宏,其扩展可能取决于环境 - 因此宏定义需要环境。

不是特殊变量

特殊变量更危险,因为用户可能会重新绑定它们,因为它们在多线程代码中更难以正确处理。

实施例

遍布places.lisp

macroexpand

来自iolib/src/new-cl/definitions.lisp

(defmacro psetf (&whole whole-form
                 &rest args &environment env)
  (labels ((recurse (args)
             (multiple-value-bind (temps subforms stores setterform getterform)
                 (get-setf-expansion (car args) env)
               (declare (ignore getterform))
               (when (atom (cdr args))
                 (error-of-type 'source-program-error
                   :form whole-form
                   :detail whole-form
                   (TEXT "~S called with an odd number of arguments: ~S")
                   'psetf whole-form))
               (wrap-let* (mapcar #'list temps subforms)
                 `(MULTIPLE-VALUE-BIND ,stores ,(second args)
                    ,@(when (cddr args) (list (recurse (cddr args))))
                    ,@(devalue-form setterform))))))
    (when args `(,@(recurse args) NIL))))

答案 1 :(得分:3)

例如,当Lisp想要 macroexpand 表单时,需要知道哪个名称引用了什么宏定义。这可能取决于全局可用的宏,通过macrolet的本地绑定宏或编译期间可用的宏。因此,环境对象可以针对不同的环境宏扩展表单。

答案 2 :(得分:1)

环境变量向宏作者提供有关声明等的信息。人。在调用宏时强制执行。然后,宏作者可以使用该信息来自定义他选择如何扩展宏。例如,他可以根据他在环境中找到的声明来添加或减去调试代码。例如,他可能会推断出他使用的表达式类型,并添加或减少代码以获得更好的性能。

您可以编写很多Common Lisp代码,而不会使用&环境。在某些情况下,有必要,当这些问题可以提出良好的后续问题时。雷纳暗示了对此的回答。