[ERR5RS] Rationale and ease of use
AndrevanTonder
andre at het.brown.edu
Thu Sep 6 08:19:44 PDT 2007
On Tue, 4 Sep 2007, Lynn Winebarger wrote:
> There were a lot of messages in that thread. In the first message,
> Andre prefered a single set of bindings for all phases, but then
> changed his mind a few messages later.
I think it is clear that if one insists on a single set of bindings
for expand-time and runtime, one would have to recompile a program
before running it every time one restarts a session, or otherwise
include the compile-time image in the compiled object file. I think
that would be an undesirable constraint to impose on compiler-based
Scheme systems.
(For simplicity and performance, my implementation does share a single
memory location for the bindings of the same identifier in phases
higher than "expand", but it syntactically prohibits access to
bindings, even though they may be present in memory, that
are used outside their declared levels. Still, communication
between levels is possible using set!, but this should not be
used in portable programs.)
I agree with the premise of R6RS that portable programs be
written to not depend on the unspecified details of the instantiation
semantics. This could be seen as analogous to the constraint that
portable programs must not depend on the unspecified evaluation order
of function calls.
However, I do not think this idea was ideally executed. A better
execution might take the form of a concise description of the
responsibility of the programmer, instead of the current description
on the freedom of implementations. In its current form, I think it
may be difficult for the reader to figure out exactly what it is that
is unspecified and what their responsibilities are.
> One of the significant points
> that came out (for me, anyway) is that some implementors viewed the
> different levels as potentially being entirely different languages,
> particularly an underlying non-Scheme implementation language.
No, the underlying implementation language exists outside the system.
By "language" at a specific level, we just meant the set of Scheme
bindings (variables and macros) imported into that level.
> While I can see an abstract
> cleanness in specifying exact metalevel instantiation, it seems like
> it would be make programming much more painful in general, in that the
> programmer has to know exactly at what levels he/she needs particular
> definition.
This can be significantly eased by good error reporting at expansion
time. In my implementation, these take the form of
Invalid reference at level 1 in library (foo) to identifier x
imported from library (bar). Identifier is only imported for
level 0.
which makes it obvious how one should change the import clause
to fix it.
> I know I have found an analogous feature of PLT's
> syntax-case incredibly annoying (not being able to directly use
> variable definitions inside a syntax-case body).
I know it is annoying, but it is also correct. It avoids the even
more annoying phenomenon of code that improperly works in the REPL
suddenly stopping working when you compile the same code (at compilation
time the runtime variable does not have value, so the reference to it
from syntax-case will fail). A good reference on this kind of thing
can be found in Matthew Flatt's paper whose title ends with
"you want it when", which I would recommend.
> If this is correct, could you (Andre, Will, or both) provide a
> single coherent explanation of why the separated binding are the
> better semantics? In any case, as a user I would prefer to know that
> it was going to be one or the other for certain.
As Will said, programs should not depend on unspecified aspects of the
semantics. Maybe a good question for err5rs is whether this
semantics-independence should be enforced by the implementation
(e.g., providing only syntax-rules) or whether one should come
up with a simple set of programmer's responsibilities that would,
if followed, ensure such independence.
Andre
More information about the Err5rs
mailing list