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