What is the purpose of &environment in Common Lisp? -
i confused &environment parameter in common lisp. in particular, useful for, , why parameter, rather special variable?
edit: nice see concrete example of how &environment
used in code.
doc
&environment
followed single variable bound environment representing lexical environment in macro call interpreted. environment should usedmacro-function
,get-setf-expansion
,compiler-macro-function
, ,macroexpand
(for example) in computing expansion of macro, ensure lexical bindings or definitions established in compilation environment taken account.
explanation
operators define macros (local or global) have define how code expanded before being evaluation or compiled, , may need expand existing macros, expansion may depend on environment - macro definitions need environment.
not special variable
special variables more dangerous because user might rebind them , because harder handle correctly in multi-threaded code.
example
all on 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 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))))
from 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)))
Comments
Post a Comment