I'd like to learn more about lisp macros and I want to create a simple implementation of the defun
macro.
I'm also interested in lisp's source code in all the implementations.
This is a tricky question, because of bootstrapping: defun
does a lot of things (iow, calls a lot of functions), but to define those functions one needs a working defun
. Thus there are three(3!) definitions of defun
in clisp/src/init.lisp: at lines
The very basic definition of defun could be this:
(defmacro defun (fname lambda-list &rest body)
`(setf (fdefinition ',fname)
(lambda ,lambda-list
(block ,fname ,@body))))
In fact, this is the first definition of defun
in CLISP (line 228), except that there is no defmacro
and no backquote at that moment yet, so the actual code looks a lot uglier.
See also Is defun or setf preferred for creating function definitions in common lisp and why? where I discuss macroexpansions of defun
s.
You can easily check how your particular CL implementation, implemented defun
by running
(macroexpand '(defun add2 (x) (+ x 2)))
On SBCL
it expands to:
(PROGN
(EVAL-WHEN (:COMPILE-TOPLEVEL) (SB-C:%COMPILER-DEFUN 'ADD2 NIL T))
(SB-IMPL::%DEFUN 'ADD2
(SB-INT:NAMED-LAMBDA ADD2
(X)
(BLOCK ADD2 (+ X 2)))
(SB-C:SOURCE-LOCATION)))
T
To see the particular source code that implemented the I would use (on Emacs) the M-.
key binding and then I will write defun
and hit enter. Then Emacs will get to the source code:
(sb!xc:defmacro defun (&environment env name lambda-list &body body)
#!+sb-doc
"Define a function at top level."
[...]
I am not going to paste the whole macro as it is rather long. If you are not on Emacs, you can try searching in the repos as most implementations are open source.
BTW defun
is not so special. You can implement much of it with setf
-inf a symbol-function
to a lambda. E.g.:
(setf (symbol-function 'ADD3) #'(lambda (x) (+ x 3)))
; => #<FUNCTION (LAMBDA (X)) {1006E94EBB}>
(add3 4)
; => 7
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With