The hand-evaluation shows that the <#68076#><#44214#>local<#44214#><#68076#> definition for <#68077#><#44215#>z<#44215#><#68077#>
serves to evaluate a <#68078#><#44216#>set!<#44216#>-expression<#68078#> and ``to throw away'' its
value. After all, a <#68079#><#44217#>set!<#44217#><#68079#>'s true purpose is to change a definition
and not to generate a value. Because this situation is quite common, Scheme
also provides the <#68080#><#44218#>begin<#44218#>-expression<#68080#>:
<#44223#>(begin<#44223#> <#44224#>exp-1<#44224#>
<#44225#>...<#44225#>
<#44226#>exp-n<#44226#>
<#44227#>exp)<#44227#>
A <#68081#><#44231#>begin<#44231#>-expression<#68081#> consists of the keyword <#68082#><#44232#>begin<#44232#><#68082#> followed
by a sequence of n+1 expressions. The evaluation determines the values of
all expressions, in order, and then throws away the first n. The value of
the last expression is the value of the entire <#68083#><#44233#>begin<#44233#>-expression<#68083#>.
In general, the first n subexpressions in a <#68084#><#44234#>begin<#44234#>-expression<#68084#>
change some definitions; only the last one has an interesting value.
We can now rewrite our first sample program with <#68085#><#44235#>set!<#44235#><#68085#> into
a short expression:
<#44240#>(define<#44240#> <#44241#>x<#44241#> <#44242#>3)<#44242#>
<#44243#>(begin<#44243#> <#44244#>(set!<#44244#> <#44245#>x<#44245#> <#44246#>(+<#44246#> <#44247#>x<#44247#> <#44248#>2))<#44248#>
<#44249#>x)<#44249#>
The use of <#68086#><#44253#>begin<#44253#><#68086#> not only simplifies the program, it also suggests
a straight-line ordering of the evaluation.
The hand-evaluation also shows that the evaluation of <#68087#><#44254#>set!<#44254#><#68087#>
expressions introduce additional timing constraints. More concretely, the
above evaluation consists of two parts: the one before and the one after
the assignment exerted its effect on the state of the definitions. Before
we introduced assignments, we could replace a variable by its value or a
function application by the function's body whenever we wished. Now, we
must wait until we truly need the value of a variable before we perform the
substitution. After all, definitions may change.
While some partial ordering is always a part of computation, the timing
constraints of <#68088#><#44255#>set!<#44255#><#68088#> are new. By altering a definition, an
assignment ``destroys'' the current value. Unless the programmer carefully
plans the arrangement of assignments, such an action may be fatal. The
exercises illustrate the problem in more detail.
~<#68089#>Finally, an evaluation is no longer a manipulation of a single expression. Instead, we must rewrite the <#44257#>entire<#44257#> program, that is, the definitions and the expression, when we wish to evaluate a program. <#68089#>
<#44260#>Exercise 35.2.1<#44260#>
Evaluate the following program by hand:
<#44266#>(define<#44266#> <#44267#>x<#44267#> <#44268#>1)<#44268#>
<#44269#>(define<#44269#> <#44270#>y<#44270#> <#44271#>1)<#44271#>
<#44272#>(begin<#44272#> <#44273#>(set!<#44273#> <#44274#>x<#44274#> <#44275#>(+<#44275#> <#44276#>x<#44276#> <#44277#>1))<#44277#>
<#44278#>(set!<#44278#> <#44279#>y<#44279#> <#44280#>(-<#44280#> <#44281#>y<#44281#> <#44282#>1))<#44282#>
<#44283#>(*<#44283#> <#44284#>x<#44284#> <#44285#>y))<#44285#>
How many time periods can we distinguish in this hand-evaluation?
Compare this with the evaluation of
<#44293#>(define<#44293#> <#44294#>a<#44294#> <#44295#>5)<#44295#>
<#44296#>(*<#44296#> <#44297#>(+<#44297#> <#44298#>a<#44298#> <#44299#>1)<#44299#> <#44300#>(-<#44300#> <#44301#>a<#44301#> <#44302#>1)))<#44302#>
Does the nesting imply an ordering among our calculations? Does the order
of addition and subtraction matter?~ Solution<#68090#><#68090#>
<#44311#>Exercise 35.2.2<#44311#>
Evaluate the following program by hand:
<#44317#>(define<#44317#> <#44318#>x<#44318#> <#44319#>3)<#44319#>
<#44320#>(define<#44320#> <#44321#>y<#44321#> <#44322#>5)<#44322#>
<#44323#>(begin<#44323#> <#44324#>(set!<#44324#> <#44325#>x<#44325#> <#44326#>y)<#44326#>
<#44327#>(set!<#44327#> <#44328#>y<#44328#> <#44329#>x)<#44329#>
<#44330#>(list<#44330#> <#44331#>x<#44331#> <#44332#>y))<#44332#>
How many time periods can we distinguish in this hand-evaluation?
Now evaluate the following:
<#44340#>(define<#44340#> <#44341#>x<#44341#> <#44342#>3)<#44342#>
<#44343#>(define<#44343#> <#44344#>y<#44344#> <#44345#>5)<#44345#>
<#44346#>(l<#44346#><#44347#>ocal<#44347#> <#44348#>((define<#44348#> <#44349#>z<#44349#> <#44350#>x))<#44350#>
<#44351#>(begin<#44351#> <#44352#>(set!<#44352#> <#44353#>x<#44353#> <#44354#>y)<#44354#>
<#44355#>(set!<#44355#> <#44356#>y<#44356#> <#44357#>z)<#44357#>
<#44358#>(list<#44358#> <#44359#>x<#44359#> <#44360#>y)))<#44360#>
Is it true that the definition of <#68091#><#44364#>x<#44364#><#68091#> contains the initial value of
<#68092#><#44365#>y<#44365#><#68092#> and <#68093#><#44366#>y<#44366#><#68093#> contains the initial value of <#68094#><#44367#>x<#44367#><#68094#> after
the two <#68095#><#44368#>set!<#44368#>-expression<#68095#>s are evaluated, no matter what the initial
values are?
Discuss what the two examples teach us about time and ``destruction of
values'' in definitions.~ Solution<#68096#><#68096#>
<#44374#>Exercise 35.2.3<#44374#>
Evaluate the following program by hand:
<#44380#>(define<#44380#> <#44381#>x<#44381#> <#44382#>3)<#44382#>
<#44383#>(define<#44383#> <#44384#>y<#44384#> <#44385#>5)<#44385#>
<#44386#>(b<#44386#><#44387#>egin<#44387#>
<#44388#>(set!<#44388#> <#44389#>x<#44389#> <#44390#>y)<#44390#>
<#44391#>(set!<#44391#> <#44392#>y<#44392#> <#44393#>(+<#44393#> <#44394#>y<#44394#> <#44395#>2))<#44395#>
<#44396#>(set!<#44396#> <#44397#>x<#44397#> <#44398#>3)<#44398#>
<#44399#>(list<#44399#> <#44400#>x<#44400#> <#44401#>y))<#44401#>
How many time intervals must we distinguish in this hand-evaluation?~ Solution<#68097#><#68097#>