[r6rs-discuss] Import choices: flexibility vs. discoverability
Per Bothner
per at bothner.com
Tue Oct 13 21:53:22 EDT 2009
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
per at bothner.com http://per.bothner.com/
More information about the r6rs-discuss
mailing list