[racket] internal definitions in r6rs

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Sat Sep 18 21:53:42 EDT 2010

This is a bug in the R6RS binding for `define'. Your program works as
it should if you use

 (define a
   (lambda ()
     (define (b) "who cares?")
     (define c (b))
     c))

or

 (define (a)
   (let ()
     (define (b) "who cares?")
     (define c (b))
     c))

because the problem is specific to `define' with the function
shorthand.

I've pushed a repair.

At Sat, 18 Sep 2010 12:52:26 +0200, "Jos Koot" wrote:
> Hi,
>  
> Section 11.3 of R6RS states: "An expanded <body> (see chapter 10) containing
> variable definitions can always be converted into an equivalent letrec*
> expression." The semantics of letrec* includes "each <variable> is assigned
> in left-to-right order". This I interpret as allowing an internal definition
> to refer to the value of a previously defined variable. However:
>  
> #!r6rs
>  
> (import
>  (rnrs base (6))
>  (rnrs io simple (6)))
>  
> (define (a)
>   (define (b) "who cares?")
>   (define c (b))
>   c)
>  
> (write (a))
>  
> Produces:
>  
> Welcome to DrRacket, version
> 5.0.1.5--2010-09-13(5b54caebb066920e2585244a5ee444a3f121c966/a) [3m].
> Language: r6rs; memory limit: 2000 MB.
> . . procedure application: expected procedure, given: #<undefined> (no
> arguments)
>  
> The code expands as follows. The hot spots is marked with an arrow.
>  
> (module anonymous-module r6rs
>   (#%plain-module-begin
>    (#%require r6rs/private/prelims)
>    (#%require (lib "rnrs/base-6.rkt"))
>    (#%require (for-meta #f (lib "rnrs/base-6.rkt")))
>    (#%require (lib "rnrs/io/simple-6.rkt"))
>    (#%require (for-meta #f (lib "rnrs/io/simple-6.rkt")))
>    (define-values (a)
>      (#%plain-lambda
>       ()
>       (let-values (((b) undefined) ((c) undefined))
>         (let-values ; <====== prohibits reference to value of previously
> defined var
>             (((newtemp)
>               (#%plain-lambda () (letrec-values () (let-values () '"who
> cares?"))))
>              ((newtemp:19) (#%app b))) ; <======
>           (set! b newtemp)
>           (set! c newtemp:19)
>           (let-values:20 () (let-values:21 () c))))))
>    (#%app write (#%app a))))
> 
> Is this a bug or do I misunderstand R6RS?
> The following works correct:
>  
> #!r6rs
>  
> (import
>  (rnrs base (6))
>  (rnrs io simple (6)))
>  
> (define (a)
>   (letrec*
>    ((b (lambda () "who cares?"))
>     (c (b)))
>    c))
>  
> (write (a))
>  
> Thanks, Jos
> _________________________________________________
>   For list-related administrative tasks:
>   http://lists.racket-lang.org/listinfo/users


Posted on the users mailing list.