SLIME, 2
.
Alt + Up/Down
Switch between the editor and the REPL
— Me@2018-11-07 05:57:54 AM
~~~
defmacro
.
(defmacro our-expander (name) `(get ,name 'expander)) (defmacro our-defmacro (name parms &body body) (let ((g (gensym))) `(progn (setf (our-expander ',name) #'(lambda (,g) (block ,name (destructuring-bind ,parms (cdr ,g) ,@body)))) ',name))) (defun our-macroexpand-1 (expr) (if (and (consp expr) (our-expander (car expr))) (funcall (our-expander (car expr)) expr) expr))
.
A formal description of what macros do would be long and confusing. Experienced programmers do not carry such a description in their heads anyway. It’s more convenient to remember what
defmacro
does by imagining how it would be defined.…
The definition in Figure 7.6 gives a fairly accurate impression of what macros do, but like any sketch it is incomplete. It wouldn’t handle the
&whole
keyword properly. And whatdefmacro
really stores as the macro-function of its first argument is a function of two arguments: the macro call, and the lexical environment in which it occurs.
— p.95
— A MODEL OF MACROS
— On Lisp
— Paul Graham
.
(our-defmacro sq (x) `(* ,x ,x))
After using our-defmacro
to define the macro sq
, if we use it directly,
(sq 2)
we will get an error.
The function COMMON-LISP-USER::SQ is undefined.
[Condition of type UNDEFINED-FUNCTION]
Instead, we should use (eval (our-macroexpand-1 '
:
(eval (our-macroexpand-1 '(sq 2)))
— Me@2018-11-07 02:12:47 PM
.
.
2018.11.07 Wednesday (c) All rights reserved by ACHK