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.