On Sep 6, 2009, at 2:57 AM, Brian Harvey wrote:

> If there's a REPL, there aren't any phases.  The REPL keeps shifting  
> back
> and forth between syntax and semantics.


Can you please explain to me how the REPL involves phase-shifting in a  
way that an ordinary top-level program does not in the case when only  
`syntax-rules' is allowed on the right side of a `define-syntax' or  
`let-syntax' form?

More generally, can you explain why forms which are input at the REPL  
can't be treated identically to the forms of a top-level program, even  
when a lower-level macro system is involved? As long as the user is  
given the opportunity to reinitialize the top-level REPL environment  
by starting a new top-level program with a fresh set of library  
imports, I don't see why the semantics of the REPL need be any more  
confusing than the semantics of top-level programs themselves. Such a  
Scheme (excuse the pun) could be used to directly translate the  
semantics of R6RS top-level programs to REPL semantics:

* When the REPL is initialized, a new top-level program is created  
with an implementation-chosen set of initial bindings, preferably  
containing at least (rnrs (6)) at phase (meta 0).
* When a certain token is encountered at the REPL, a fresh top-level  
environment is created, and the REPL waits to read an `import' form to  
define the bindings available in this environment. The natural choice  
for this token is "#!r6rs".
* To aid in meta-programming at the REPL, the top-level environment  
previously created at the REPL can be assigned a name and be made  
available as a library for import at this point. In an implicitly- 
phased implementation, the bindings are available directly. A separate- 
instantiation implementation must record the top-level forms entered  
at the REPL for future instantiations of the library.

This adds no more phase-shifting to the REPL semantics beyond that  
which is already present in the semantics of top-level programs. All  
phase boundaries are explicitly marked as such.

Here's an example of how this would work:

$ hypothetical-r6rs
 > (define a 42)
 > (define-syntax b (lambda (stx) a))
WARNING: reference to unbound identifier `a' in phase 1.
 > #!r6rs
(import (rnrs base (6))
         (rnrs syntax-case (6))
         (for (rnrs base (6)) (meta -1)))
 > (define foo (lambda (stx) (syntax-case stx () ((_ a body ...)  
(identifier? #'a) #'(let ((a 42)) body ...)))))
 > (define bar (display "hi"))
OUTPUT: hi
 > #!r6rs
(import (rnrs base (6))
         (top-level 1 ())
         (for (top-level 0 ()) (meta 1)))
OUTPUT: hi ; in a separate-instantiation implementation only
 > (define-syntax baz foo)
 > (baz n (+ a n))
84
 > bar
ERROR: reference to unbound identifier `bar' in phase 0.

--
Brian Mastenbrook
[email protected]
http://brian.mastenbrook.net/


_______________________________________________
r6rs-discuss mailing list
[email protected]
http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss

Reply via email to