Can letrec be the same as letrec*?

106 views Asked by At

If I have implemented letrec* in my Scheme interpreter, can I simply implement letrec by making it the same as letrec*? Is this allowed by the Scheme standards?

1

There are 1 answers

1
mnemenaut On

Hmmm...

r6rs uses the language "It should be possible to evaluate each <init> without assigning or referring to the value of any <variable>" (emphasis added), but I think the formal semantics indicates that implementations must raise an exception:

$ scheme
> (letrec ([x 1]
           [y (+ x 1)])
    y)
Exception: attempt to reference undefined variable x

> (alias letrec letrec*)
> (letrec ([x 1]
           [y (+ x 1)])
    y)
2
> 

( (alias letrec letrec*) is Chez to make letrec the same as letrec* )

r7rs provides a letrec macro expanding to let and set! (page 69 of the PDF):

(define-syntax letrec
        (syntax-rules ()
  ((letrec ((var1 init1) ...) body ...)
    (letrec "generate temp names"
             (var1 ...)
             ()
             ((var1 init1) ...)
             body ...))
  ((letrec "generate temp names" ()
             (temp1 ...)
             ((var1 init1) ...)
             body ...)
           (let ((var1 0 #|<undefined>|#) ...)
             (let ((temp1 init1) ...)
               (set! var1 temp1)
               ...
               body ...)))
  ((letrec "generate temp names" (x y ...)
             (temp ...)
             ((var1 init1) ...)
             body ...)
  (letrec "generate temp names" (y ...)
             (newtemp temp ...)
             ((var1 init1) ...)
             body ...))))

(nb <undefined> replaced by 0) Using this produces:

> (letrec ([x 1]
           [y (+ x 1)])
    `(,x . ,y))
(1 . 1)
>

(One can (expand '(letrec ([x 1] [y (+ x 1)]) y)) in Chez Scheme to see why)

(edit: Ghuloum & Dybvig 2009 Fixing Letrec (reloaded) (PDF) discusses letrec and letrec*)