[r6rs-discuss] [Formal] Remove double phase semantics
William D Clinger
will at ccs.neu.edu
Sun Nov 26 10:58:19 EST 2006
I am posting this as an individual member of the Scheme
community. I am not speaking for the R6RS editors, and
this message should not be confused with the editors'
eventual formal response.
Matthew Flatt wrote:
> > With the allegedly
> > cleaner semantics, the symbols that would be available to
> > procedural macros at macro expansion time would be completely
> > different from the symbols that exist at run time.
> I see no problem with that. One point of the separation is that an
> implementor could make this choice. Maybe symbols tend to be used in
> different ways at compile time and run time, so it's useful to have
> different representations?
Everyone needs to understand that this applies to all
data types, not just symbols. If booleans, numbers,
pairs, vectors, strings, ports, and enum sets are defined
by generative records, then they too will be different at
expand time than at run time.
In the reference implementations, does the datum->syntax
procedure arrange for macro-time representations of all
booleans, numbers, pairs, vectors, strings, and so on to
be converted into run-time representations in the
macro-expanded code? If so, then how do they accomplish
If not, then I don't see how a procedural macro could
reliably insert a boolean constant into macro-expanded
> Suppose I compile a MzScheme program on my PPC machine today and run it
> tomorrow on an x86 machine. In that case, the compile-time and run-time
> representations of symbols are different. The only connection between
> them is an external representation.
I understand that separate compilation will work, because
the external representations form an intermediate language
for translating between the representations used at macro
time and at run time.
I am worried, however, that the reference implementations
of draft R6RS libraries might work only when the result of
macro expansion is converted to an external representation
and passed through the read procedure of the next lower
stage. If that were so, then I might feel compelled to
retain my current implementation of syntax-rules, because
it would avoid the write/read overhead in most cases (all
except separate compilation). That would make integration
of syntax-case much more complex, to the point where I
might not bother to implement syntax-case at all.
Andre van Tonder wrote:
> With separated bindings, one cannot compare values that exist in different
> phases, even though they may be present in memory at the same time...
I am glad to see our experts agree on this point: run-time
booleans cannot be compared with macro-time booleans.
> With shared bindings, on the other hand, code run in one phase can affect
> values existing in different phases. As a result
> - Code that works today when you compile and run in the same
> image may stop working tomorrow when you distribute the compiled binary.
> - Code that works in the repl may stop working when you wrap it in a
> - A library may behave differently when imported for RUN than it does
> when imported for EXPAND.
> - A library that has been tested in one phase may stop working when
> imported into a different phase instead.
> - A library that has been tested when imported into one phase may
> stop working when imported into more than one phase simultaneously.
> Most of these problems are avoided in the separated binding semantics.
Are you sure? It looks to me as though the separated binding
semantics ensures that
- A library *will* behave differently when imported for RUN than it
does when imported for EXPAND.
- A library that has been tested in one phase *is likely to* stop
working when imported into a different phase instead.
- A library that has been tested when imported into one phase *is
likely to* stop working when imported into more than one phase
I hope I'm wrong, but I don't see how.
More information about the r6rs-discuss