[r6rs-discuss] [Formal] Remove double phase semantics
andre at het.brown.edu
Sun Nov 26 09:41:13 EST 2006
On Sat, 25 Nov 2006, William D Clinger wrote:
> Here's another use case that seems more likely to work with
> shared bindings than with the allegedly cleaner semantics:
> Suppose string->symbol is implemented as a library, using a
> hash table that maps strings to symbols as its mutable state.
> With shared bindings, I think procedural macros would see the
> same symbols that are seen at run-time. 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.
> Maybe that doesn't matter; I don't see anything in the draft
> R6RS that would require the symbols seen at macro expansion
> time to have anything to do with the symbols seen at run
> time. If the R6RS were to require symbols to be the same
> at run time and at macro expansion time, however, then the
> R6RS ought not to require a semantics that makes it difficult
> or impossible to implement string->symbol in Scheme.
The semantics with separated bindings was invented precisely
to solve the kind of problem that you describe (see Matthew Flatt's paper).
The problem you describe can only arise in a semantics that shares bindings.
One of the stated goals of the library system is to allow separate compilation,
so that compile-time and runtime code might not run in the same image or even
on the same machine.
With separated bindings, one cannot compare values that exist in different
phases, even though they may be present in memory at the same time and even, in
the case of symbols, may refer to the same memory location (note that you are
not required to have separate symbol tables for separate phases - it is simply
a syntactic enforcement on the phase of use of names of the bindings). So the
problem you describe is avoided by making the comparison inexpressible.
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.
More information about the r6rs-discuss