[comp.lang.scheme] Internal Definitions

math1205@waikato.ac.nz (06/29/90)

In a book by H. Abelson & G. Sussman entitled "Structure and Interpretation
of Computer Programs" (1985) there is a section on the evaluation of internal
definitions (pp. 439-442). In here they show there are several ways to evaluate
multiple internal definitions which can lead to inconsistent results when the 
definitions reference each other. 

For example, the expression
(let ((a 1))
  (define (f x)
    (define b (+ a x))
    (define a 5)
    (+ a b))
  (f 10))
can return different results depending on whether the definition of a and b
are evaluated simultaneously or in sequence; returning 20 or 16 resp. The book
suggests a simultaneous evaluation of definitions is the desired approach, but
because this is difficult to implement, they note the MIT implementors of
Scheme generate an error in the above case.
As I see the Scheme description given in R^nRS, expressions in the body of f
should be evaluated in sequence and therefore the above should return 16.

Who agrees/disagrees?
 

Also in the DEC Scheme->C implementation the above expression returns the rather
confusing value of 15. I assume this is caused by a having the value of 0 when
the definition of b is evaluated. I think this is a bug!

Who agrees/disagrees?

-Wayne Schou
math1205@waikato.ac.nz

markf@ZURICH.AI.MIT.EDU (06/29/90)

>> (let ((a 1))
>>   (define (f x)
>>     (define b (+ a x))
>>     (define a 5)
>>     (+ a b))
>>   (f 10))

>> As I see the Scheme description given in R^nRS, expressions in the body of f
>> should be evaluated in sequence and therefore the above should return 16.
>> 
>> Who agrees/disagrees?

I disagree. Internal definitions are not like other expressions in the
body of let expressions (or procedures, or begin blocks, etc.). The
section in the reports on internal defines explains that the above
expression is equivalent to the following letrec:

(let ((a 1))
  (define (f x)
    (letrec ((b (+ a x))
	     (a 5))
      (+ a b)))
  (f 10))

The section on letrec says that it must be possible to evaluate each
initialization expression (e.g. "(+ a x)" and "5" in the above)
without referring to the value of any of the variables bound by the
letrec. 

The above expression is in error since there is a reference to the
variable "a" in the initialization expression for the variable "b".

Note that the r3.99 (and the r4rs to come) explicitly mentions the
restriction with respect to internal defines. In r3rs the restriction
is implicit.

>> Also in the DEC Scheme->C implementation the above expression returns
>> the rather confusing value of 15. I assume this is caused by a having
>> the value of 0 when the definition of b is evaluated. I think this is
>> a bug!
>> 
>> Who agrees/disagrees?

Naturally, I disagree again. Since the expression is in error, and the
report does not say that this error must be signalled, Scheme->C is
free to do anything it wants with the expression.

-Mark


Mark Friedman
MIT Artificial Intelligence Lab
545 Technology Sq.
Cambridge, Ma. 02139

markf@zurich.ai.mit.edu

max@Neon.Stanford.EDU (Max Hailperin) (06/29/90)

In article <904.268b61d9@waikato.ac.nz> math1205@waikato.ac.nz writes:
>In a book by H. Abelson & G. Sussman entitled "Structure and Interpretation
>of Computer Programs" (1985) there is a section on the evaluation of internal
>definitions (pp. 439-442). In here they show there are several ways to evaluate
>multiple internal definitions which can lead to inconsistent results when the 
>definitions reference each other. 
>
>For example, the expression
>(let ((a 1))
>  (define (f x)
>    (define b (+ a x))
>    (define a 5)
>    (+ a b))
>  (f 10))
>can return different results depending on whether the definition of a and b
>are evaluated simultaneously or in sequence; returning 20 or 16 resp. The book
>suggests a simultaneous evaluation of definitions is the desired approach, but
>because this is difficult to implement, they note the MIT implementors of
>Scheme generate an error in the above case.
>As I see the Scheme description given in R^nRS, expressions in the body of f
>should be evaluated in sequence and therefore the above should return 16.
>
>Who agrees/disagrees?

I disagree.  Yes, the *expressions* in the body of f should be evaluated in
sequence, but technically definitions are not expressions, if you read R^3R
carefully.  Definitions are treated differently; they are treated as a letrec.
Letrec is defined such that it is an error, which the implementation *may*
signal, to do something such as the example.  If you used the actual formal
semantics expansion, an error would indeed be signaled.  But, it is explicitly
sanctioned to omit this.  Under this guise of a "non-signaled error," it is
legal to extend the semantics to work the way you expect, and some
implementations do.  However, it is also equally legal to not signal the
error, but do something else other than your sequential version.  This explains
the Scheme->C result you observed.  Therefore, I disagree with you on that
as well.