Next: Macro Expansion, Previous: Syntax Parameters, Up: Macros [Contents][Index]
As syntax-case macros have the whole power of Scheme available to them,
they present a problem regarding time: when a macro runs, what parts of the
program are available for the macro to use?
The default answer to this question is that when you import a module (via
define-module or use-modules), that module will be loaded up at
expansion-time, as well as at run-time. Additionally, top-level syntactic
definitions within one compilation unit made by define-syntax are also
evaluated at expansion time, in the order that they appear in the compilation
unit (file).
But if a syntactic definition needs to call out to a normal procedure at expansion-time, it might well need need special declarations to indicate that the procedure should be made available at expansion-time.
For example, the following code will work at a REPL, but not in a file:
;; incorrect (use-modules (srfi srfi-19)) (define (date) (date->string (current-date))) (define-syntax %date (identifier-syntax (date))) (define *compilation-date* %date)
It works at a REPL because the expressions are evaluated one-by-one, in order, but if placed in a file, the expressions are expanded one-by-one, but not evaluated until the compiled file is loaded.
The fix is to use eval-when.
;; correct: using eval-when (use-modules (srfi srfi-19)) (eval-when (expand load eval) (define (date) (date->string (current-date)))) (define-syntax %date (identifier-syntax (date))) (define *compilation-date* %date)
Evaluate exp... under the given conditions. Valid conditions include:
expandEvaluate during macro expansion, whether compiling or not.
loadEvaluate during the evaluation phase of compiled code, e.g. when loading a compiled module or running compiled code at the REPL.
evalEvaluate during the evaluation phase of non-compiled code.
compileEvaluate during macro expansion, but only when compiling.
In other words, when using the primitive evaluator, eval-when
expressions with expand are run during macro expansion, and those
with eval are run during the evaluation phase.
When using the compiler, eval-when expressions with either
expand or compile are run during macro expansion, and
those with load are run during the evaluation phase.
When in doubt, use the three conditions (expand load eval), as in
the example above. Other uses of eval-when may void your
warranty or poison your cat.
Next: Macro Expansion, Previous: Syntax Parameters, Up: Macros [Contents][Index]