Tha*_*yne 6 environment common-lisp
我对常见的lisp中的&environment参数感到困惑.特别是,它有什么用处,为什么它是一个参数,而不是一个特殊的变量?
编辑:看到如何&environment在代码中使用的具体示例也很高兴.
&environment后面跟着一个变量,该变量绑定到表示要在其中解释宏调用的词法环境的环境。此环境应与macro-function、get-setf-expansion、compiler-macro-function和macroexpand(例如)一起使用来计算宏的扩展,以确保考虑到在编译环境中建立的任何词法绑定或定义。
定义宏(本地或全局)的运算符必须在评估或编译之前定义代码如何扩展,因此可能需要扩展现有的宏,其扩展可能取决于环境 - 因此宏定义需要环境。
特殊变量更加危险,因为用户可能会重新绑定它们,并且它们在多线程代码中更难正确处理。
遍布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)
| 归档时间: |
|
| 查看次数: |
806 次 |
| 最近记录: |