Consider the following definition and expression:
<#43987#>(define<#43987#> <#43988#>x<#43988#> <#43989#>3)<#43989#>
<#43990#>(l<#43990#><#43991#>ocal<#43991#> <#43992#>((define<#43992#> <#43993#>z<#43993#> <#43994#>(set!<#43994#> <#43995#>x<#43995#> <#43996#>(+<#43996#> <#43997#>x<#43997#> <#43998#>2))))<#43998#>
<#43999#>x)<#43999#>
The definition says that <#68044#><#44003#>x<#44003#><#68044#> stands for <#68045#><#44004#>3<#44004#><#68045#>. The
<#68046#><#44005#>local<#44005#>-expression<#68046#> introduces a definition for <#68047#><#44006#>z<#44006#><#68047#>. Its body
is <#68048#><#44007#>x<#44007#><#68048#> so, in the past, the value of this <#68049#><#44008#>local<#44008#>-expression<#68049#>
would have been <#68050#><#44009#>3<#44009#><#68050#> (if anything). Now, with <#68051#><#44010#>set!<#44010#><#68051#> in the
language, this is no longer true. To understand what happens, we must
rewrite the program step by step until we have a final answer.
The first step in the evaluation lifts the <#68052#><#44011#>local<#44011#><#68052#> definition:
<#44016#>(define<#44016#> <#44017#>x<#44017#> <#44018#>3)<#44018#>
<#44019#>(define<#44019#> <#44020#>z<#44020#> <#44021#>(set!<#44021#> <#44022#>x<#44022#> <#44023#>(+<#44023#> <#44024#>x<#44024#> <#44025#>2)))<#44025#>
<#44026#>x<#44026#>
Next we must determine the value of <#68053#><#44030#>(set!<#44030#>\ <#44031#>x<#44031#>\ <#44032#>(+<#44032#>\ <#44033#>x<#44033#>\ <#44034#>2))<#44034#><#68053#>. According to
the general explanation of <#68054#><#44035#>set!<#44035#><#68054#>, this requires the evaluation of
the right-hand side of the assignment:
<#44040#>(define<#44040#> <#44041#>x<#44041#> <#44042#>3)<#44042#>
<#44043#>(define<#44043#> <#44044#>z<#44044#> <#44045#>(set!<#44045#> <#44046#>x<#44046#> <#44047#>5))<#44047#>
<#44048#>x<#44048#>
That value is <#68055#><#44052#>5<#44052#><#68055#> because the current value of <#68056#><#44053#>x<#44053#><#68056#> is
<#68057#><#44054#>3<#44054#><#68057#>.
Finally, the general explanation says that the effect of the <#68058#><#44055#>set!<#44055#><#68058#>
expression is to change the value that the left-hand side variable
represents. In our example this means that from now on, <#68059#><#44056#>x<#44056#><#68059#> is no
longer <#68060#><#44057#>3<#44057#><#68060#> but <#68061#><#44058#>5<#44058#><#68061#>. The best way to express this change is to
modify the definition of <#68062#><#44059#>x<#44059#><#68062#> for the next step:
<#44064#>(define<#44064#> <#44065#>x<#44065#> <#44066#>5)<#44066#>
<#44067#>(define<#44067#> <#44068#>z<#44068#> <#44069#>(<#44069#><#44070#>void<#44070#><#44071#>))<#44071#>
<#44072#>x<#44072#>
The value of <#68063#><#44076#>set!<#44076#><#68063#> is <#68064#><#44077#>(<#44077#><#44078#>void<#44078#><#44079#>)<#44079#><#68064#>, the invisible value. By
replacing the <#68065#><#44080#>set!<#44080#>-expression<#68065#> with the invisible value, we indicate that its
evaluation is finished.
At this point, it is easy to see that the result is <#68066#><#44081#>5<#44081#><#68066#>. The first
definition says that <#68067#><#44082#>x<#44082#><#68067#> currently represents <#68068#><#44083#>5<#44083#><#68068#>, and the
last expression is <#68069#><#44084#>x<#44084#><#68069#>. Hence, the value of the function evaluation
is <#68070#><#44085#>5<#44085#><#68070#>.
<#44088#>Exercise 35.1.1<#44088#>
Consider the following:
-
<#44095#>(set!<#44095#> <#44096#>x<#44096#> <#44097#>5)<#44097#>
-
<#44105#>(define<#44105#> <#44106#>x<#44106#> <#44107#>3)<#44107#>
<#44108#>(set!<#44108#> <#44109#>(+<#44109#> <#44110#>x<#44110#> <#44111#>1)<#44111#> <#44112#>5)<#44112#>
-
<#44120#>(define<#44120#> <#44121#>x<#44121#> <#44122#>3)<#44122#>
<#44123#>(define<#44123#> <#44124#>y<#44124#> <#44125#>7)<#44125#>
<#44126#>(define<#44126#> <#44127#>z<#44127#> <#44128#>false)<#44128#>
<#44129#>(set!<#44129#> <#44130#>(if<#44130#> <#44131#>z<#44131#> <#44132#>x<#44132#> <#44133#>y)<#44133#> <#44134#>5)<#44134#>
Which ones are syntactically legal programs? Which ones are
illegal?~ Solution<#68071#><#68071#>
<#44144#>Exercise 35.1.2<#44144#>
Evaluate the following program:
<#44150#>(define<#44150#> <#44151#>x<#44151#> <#44152#>1)<#44152#>
<#44153#>(define<#44153#> <#44154#>y<#44154#> <#44155#>1)<#44155#>
<#44156#>(l<#44156#><#44157#>ocal<#44157#> <#44158#>(<#44158#><#44159#>(define<#44159#> <#44160#>u<#44160#> <#44161#>(set!<#44161#> <#44162#>x<#44162#> <#44163#>(+<#44163#> <#44164#>x<#44164#> <#44165#>1)))<#44165#>
<#44166#>(define<#44166#> <#44167#>v<#44167#> <#44168#>(set!<#44168#> <#44169#>y<#44169#> <#44170#>(-<#44170#> <#44171#>y<#44171#> <#44172#>1))))<#44172#>
<#44173#>(*<#44173#> <#44174#>x<#44174#> <#44175#>y))<#44175#>
If <#68072#><#44179#>set!<#44179#><#68072#> were not a part of the language, what could we say about
the result of the <#68073#><#44180#>local<#44180#>-expression<#68073#>? That is, consider the skeleton
<#44185#>(define<#44185#> <#44186#>x<#44186#> <#44187#>1)<#44187#>
<#44188#>(define<#44188#> <#44189#>y<#44189#> <#44190#>1)<#44190#>
<#44191#>(l<#44191#><#44192#>ocal<#44192#> <#44193#>(<#44193#><#44194#>(define<#44194#> <#44195#>u<#44195#> <#44196#>...)<#44196#>
<#44197#>(define<#44197#> <#44198#>v<#44198#> <#44199#>...))<#44199#>
<#44200#>(*<#44200#> <#44201#>x<#44201#> <#44202#>y))<#44202#>
where the right-hand sides of the definitions have been removed. What would
this expression have produced before the introduction of
<#68074#><#44206#>set!<#44206#>-expression<#68074#>s?~ Solution<#68075#><#68075#>