On 10/13/2009 06:28 PM, John Cowan wrote:
> Per Bothner scripsit:
>
>> OTOH, it would be nice to allow define in the middle of a body, to avoid
>> having to add too much "let-nesting":
>>
>> (define (foo)
>>     (define t1 ....)
>>     (bar t1)
>>     (define t2 (baz t1))
>>     (whatever t1 t2))
>
> That would be a pretty big change, from LETREC* semantics to LET*
> semantics, or are you still allowed the limited kind of forward reference
> that internal DEFINE currently allows?  If so, I think the scope would
> be hard to understand.

I think the best way to do this is to use LETREC* semantics, where
a non-final <expression> is equivalent to
   (define <unused> <expression>)
So the above is equivalent to:

(define (foo)
   (letrec* ((t1 ...)
             (unused1 (bar t1))
             (t2 (baz t1)))
      (whatever t1 t2))

When it comes to forward references:

(define t1 ...)
(define (foo)
   (baz t1) ;; References the following t1
   (define t1 ...)
   (whatever t1))

The initial t1 would be in the scope of the following definition,
not any outer definition.  Of course this program is erroneous,
but in the same way forward references are currently dynamically
disallowed (as in the "Implementation responsibilities" note in
the R6RS definition of letrec*).

(I would allow an implementation to catch such invalid
forward references at compile-time, rather than evaluation-time,
but that's a general issue of compile-time detection of
program errors.)
-- 
        --Per Bothner
[email protected]   http://per.bothner.com/

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

Reply via email to