Next: , Previous: , Up: Macros   [Contents][Index]

6.10.5 Lisp-style Macro Definitions

The traditional way to define macros in Lisp is very similar to procedure definitions. The key differences are that the macro definition body should return a list that describes the transformed expression, and that the definition is marked as a macro definition (rather than a procedure definition) by the use of a different definition keyword: in Lisp, defmacro rather than defun, and in Scheme, define-macro rather than define.

Guile supports this style of macro definition using both defmacro and define-macro. The only difference between them is how the macro name and arguments are grouped together in the definition:

(defmacro name (args …) body …)

is the same as

(define-macro (name args …) body …)

The difference is analogous to the corresponding difference between Lisp’s defun and Scheme’s define.

Having read the previous section on syntax-case, it’s probably clear that Guile actually implements defmacros in terms of syntax-case, applying the transformer on the expression between invocations of syntax->datum and datum->syntax. This realization leads us to the problem with defmacros, that they do not preserve referential transparency. One can be careful to not introduce bindings into expanded code, via liberal use of gensym, but there is no getting around the lack of referential transparency for free bindings in the macro itself.

Even a macro as simple as our when from before is difficult to get right:

(define-macro (when cond exp . rest)
  `(if ,cond
       (begin ,exp . ,rest)))

(when #f (display "Launching missiles!\n"))
⇒ #f

(let ((if list))
  (when #f (display "Launching missiles!\n")))
-| Launching missiles!
⇒ (#f #<unspecified>)

Guile’s perspective is that defmacros have had a good run, but that modern macros should be written with syntax-rules or syntax-case. There are still many uses of defmacros within Guile itself, but we will be phasing them out over time. Of course we won’t take away defmacro or define-macro themselves, as there is lots of code out there that uses them.

Next: , Previous: , Up: Macros   [Contents][Index]