Common Lisp中&environment的目的是什么?

Tha*_*yne 6 environment common-lisp

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

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

sds*_*sds 4

医生

宏 Lambda 列表

&environment后面跟着一个变量,该变量绑定到表示要在其中解释宏调用的词法环境的环境。此环境应与 macro-functionget-setf-expansioncompiler-macro-functionmacroexpand(例如)一起使用来计算宏的扩展,以确保考虑到在编译环境中建立的任何词法绑定或定义。

解释

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

不是特殊变量

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

例子

遍布places.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))))
Run Code Online (Sandbox Code Playgroud)

iolib/src/new-cl/definitions.lisp

(defmacro defconstant (name value &optional documentation
                       &environment env)
  (destructuring-bind (name &key (test ''eql))
      (alexandria:ensure-list name)
    (macroexpand-1
     `(alexandria:define-constant ,name ,value
        :test ,test
        ,@(when documentation `(:documentation ,documentation)))
     env)))
Run Code Online (Sandbox Code Playgroud)