On Wed, 2009-09-16 at 16:08 -0500, Brian Mastenbrook wrote:
> On Sep 15, 2009, at 9:31 PM, Ray Dillinger wrote:
> > If you design for a separation of phases anyway, then your design
> > is going to have semantic inconsistencies. *That* is the
> > unfortunate necessity.
> I don't understand why the time when macros are expanded has anything
> to do with the scoping rules of the language, unless you're trying to
> do things which are not possible in a lexically scoped environment.
There are two different issues here. One is scope, the other is
extent. Scope governs *where* a definition is visible; Extent
governs *when* the definition is usable. In order to work, a
syntax invocation or a procedure call has to appear within the
scope of the corresponding form *AND* get executed during the
extent of the form.
With both procedures and syntax, the extent starts when the
definition is processed at readtime. For procedures, this is
mostly a nonissue because execution time comes during the extent
of the procedure (ie, after the definition itself is processed).
Procedure invocations can be compiled into procedure calls even
before the procedure definition has been seen. It is only when
actually trying to execute the procedure calls that we need to
be in the extent of the procedure.
For syntax definitions, this is most definitely not a nonissue
because in a straightforward implementation, a forward use of
a syntax form, even if within the lexical scope of that syntax,
may come before the extent of that syntax begins.
In order to create a semantics where syntax behaved in the same
way as procedures (and therefore scope were usually all you
needed to worry about), you'd have to be able to compile a
"call" to a syntactic form without actually doing the expansion,
read the syntax definition later (causing the extent of the
syntax to start) and then do the expansion at the last possible
instant when the form was actually executed. At that point the
"execution" of the syntax (eg, macroexpansion) would be during
the extent of the syntax as well as being within its scope.
But for engineering reasons such as a desire not to have to
store all the source code at runtime, phase separation,
runtime efficiency, not wanting to muck about with reified
first-class environments under the hood (which is necessary
to compile "calls" to syntax), and hoping that the extent of
syntax (and the memory requirement to hold syntax definitions)
can be allowed to end before runtime, we don't want to do that
in scheme.
Therefore, rejecting the most consistent semantics, we are
obligated to decide exactly which inconsistencies we have to
put up with and what we are willing to sacrifice to achieve
our engineering goals.
So this whole debate is about how to handle our reading and
expansion in such a way that macroexpansion happens both within
the scope *and* during the extent of the macro.
My contention is that if you're not willing to go for consistent
then simple is probably the best thing available. And "simple",
in this case, just means no use of a macro before its definition.
That means disallowing mutually-recursive macros. This is a
"restriction that makes additional complications appear necessary",
in the sense of the first paragraph of the report.
The appropriate additional complication is probably a form
allowing simultaneous definition of multiple (potentially
mutually-recursive) macros, and we'd have to live with it
until we were ready to "strip away the restrictions that
made the additional complication appear necessary."
Bear
_______________________________________________
r6rs-discuss mailing list
[email protected]
http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss