Reputation: 10930
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?
Upvotes: 0
Views: 111
Reputation: 820
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*)
Upvotes: 2