Newsgroups: comp.lang.scheme
Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!sdd.hp.com!news.cs.indiana.edu!hieb@heston.cs.indiana.edu
From: Robert Hieb <hieb@heston.cs.indiana.edu>
Subject: Re: Letrecs and continuations
Message-ID: <1991May20.092814.27355@news.cs.indiana.edu>
Organization: Computer Science, Indiana University
References: <CARLTON.91May18111407@husc8.harvard.edu> <ALAN.91May20014925@transit.lcs.mit.edu>
Distribution: comp
Date: Mon, 20 May 91 09:28:02 EST

alan@lcs.mit.edu (Alan Bawden) writes:

>I expect that you are right.  I note that the text accompanying the
>macro expansion for LETREC in R3RS remarks:

>  The second LET expression in the expansion is not strictly necessary, but
>  it serves to preserve the property that the <init> expressions are
>  evaluated in an arbitrary order.

>This seems to imply that the writer believed that 

>  (let ((v #f)
>	(k #f))
>    (set! v 0)
>    (set! k (call/cc (lambda (x) x)))
>    (set! v (+ v 1))
>    (k (lambda (x) v)))

>was also an acceptable implementation of LETREC, but this was unsuitable
>for the standard because it specified the order of evaluation.  I don't
>think the writer realized he had accidentally specified that all the
>assignments must take place -after- all the initializers were evaluated.
>(Probably he thought there was no way to detect that.)

R^3.99, section 4.2.2, states that for a "letrec":

   Semantics:  The <variable>s are bound to fresh locations
   holding undefined values, the <init>s are evaluated in the
   resulting environment (in some unspecified order), each
   <variable> is assigned to the result of the corresponding
   <init>, the <body> is evaluated in the resulting environment,
   and the value of the last expression in <body> is returned.

This implies that the evaluation of all the initial values takes place
before any of the values are assigned to their respective variables.
That is what the rewrite rule for "letrec" in section 7.3 does, but the
above does not, so it may not be accidental after all.

One can still get away with optimizing the implementation of "letrec",
but only in special circumstances.  In particular one must watch out
for complex right-hand-sides and assigned variables.  Doing so would
seem to rule out treating "letrec" as a derived form (macro), since it
is not reasonable for the expander to do such complex analysis.

As a side point, the statement that the variable locations are
initialized with "undefined" values also makes expanding "letrec" as a
macro undesirable.  The original posting used "#f", which is rather
well defined.  I suppose that, since the meaning of "undefined" is not
specified, one could substitute "unspecified value," but that doesn't
seem to be the intent.

This is certainly an area that should be cleared up.
