[plt-scheme] to define, or to let

From: Anton van Straaten (anton at appsolutions.com)
Date: Sun Mar 21 12:25:50 EST 2004

Matthew Flatt wrote:
> 1. Evaluation order is a different issue from allowing access to
>    previously-bound variables in the right-hand side of a `letrec'
>    binding.

True.  Of course, with letrec, if you can rely on eval order, it becomes
natural to expect that you can rely on access to previously bound variables
in that letrec.  That was the connection made earlier in this thread with
one of the examples Richard Cleis raised.

Without being able to rely on access to previously bound variables in
letrec, the only use for a defined eval order is sequencing of side effects,
which I imagine is not what is wanted most of the time from a defined eval
order for letrec.

> The former is in the spirit of adding hash tables, etc. These are
> extras that you can rely on in MzScheme, but not in plain R5RS.

I agree.

> 2. MzScheme is not actually R5RS-compliant.
> Anton is obviously correct --- it's the time at which the variables
> receive their values that makes MzScheme non-compliant, not the lack of
> an error, and not the order of right-hand-side evaluation. I've been
> sloppy to leave the "MzScheme is R5RS" claims in place.

I think it would be fine to say "MzScheme is R5RS except for...", as many
implementations do.

> 2. Internal defines versus `letrec'.
> I agree that `letrec*' is a more natural target for a sequence of
> internal definitions.

Me too.

> In fact, it's possible that `letrec*' will appear in R6RS for this


> 3. Changing MzScheme's `letrec' to match R5RS.
> I don't know.

I don't think this is essential.  I mentioned it myself, but I meant it as
"it would be nice if...".

> Originally, `letrec*' was included in MzScheme so that programmers
> could explicitly request the current behavior. But I only saw the
> is-an-error difference, and not the time-of-assignment difference, so I
> defined `letrec' as an alias for `letrec*'. Of course, no one used
> `letrec*', so it was dropped.

Most other implementations seem to have done something similar.

> For v300, we could restore `letrec*' and make `letrec' compliant with
> R5RS. But we would also need something like `begin*' to have internal
> definitions expand to `letrec*' (since R5RS requires `letrec'), and
> that's where it starts to get painful.
> Another possibility is to add `letrec*', change `letrec', and define
> internal-definition expansion to use `letrec*'. MzScheme would remain
> technically non-compliant with R5RS, but it might be well-positioned for
> R6RS compliance.

I think the bigger issue (relatively speaking) is how R6RS will deal with
this.  Introducing letrec* into R6RS and basing internal define on it -
which I think is an excellent idea - won't affect the non-compliance of all
the implementations which rely on the letrec extension.  An obvious solution
would be for R6RS to change the letrec spec to that of letrec*, and perhaps
introduce a letrec-pure for anyone who wants or needs it.  I don't like that
much myself, but it's pragmatic.


Posted on the users mailing list.