[plt-scheme] about letrec and continuation : which behavior is correct ? and why ?
Jumping in here...
I wasn't aware that "letrec" was defined in terms of its let/set!
semantics (though I knew that it could be so defined). I had always
assumed that it was a primitive. To muddy the waters further, I believe
that R6RS says that internal defines are actually translated into
"letrec*", even though I don't know of any Scheme implementation that
actually supports "letrec*". It's all a big mess. I also hate it wrt
teaching, because SICP, for instance, describes define to have very
simple semantics, but this isn't at all what internal defines really do
(I'm guessing that the reason for this is that implementing internal
defines in terms of some letrec or let/set! primitives is easier to
optimize). So users expect that internal defines behave in ways similar
to top-level defines, which they do not. This significantly undercuts
the argument that Scheme is a "simple, elegant" language. I don't know
of a good way out, either.
I kind of like the Ocaml model where there are exactly two let forms,
"let" (which makes one binding only) and "let rec" (which makes any
number of mutually-recursive bindings). However, the syntax would be
awkward for Scheme, and even in Ocaml, top-level lets behave differently
(there is an implicit "in" which scopes over the rest of the file). I
don't know if Ocaml resolves "let rec" to let/set!, but I doubt it.
One other gripe: I've read in some places that PLT Scheme has about 12
fundamental special forms, but I can't find any documentation about
which forms they are. Is that an oversight or intentional? I'm sure
there is no desire to set Scheme primitives in stone, but it would be
nice to know what forms an expression will eventually expand into.
None of this is meant to detract from the enormous respect I have for
PLT Scheme and its implementors, of course.
Mike