Next: Higher Ordered Fun, Previous: Syntax Case, Up: Procedures and Macros
Internally, Guile uses three different flavors of macros. The three flavors are called acro (or syntax), macro and mmacro.
Given the expression
(foo ...)
with foo being some flavor of macro, one of the following things
will happen when the expression is evaluated.
foo has been defined to be an acro, the procedure used
in the acro definition of foo is passed the whole expression and
the current lexical environment, and whatever that procedure returns is
the value of evaluating the expression. You can think of this a
procedure that receives its argument as an unevaluated expression.
foo has been defined to be a macro, the procedure used
in the macro definition of foo is passed the whole expression and
the current lexical environment, and whatever that procedure returns is
evaluated again. That is, the procedure should return a valid Scheme
expression.
foo has been defined to be a mmacro, the procedure
used in the mmacro definition of `foo' is passed the whole expression
and the current lexical environment, and whatever that procedure returns
replaces the original expression. Evaluation then starts over from the
new expression that has just been returned.
The key difference between a macro and a mmacro is that the expression returned by a mmacro procedure is remembered (or memoized) so that the expansion does not need to be done again next time the containing code is evaluated.
The primitives procedure->syntax, procedure->macro and
procedure->memoizing-macro are used to construct acros, macros
and mmacros respectively. However, if you do not have a very special
reason to use one of these primitives, you should avoid them: they are
very specific to Guile's current implementation and therefore likely to
change. Use defmacro, define-macro (see Macros) or
define-syntax (see Syntax Rules) instead. (In low level
terms, defmacro, define-macro and define-syntax are
all implemented as mmacros.)
Return a macro which, when a symbol defined to this value appears as the first symbol in an expression, returns the result of applying code to the expression and the environment.
Return a macro which, when a symbol defined to this value appears as the first symbol in an expression, evaluates the result of applying code to the expression and the environment. The value returned from code which has been passed to
procedure->macroreplaces the form passed to code. For example:(define trace (procedure->macro (lambda (x env) `(set! ,(cadr x) (tracef ,(cadr x) ',(cadr x)))))) (trace foo) == (set! foo (tracef foo 'foo))
Return a macro which, when a symbol defined to this value appears as the first symbol in an expression, evaluates the result of applying proc to the expression and the environment. The value returned from proc which has been passed to
procedure->memoizing-macroreplaces the form passed to proc. For example:(define trace (procedure->macro (lambda (x env) `(set! ,(cadr x) (tracef ,(cadr x) ',(cadr x)))))) (trace foo) == (set! foo (tracef foo 'foo))
In the following primitives, acro flavor macros are referred to as syntax transformers.
Return
#tif obj is a regular macro, a memoizing macro or a syntax transformer.
Return one of the symbols
syntax,macroormacro!, depending on whether obj is a syntax tranformer, a regular macro, or a memoizing macro, respectively. If obj is not one of these, return#f.