<< Previous exercise (4.16) | Index | Next exercise (4.18) >>

Sequential definition:

```
((lambda <vars>
(define u <e1>)
(define v <e2>)
<e3>) <inputs>)
```

will evaluate `<e3>` in the environment:

GLOBAL ------ FRAME1 (<e3> evaluated here) ------ <vars>: <inputs> u: <e1> v: <e2>

(where each frame is a child of the one above it.)

Simultaneous definition:

```
((lambda <vars> (let ((u '*unassigned*)
(v '*unassigned*))
(set! u <e1>)
(set! v <e2>)
<e3>)) <inputs>)
```

expands to

```
((lambda <vars> (lambda (u v)
(set! u <e1>)
(set! v <e2>)
<e3>)
'*unassigned* '*unassigned*)
<inputs>)
```

and since there are two lambdas, there are two frames:

GLOBAL ------ FRAME1 ------ <vars>: <inputs> FRAME2 (<e3> evaluated here) ------ u: <e1> v: <e2>

It's pretty clear that evaluating an expression in either environment will give the same values for all variables, and thus the same result.

In addition to @meteorgan's idea of replacing `(let ((u '*unassigned*) (v '*unassigned)) ...)` with `(define u '*unassigned*) (define v '*unassigned) ...`, one can imagine a solution that would essentially translate the whole expression to

```
((lambda (<vars> u v)
(set! u <e1>)
(set! v <e2>)
<e3>)
<inputs> '*unassigned* '*unassigned*)
```

Doing this would require modifying how procedures are applied to inputs, i.e., replace

```
(eval-sequence (procedure-body procedure)
(extend-environment (procedure-parameters procedure)
arguments
(procedure-environment procedure)))
```

in the definition of `apply` with

(eval-sequence (procedure-body procedure) (extend-environment (append (procedure-parameters procedure) (internally-defined-vars procedure)) (append arguments (unassigneds procedure)) (procedure-environment procedure)))

with appropriate definitions of the undefined terms, and modifications to the internal representation of procedures. I think this is all pretty academic, so excuse me if I leave out the details.

meteorgan