|
Update to SRFI 72
Andre van Tonder
(29 Aug 2005 19:20 UTC)
|
|
Re: Update to SRFI 72 (Sorry I'm lost)
Keith Wright
(31 Aug 2005 04:02 UTC)
|
|
Re: Update to SRFI 72 (Sorry I'm lost)
Panu Kalliokoski
(31 Aug 2005 12:19 UTC)
|
|
Re: Update to SRFI 72 (Sorry I'm lost) Andre van Tonder (31 Aug 2005 15:22 UTC)
|
On Wed, 31 Aug 2005, Keith Wright wrote:
> Although the above quotation occurs three times almost verbatim,
> in the abstract, the introduction, and the specification, it does
> not get any clearer with repetition. As Brian Smith used the term
> "reflective tower" it referred to an interpreter for a language
> that could express modifications to its own interpreter. I don't
> think that's what you are after, is it?
> The second mention of the "infinite reflective tower" is followed
> by a reference [11] to Richard Kelsey and Jonathan Rees
> - The Scheme 48 implementation http://s48.org/
> but a couple hours searching the Scheme 48 manual at that
> web site turned up no mention of reflective towers, and not much
> about macro expansion.
I'll try to rewrite this more clearly. I mean a reflective tower in the Scheme
48 sense, also called a syntactic tower by the authors, who indeed criticise
the word "reflective" as a misnomer, though it seems to be widespread in the
Scheme folklore. The Scheme 48 manual is notoriously cryptic, to the point of
unusability, but there is a mention on the page:
http://s48.org/1.2/manual/s48manual_33.html
If someone else has a better reference to the Scheme 48 tower, I'd be grateful
for it.
> Perhaps a better reference would be
> <a href="http://www2.parc.com/csl/groups/sda/projects/reflection96/abstracts/queinnec.html">
> Queinnec - Macroexpansion Reflective Tower</a>
I'll add the reference.
> A couple of examples of odd scope rules just isn't enough for me
> to figure out the plan. This seems to be a very big change from
> the previous proposal, and not like anything that I understand well.
>
>> * Added BEGIN-FOR-SYNTAX.
Maybe this will help: In the example
(define x 1)
(begin-for-syntax (define x 2))
(let-syntax ((m (lambda (form)
(quasisyntax (list x ,x)))))
(m)) ==> (1 2)
one would get different answers depending on whether you evaluate the
sequence of expressions one by one in the REPL, or compile the whole thing and
then run it, *unless* the runtime x and the expand-time x live in separate
namespaces or, equivalently, runtime and expand-time variables have separate
lexical scopes.
It is still lexical scoping. Any programmer worth her salt will know that the
first x in (list x ,x) denotes a runtime variable and the second x an
expand-time variable, and be able to look up the appropriate lexically preceding
binding for each.
I consider this "invariance under compilation" property the right thing to do.
> The phrase:
>> ... the hygiene algorithm of this SRFI implements a refinement of
>> lexical scoping that takes into account the level of use of an
>> identifier in determining its meaning.
>
> might be better worded as: the algorithm of this SRFI totally ignores
> lexical scoping by making the meaning of an identifier depend upon
> an invisible property called its "level" rather than its position
> in the source code. ...but I have already stated my objections
> when you first brought up this idea.
I think it is clear that one has different environment bindings at expansion
time and at runtime. In fact, there is no reason that the expansion-time
bindings have to implement standard Scheme. For example, the compile-time CAR
can be different from the runtim CAR. So the compile-time language can be
different from the runtim language.
For argument's sake, let's call the runtime-language Scheme and the
compile-time language Pascal. Now Pascal binding forms and Scheme
binding forms a priori have nothing to do with each other, so I would be very
surprised if the inner Pascal LET were to affect the x in (syntax x) at all in
the following.
(let ((x 1))
(let-syntax ((m (lambda (form)
(let ((x 2))
(syntax x)))))
(m))) ==> 1
Indeed, the x in (syntax x) represents a Scheme variable, not a Pascal variable.
It should therefore be bound by the enclosing outer Scheme LET. In other
words, Scheme code and Pascal code should have separate lexical scopes.
>> * Added SYNTACTIC-WIND.
>
> Oy.
This allows one to do a computation before and after expanding a block of code.
It is useful for maintaining environments at expansion time when implementing
things like syntax-case and pattern matchers. For example, in the syntax-case
macros I used it for maintaining the environment of pattern variables.
I included it because without it I do not know how to write syntax-case as a
library macro. I do not wish to specify syntax-case as a primitive.
>> * Removed EXPAND.
>
> Why?
Because just like EVAL, EXPAND really does not make sense without a second
argument specifying the environment. I did not wish to overcomplicate the SRFI
with a complicated explanation (and implementation) of a primitive that is used
mainly for debugging.
> ...and if it is gone, why is this code in the section
> on the reflective tower?
>
> (for-each (lambda (form) (eval (expand form))) sequence)
> == (for-each eval (map-in-order expand sequence))
The "schematically" was meant to indicate that it is just a pseudocode
expression of the previous verbal phrase.
> In other words, would the old srfi be compatible
> with the reflective tower, except that it would give errors
> (identifer used outside its scope of definition) in some cases
> where the tower would find and use a binding occurrence that
> would appear to be shadowed?
My view is that it is just wrong for a binding form in one phase to affect
variables in another phase at all. I consider the out-of-scope errors in
comparable macro systems a bug.
Cheers
Andre