28.  Macros  

(macro formals body)

This special form creates a macro. The syntax is identical to the syntax of lambda expressions. When a macro is called, the actual arguments are bound to the formal arguments of the macro expression in the current environment (they are not evaluated), then the body is evaluated. The result of this evaluation is considered the macro expansion and is evaluated in place of the macro call.

(define-macro (variable formals) body)
(define-macro (variable . formal) body)

Like define, except that macro is used instead of lambda.
Examples:

(define-macro (++ x) `(set! ,x (1+ ,x)))
(define foo 5)
foo           ==>  5
(++ foo)
foo           ==>  6
(define-macro (while test . body)
  `(let loop ()
     (cond (,test ,@body (loop)))))

(macro? obj)

Returns #t if obj is a macro, #f otherwise.

(macro-body macro)

Returns a copy of the macro expression which has been evaluated to created the given macro (similar to procedure-lambda).
Examples:

(define-macro (++ x) `(set! ,x (1+ ,x)))

(macro-body ++)
  ==>  (macro (x) (quasiquote (set! (unquote x) (1+ (unquote x)))))

(macro-expand list)

If the expression list is a macro call, the macro call is expanded.
Examples:

(define-macro (++ x) `(set! ,x (1+ ,x)))

(macro-expand '(++ foo))         ==>  (set! foo (1+ foo))

The following function can be used to expand all macro calls in an expression, i.e. not only at the outermost level:

(define (expand form)
  (if (or (not (pair? form)) (null? form))
      form
      (let ((head (expand (car form)))
            (args (expand (cdr form)))
            (result))
        (if (and (symbol? head) (bound? head))
            (begin
              (set! result (macro-expand (cons head args)))
              (if (not (equal? result form))
                  (expand result)
                  result))
              (cons head args)))))


Markup created by unroff 1.0,    September 24, 1996,    net@informatik.uni-bremen.de