4.19 Exercise 4.19
Consider the following:
(let ((a 1)) (define (f x) (define b (+ a x)) (define a 5) (+ a b)) (f 10))
What should the result be? We are given a few options:
16, because b is computed to be 11 (using the definition of a as 1) and a is then reset to 5
No value – because the internal definition of a would be lifted and unassigned at the time the value of b is computed
20, because the internal definition are truly simultaneous and a has the value of 5
I believe the first option is a violation of the semantics of the language as I understand them, which state that internal definitions are computed simultaneously. But the meaning of "simultaneously" is tricky, as supporting the third option requires us to traverse the definitions to compute the dependencies between them to attempt to reorder them such that they can be computed sequentially (as they must be in practice).
Alternatively, if the definition of b (which references that of a) were only computed at the point when it is used, which takes place after the sequence of internal definitions, then the use of the internal definition of a would almost naturally fall out. However, this would not be in line with Scheme’s strict evaluation.
It’s not clear to me that there is a simple way to decide whether a set of internal definitions can be reordered such that they can be evaluated sequentially. For a counterexample, consider the following:
(let ((a 1)) (define b a) (define a b) (+ a b))
By the intuition of strictly sequential definitions, one could imagine what this might do. But given that the internal definitions are done "simultaneously", this expression isn’t meaningful at all.
In light of this, allowing the procedure to evaluate to an error due to the referencing of an unassigned value seems to me to be a reasonable thing to do.