The SRFI does not currently specify how side effects during expansion are
treated. This was not relevant for syntax-rules, but does make a difference
in a procedural macro system.
I am particularly interested in cases where a common strategy may involve
repeating the same expansion step, or only partially expanding an expression,
typically to determine if it is a definition.
In the following example:
(define-syntax foo
(let ((count 0))
(lambda (s)
(set! count (+ 1 count))
count)))
(define-syntax bar
(let ((count 0))
(lambda (s)
(set! count (+ count 1))
(syntax-case s ()
((_ x) (with-syntax ((count count))
(syntax (list count (foo) x)))))))
(let ()
(define x (foo))
(bar x))
the result could be any of:
- (1 1 2)
If the first non-definition (bar x) in the let is expanded atomically
as soon as it is encountered.
- (1 2 1)
If the first non-definition (bar x) is expanded only far enough to
determine if it is a definition before expanding the RHS of the
define.
- (2 2 1)
If we do as in the previous case, but do not save the partially
expanded (bar x), instead re-expanding it from the beginning
after the definitions are all expanded (I have seen implementations
that do this).
This seems academic, but I do think the differences could conceivably lead to
difficulties in macros that rely on side effects to register compile-time
information, as in record or object systems. For example, if BAR were
a record definition, I would probably feel most comfortable if I could rely on
the expression being epanded atomically (the first behaviour above).
Regards
Andre