<#48662#>(+<#48662#> <#48663#>(*<#48663#> <#48664#>3<#48664#> <#48665#>3)<#48665#> <#48666#>(*<#48666#> <#48667#>4<#48667#> <#48668#>4))<#48668#>we may choose to evaluate <#68907#><#48672#>(*<#48672#>\ <#48673#>3<#48673#>\ <#48674#>3)<#48674#><#68907#> and then <#68908#><#48675#>(*<#48675#>\ <#48676#>4<#48676#>\ <#48677#>4)<#48677#><#68908#> or <#48678#>vice versa<#48678#>. Fortunately, for such simple expressions, the choice doesn't affect the final outcome, so we don't have to supply a complete unambigous rule. In general, though, we rewrite subexpressions in a left-to-right and top-to-bottom order. At each stage in the evaluation, we best start by underlining the subexpression that must be evaluated next.
<#48686#>(define<#48686#> <#48687#>x<#48687#> <#48688#>aValue)<#48688#> <#48689#>...<#48689#> <#48690#>...<#48690#> <#72351#>The equation indicates that the program changes in two ways. First, the variable definition is modified. Second, the underlined <#48708#>set!<#48708#>-expression\ is replaced by <#68912#><#48709#>(<#48709#><#48710#>void<#48710#><#48711#>)<#48711#><#68912#>, the invisible value.#tex2html_wrap_inline74142#<#72351#> <#48694#>...<#48694#> <#48695#>=<#48695#> <#48696#>(define<#48696#> <#48697#>x<#48697#> <#48698#>anotherValue)<#48698#> <#48699#>...<#48699#> <#48700#>...<#48700#> <#48701#>(<#48701#><#48702#>void<#48702#><#48703#>)<#48703#> <#48704#>...<#48704#>
<#48718#>(define<#48718#> <#48719#>x<#48719#> <#48720#>aValue)<#48720#> <#48721#>...<#48721#> <#48722#>...<#48722#> <#72275#>In short, substitute the value in a state variable definition for the state variable only when the value is needed for this particular occurrence of the state variable.#tex2html_wrap_inline74144#<#72275#> <#48724#>...<#48724#> <#48725#>=<#48725#> <#48726#>(define<#48726#> <#48727#>x<#48727#> <#48728#>aValue)<#48728#> <#48729#>...<#48729#> <#48730#>...<#48730#> <#48731#>aValue<#48731#> <#48732#>...<#48732#>
<#48741#>(begin<#48741#> <#48742#>v<#48742#> <#48743#>exp-1<#48743#> <#48744#>...<#48744#> <#48745#>exp-n)<#48745#> <#48746#>=<#48746#> <#48747#>(begin<#48747#> <#48748#>exp-1<#48748#> <#48749#>...<#48749#> <#48750#>exp-n)<#48750#>That means, we also need a rule for dropping <#68916#><#48754#>begin<#48754#><#68916#> completely:
<#48759#>(begin<#48759#> <#48760#>exp)<#48760#> <#48761#>=<#48761#> <#48762#>exp<#48762#>In addition, we use a rule for dropping several values at once:
<#48770#>(begin<#48770#> <#48771#>v-1<#48771#> <#48772#>...<#48772#> <#48773#>v-m<#48773#> <#48774#>exp-1<#48774#> <#48775#>...<#48775#> <#48776#>exp-n)<#48776#> <#48777#>=<#48777#> <#48778#>(begin<#48778#> <#48779#>exp-1<#48779#> <#48780#>...<#48780#> <#48781#>exp-n)<#48781#>But this is only a convenience, nothing else.
<#48793#>(define<#48793#> <#48794#>x<#48794#> <#48795#>5)<#48795#> <#48796#>(+<#48796#> <#48797#>(begin<#48797#> <#72352#>The program consists of one definition and one addition, which is to be evaluated. One of the addition's arguments is a <#48835#>set!<#48835#>-expression\ that mutates <#68921#><#48836#>x<#48836#><#68921#>; the other is just <#68922#><#48837#>x<#48837#><#68922#>. By evaluating the subexpressions of the addition from left to right, the mutation takes place before we replace the second subexpression with its value. As a result, the outcome is <#68923#><#48838#>22<#48838#><#68923#>. If we had evaluated the addition from right to left, the result would have been <#68924#><#48839#>16<#48839#><#68924#>. To avoid such problems, we use the fixed ordering but give ourselves more freedom when no state variables are involved. The second example illustrates how a <#48840#>set!<#48840#>-expression\ that occurred in a <#48841#>local<#48841#>-expression\ actually affects a top-level definition:#tex2html_wrap_inline74146#<#72352#> <#48801#>x)<#48801#> <#48802#>x)<#48802#> <#48803#>=<#48803#> <#48804#>(define<#48804#> <#48805#>x<#48805#> <#48806#>11)<#48806#> <#48807#>(+<#48807#> <#48808#>(begin<#48808#> <#48809#>(<#48809#><#48810#>void<#48810#><#48811#>)<#48811#> <#72277#> #tex2html_wrap_inline74148#<#72277#><#48813#>)<#48813#> <#48814#>x)<#48814#> <#48815#>=<#48815#> <#48816#>...<#48816#> <#48817#>=<#48817#> <#48818#>(define<#48818#> <#48819#>x<#48819#> <#48820#>11)<#48820#> <#48821#>(+<#48821#> <#48822#>11<#48822#> <#72278#> #tex2html_wrap_inline74150#<#72278#><#48824#>)<#48824#> <#48825#>=<#48825#> <#48826#>(define<#48826#> <#48827#>x<#48827#> <#48828#>11)<#48828#> <#72353#> #tex2html_wrap_inline74152#<#72353#>
<#48846#>(d<#48846#><#48847#>efine<#48847#> <#48848#>(make-counter<#48848#> <#48849#>x0)<#48849#> <#48850#>(l<#48850#><#48851#>ocal<#48851#> <#48852#>(<#48852#><#48853#>(define<#48853#> <#48854#>counter<#48854#> <#48855#>x0)<#48855#> <#48856#>(d<#48856#><#48857#>efine<#48857#> <#48858#>(increment)<#48858#> <#48859#>(b<#48859#><#48860#>egin<#48860#> <#48861#>(set!<#48861#> <#48862#>counter<#48862#> <#48863#>(+<#48863#> <#48864#>counter<#48864#> <#48865#>1))<#48865#> <#48866#>counter)))<#48866#> <#48867#>increment))<#48867#> <#48868#>(<#48868#><#72354#>The program again consists of a single definition and an expression that is to be evaluated. The latter, however, is an application nested in an application. The inner application is underlined, because we must evaluate it to make progress. Here are the first few steps:#tex2html_wrap_inline74154#<#72354#><#48871#>)<#48871#>
<#48879#>...<#48879#> <#48880#>=<#48880#> <#48881#>(d<#48881#><#48882#>efine<#48882#> <#48883#>(make-counter<#48883#> <#48884#>x0)<#48884#> <#48885#>(l<#48885#><#48886#>ocal<#48886#> <#48887#>(<#48887#><#48888#>(define<#48888#> <#48889#>counter<#48889#> <#48890#>x0)<#48890#> <#48891#>(d<#48891#><#48892#>efine<#48892#> <#48893#>(increment)<#48893#> <#48894#>(b<#48894#><#48895#>egin<#48895#> <#48896#>(set!<#48896#> <#48897#>counter<#48897#> <#48898#>(+<#48898#> <#48899#>counter<#48899#> <#48900#>1))<#48900#> <#48901#>counter)))<#48901#> <#48902#>increment))<#48902#> <#48903#>((l<#48903#><#48904#>ocal<#48904#> <#48905#>(<#48905#><#48906#>(define<#48906#> <#48907#>counter<#48907#> <#48908#>0)<#48908#> <#48909#>(d<#48909#><#48910#>efine<#48910#> <#48911#>(increment)<#48911#> <#48912#>(b<#48912#><#48913#>egin<#48913#> <#48914#>(set!<#48914#> <#48915#>counter<#48915#> <#48916#>(+<#48916#> <#48917#>counter<#48917#> <#48918#>1))<#48918#> <#48919#>counter)))<#48919#> <#48920#>increment))<#48920#> <#48921#>=<#48921#> <#48922#>(d<#48922#><#48923#>efine<#48923#> <#48924#>(make-counter<#48924#> <#48925#>x0)<#48925#> <#48926#>(l<#48926#><#48927#>ocal<#48927#> <#48928#>(<#48928#><#48929#>(define<#48929#> <#48930#>counter<#48930#> <#48931#>x0)<#48931#> <#48932#>(d<#48932#><#48933#>efine<#48933#> <#48934#>(increment)<#48934#> <#48935#>(b<#48935#><#48936#>egin<#48936#> <#48937#>(set!<#48937#> <#48938#>counter<#48938#> <#48939#>(+<#48939#> <#48940#>counter<#48940#> <#48941#>1))<#48941#> <#48942#>counter)))<#48942#> <#48943#>increment))<#48943#> <#48944#>(define<#48944#> <#48945#>counter1<#48945#> <#48946#>0)<#48946#> <#48947#>(d<#48947#><#48948#>efine<#48948#> <#48949#>(increment1)<#48949#> <#48950#>(b<#48950#><#48951#>egin<#48951#> <#48952#>(set!<#48952#> <#48953#>counter1<#48953#> <#48954#>(+<#48954#> <#48955#>counter1<#48955#> <#48956#>1))<#48956#> <#48957#>counter1))<#48957#> <#48958#>(increment1)<#48958#>The evaluation of the <#48962#>local<#48962#>-expression\ created additional top-level expressions. One of them introduces a state variable; the others define functions. The second part of the evaluation determines what <#68926#><#48963#>(increment1)<#48963#><#68926#> accomplishes:
<#48968#>(define<#48968#> <#48969#>counter1<#48969#> <#48970#>0)<#48970#> <#72355#>During the evaluation, we replace <#68932#><#49026#>counter1<#49026#><#68932#> with its value twice. First, the second step replaces <#68933#><#49027#>counter1<#49027#><#68933#> with <#68934#><#49028#>0<#49028#><#68934#>, its value at that point. Second, we substitute <#68935#><#49029#>1<#49029#><#68935#> for <#68936#><#49030#>counter1<#49030#><#68936#> during the last step, which is its new value.#tex2html_wrap_inline74156#<#72355#> <#48972#>=<#48972#> <#48973#>(define<#48973#> <#48974#>counter1<#48974#> <#48975#>0)<#48975#> <#48976#>(b<#48976#><#48977#>egin<#48977#> <#48978#>(set!<#48978#> <#48979#>counter1<#48979#> <#48980#>(+<#48980#> <#72356#> #tex2html_wrap_inline74158#<#72356#> <#48982#>1))<#48982#> <#48983#>counter1)<#48983#> <#48984#>=<#48984#> <#48985#>(define<#48985#> <#48986#>counter1<#48986#> <#48987#>0)<#48987#> <#48988#>(b<#48988#><#48989#>egin<#48989#> <#48990#>(set!<#48990#> <#48991#>counter1<#48991#> <#72357#> #tex2html_wrap_inline74160#<#72357#><#48995#>)<#48995#> <#48996#>counter1)<#48996#> <#48997#>=<#48997#> <#48998#>(define<#48998#> <#48999#>counter1<#48999#> <#49000#>0)<#49000#> <#49001#>(b<#49001#><#49002#>egin<#49002#> <#72358#> #tex2html_wrap_inline74162#<#72358#> <#49006#>counter1)<#49006#> <#49007#>=<#49007#> <#49008#>(define<#49008#> <#49009#>counter1<#49009#> <#49010#>1)<#49010#> <#49011#>(b<#49011#><#49012#>egin<#49012#> <#49013#>(<#49013#><#49014#>void<#49014#><#49015#>)<#49015#> <#72359#> #tex2html_wrap_inline74164#<#72359#><#49017#>)<#49017#> <#49018#>=<#49018#> <#49019#>(define<#49019#> <#49020#>counter1<#49020#> <#49021#>1)<#49021#> <#49022#>1<#49022#>
<#49039#>1.<#49039#> <#49040#>(def<#49040#><#49041#>ine<#49041#> <#49042#>x<#49042#> <#49043#>11)<#49043#> <#49044#>(b<#49044#><#49045#>egin<#49045#> <#49046#>(set!<#49046#> <#49047#>x<#49047#> <#49048#>(*<#49048#> <#49049#>x<#49049#> <#49050#>x))<#49050#> <#49051#>x)<#49051#> <#49052#>2.<#49052#> <#49053#>(def<#49053#><#49054#>ine<#49054#> <#49055#>x<#49055#> <#49056#>11)<#49056#> <#49057#>(b<#49057#><#49058#>egin<#49058#> <#49059#>(s<#49059#><#49060#>et!<#49060#> <#49061#>x<#49061#> <#49062#>(c<#49062#><#49063#>ond<#49063#> <#49064#>[<#49064#><#49065#>(zero?<#49065#> <#49066#>0)<#49066#> <#49067#>22]<#49067#> <#49068#>[<#49068#><#49069#>else<#49069#> <#49070#>(/<#49070#> <#49071#>1<#49071#> <#49072#>x)]<#49072#><#49073#>))<#49073#> <#49074#>'<#49074#><#49075#>done)<#49075#> <#49076#>3.<#49076#> <#49077#>(def<#49077#><#49078#>in<#49078#><#49079#>e<#49079#> <#49080#>(run<#49080#> <#49081#>x)<#49081#> <#49082#>(run<#49082#> <#49083#>x))<#49083#> <#49084#>(run<#49084#> <#49085#>10)<#49085#> <#49086#>4.<#49086#> <#49087#>(def<#49087#><#49088#>ine<#49088#> <#49089#>(f<#49089#> <#49090#>x)<#49090#> <#49091#>(*<#49091#> <#49092#>pi<#49092#> <#49093#>x<#49093#> <#49094#>x))<#49094#> <#49095#>(define<#49095#> <#49096#>a1<#49096#> <#49097#>(f<#49097#> <#49098#>10))<#49098#> <#49099#>(b<#49099#><#49100#>egin<#49100#> <#49101#>(set!<#49101#> <#49102#>a1<#49102#> <#49103#>(-<#49103#> <#49104#>a1<#49104#> <#49105#>(f<#49105#> <#49106#>5)))<#49106#> <#49107#>'<#49107#><#49108#>done)<#49108#> <#49109#>5.<#49109#> <#49110#>(def<#49110#><#49111#>in<#49111#><#49112#>e<#49112#> <#49113#>(f)<#49113#> <#49114#>(set!<#49114#> <#49115#>state<#49115#> <#49116#>(-<#49116#> <#49117#>1<#49117#> <#49118#>state)))<#49118#> <#49119#>(define<#49119#> <#49120#>state<#49120#> <#49121#>1)<#49121#> <#49122#>(f<#49122#> <#49123#>(f<#49123#> <#49124#>(f)))<#49124#>Explain why the expression must be evaluated.~ Solution<#68937#><#68937#> <#49133#>Exercise 38.3.2<#49133#>
<#49139#>1.<#49139#> <#49140#>(def<#49140#><#49141#>ine<#49141#> <#49142#>x<#49142#> <#49143#>0)<#49143#> <#49144#>(define<#49144#> <#49145#>y<#49145#> <#49146#>1)<#49146#> <#49147#>(b<#49147#><#49148#>egin<#49148#> <#72360#>Rewrite the three programs to show the next state.~ Solution<#68941#><#68941#> <#49211#>Exercise 38.3.3<#49211#>#tex2html_wrap_inline74178#<#72360#> <#49152#>(set!<#49152#> <#49153#>y<#49153#> <#49154#>4)<#49154#> <#49155#>(+<#49155#> <#49156#>(*<#49156#> <#49157#>x<#49157#> <#49158#>x)<#49158#> <#49159#>(*<#49159#> <#49160#>y<#49160#> <#49161#>y)))<#49161#> <#49162#>2.<#49162#> <#49163#>(def<#49163#><#49164#>ine<#49164#> <#49165#>x<#49165#> <#49166#>0)<#49166#> <#49167#>(s<#49167#><#49168#>et!<#49168#> <#49169#>x<#49169#> <#49170#>(c<#49170#><#49171#>ond<#49171#> <#49172#>[<#49172#><#49173#>(zero?<#49173#> <#72361#> #tex2html_wrap_inline74182#<#72361#><#49175#>)<#49175#> <#49176#>1]<#49176#> <#49177#>[<#49177#><#49178#>else<#49178#> <#49179#>0]<#49179#><#49180#>))<#49180#> <#49181#>3.<#49181#> <#49182#>(def<#49182#><#49183#>in<#49183#><#49184#>e<#49184#> <#49185#>(f<#49185#> <#49186#>x)<#49186#> <#49187#>(c<#49187#><#49188#>ond<#49188#> <#49189#>[<#49189#><#49190#>(zero?<#49190#> <#49191#>x)<#49191#> <#49192#>1]<#49192#> <#49193#>[<#49193#><#49194#>else<#49194#> <#49195#>0]<#49195#><#49196#>))<#49196#> <#49197#>(b<#49197#><#49198#>egin<#49198#> <#72362#> #tex2html_wrap_inline74186#<#72362#> <#49202#>f)<#49202#>
<#49217#>1.<#49217#> <#49218#>(def<#49218#><#49219#>ine<#49219#> <#49220#>x<#49220#> <#49221#>0)<#49221#> <#49222#>(d<#49222#><#49223#>efine<#49223#> <#49224#>(bump<#49224#> <#49225#>delta)<#49225#> <#49226#>(b<#49226#><#49227#>egin<#49227#> <#49228#>(set!<#49228#> <#49229#>x<#49229#> <#49230#>(+<#49230#> <#49231#>x<#49231#> <#49232#>delta))<#49232#> <#49233#>x))<#49233#> <#49234#>(+<#49234#> <#49235#>(bump<#49235#> <#49236#>2)<#49236#> <#49237#>(bump<#49237#> <#49238#>3))<#49238#> <#49239#>2.<#49239#> <#49240#>(def<#49240#><#49241#>ine<#49241#> <#49242#>x<#49242#> <#49243#>10)<#49243#> <#49244#>(set!<#49244#> <#49245#>x<#49245#> <#49246#>(c<#49246#><#49247#>ond<#49247#> <#49248#>[<#49248#><#49249#>(zeor?<#49249#> <#49250#>x)<#49250#> <#49251#>13]<#49251#> <#49252#>[<#49252#><#49253#>else<#49253#> <#49254#>(/<#49254#> <#49255#>1<#49255#> <#49256#>x)]<#49256#><#49257#>))<#49257#> <#49258#>3.<#49258#> <#49259#>(def<#49259#><#49260#>in<#49260#><#49261#>e<#49261#> <#49262#>(make-box<#49262#> <#49263#>x)<#49263#> <#49264#>(l<#49264#><#49265#>ocal<#49265#> <#49266#>(<#49266#><#49267#>(define<#49267#> <#49268#>contents<#49268#> <#49269#>x)<#49269#> <#49270#>(d<#49270#><#49271#>efine<#49271#> <#49272#>(new<#49272#> <#49273#>y)<#49273#> <#49274#>(set!<#49274#> <#49275#>x<#49275#> <#49276#>y))<#49276#> <#49277#>(d<#49277#><#49278#>efine<#49278#> <#49279#>(peek)<#49279#> <#49280#>x))<#49280#> <#49281#>(list<#49281#> <#49282#>new<#49282#> <#49283#>peek))<#49283#> <#49284#>(define<#49284#> <#49285#>B<#49285#> <#49286#>(make-box<#49286#> <#49287#>55))<#49287#> <#49288#>(define<#49288#> <#49289#>C<#49289#> <#49290#>(make-box<#49290#> <#49291#>'<#49291#><#49292#>a))<#49292#> <#49293#>(b<#49293#><#49294#>egin<#49294#> <#49295#>((first<#49295#> <#49296#>B)<#49296#> <#49297#>33)<#49297#> <#49298#>((second<#49298#> <#49299#>C)))<#49299#>Underline for each step the subexpression that must be evaluated next. Only show those steps that involve a <#49303#>local<#49303#>-expression\ or a <#49304#>set!<#49304#>-expression.~ Solution<#68942#><#68942#>
<#49317#>(define<#49317#> <#49318#>(f<#49318#> <#49319#>x)<#49319#> <#49320#>x)<#49320#> <#49321#>(b<#49321#><#49322#>egin<#49322#> <#72363#>Here <#68945#><#49340#>f<#49340#><#68945#> is a state variable. The <#49341#>set!<#49341#>-expression\ changes the definition so <#68946#><#49342#>f<#49342#><#68946#> stands for a number. The next step in an evaluation substitutes <#68947#><#49343#>10<#49343#><#68947#> for the occurrence of <#68948#><#49344#>f<#49344#><#68948#>. Under ordinary circumstances, an assignment would replace a function definition with a different function definition. Take a look at this program:#tex2html_wrap_inline74194#<#72363#> <#49326#>f)<#49326#> <#49327#>=<#49327#> <#49328#>(define<#49328#> <#49329#>f<#49329#> <#49330#>10)<#49330#> <#49331#>(b<#49331#><#49332#>egin<#49332#> <#49333#>(<#49333#><#49334#>void<#49334#><#49335#>)<#49335#> <#49336#>f)<#49336#>
<#49349#>(define<#49349#> <#49350#>(f<#49350#> <#49351#>x)<#49351#> <#49352#>x)<#49352#> <#49353#>(define<#49353#> <#49354#>g<#49354#> <#49355#>f)<#49355#> <#49356#>(+<#49356#> <#49357#>(begin<#49357#> <#72364#>The purpose of the underlined <#49369#>set!<#49369#>-expression\ is to modify the definition of <#68950#><#49370#>f<#49370#><#68950#> so that it becomes a function that always produces <#68951#><#49371#>22<#49371#><#68951#>. But <#68952#><#49372#>g<#49372#><#68952#> stands for <#68953#><#49373#>f<#49373#><#68953#> initially. Since <#68954#><#49374#>f<#49374#><#68954#> is a the name of a function, we can think of <#68955#><#49375#>(define<#49375#>\ <#49376#>g<#49376#>\ <#49377#>f)<#49377#><#68955#> as a value definition. The problem is that our current rules change the definition of <#68956#><#49378#>f<#49378#><#68956#> and, by implication, the definition of <#68957#><#49379#>g<#49379#><#68957#>, because it stands for <#68958#><#49380#>f<#49380#><#68958#>:#tex2html_wrap_inline74196#<#72364#> <#49363#>5)<#49363#> <#49364#>(g<#49364#> <#49365#>1))<#49365#>
<#49385#>=<#49385#> <#49386#>(define<#49386#> <#49387#>f<#49387#> <#49388#>(lambda<#49388#> <#49389#>(x)<#49389#> <#49390#>22))<#49390#> <#49391#>(define<#49391#> <#49392#>g<#49392#> <#49393#>f)<#49393#> <#49394#>(+<#49394#> <#72365#>Scheme, however, does not behave this way. A <#49431#>set!<#49431#>-expression\ can modify only one definition at a time. Here it modifies two: <#68961#><#49432#>f<#49432#><#68961#>'s, which is intended, and <#68962#><#49433#>g<#49433#><#68962#>'s, which happens through the indirection from <#68963#><#49434#>g<#49434#><#68963#> to <#68964#><#49435#>f<#49435#><#68964#>. In short, our rules do not explain the behavior of all programs with <#68965#><#49436#>set!<#49436#>-expression<#68965#>s; we need better rules if we wish to understand Scheme fully.#tex2html_wrap_inline74198#<#72365#> <#49400#>(g<#49400#> <#49401#>1))<#49401#> <#49402#>=<#49402#> <#49403#>(define<#49403#> <#49404#>f<#49404#> <#49405#>(lambda<#49405#> <#49406#>(x)<#49406#> <#49407#>22))<#49407#> <#49408#>(define<#49408#> <#49409#>g<#49409#> <#49410#>f)<#49410#> <#49411#>(+<#49411#> <#49412#>5<#49412#> <#72366#> #tex2html_wrap_inline74200#<#72366#><#49415#>)<#49415#> <#49416#>=<#49416#> <#49417#>(define<#49417#> <#49418#>f<#49418#> <#49419#>(lambda<#49419#> <#49420#>(x)<#49420#> <#49421#>22))<#49421#> <#49422#>(define<#49422#> <#49423#>g<#49423#> <#49424#>f)<#49424#> <#49425#>(+<#49425#> <#49426#>5<#49426#> <#49427#>22)<#49427#>
<#68985#>Figure: <#49467#>Advanced Student<#49467#> Scheme: The values<#68985#> <#50113#>Beta and the Lambda Calculus<#50113#>:\ The
is enough to define all computable functions on a (simulation of) the
natural numbers. Functions that cannot be formulated in this language
are not computable.
The language and the
The problem concerns the definitions of functions, which suggests that we
take a second look at the representation of functions and function
definitions. So far, we used the names of functions as values. As we have
just seen, this choice may cause trouble in case the state variable is a
function. The solution is to use a concrete representation of
functions. Fortunately, we already have one in Scheme:
<#68986#><#49469#>lambda<#49469#>-expression<#68986#>s. Furthermore, we rewrite function definitions so that they turn
into variable definitions with a <#49470#>lambda<#49470#>-expression\ on the right-hand side:
<#49475#>(define<#49475#> <#49476#>(f<#49476#> <#49477#>x)<#49477#> <#49478#>x)<#49478#>
<#49479#>=<#49479#> <#49480#>(define<#49480#> <#49481#>f<#49481#> <#49482#>(lambda<#49482#> <#49483#>(x)<#49483#> <#49484#>x))<#49484#>
Even recursive definitions are evaluated in this manner:
<#49492#>(d<#49492#><#49493#>efine<#49493#> <#49494#>(g<#49494#> <#49495#>x)<#49495#>
<#49496#>(c<#49496#><#49497#>ond<#49497#>
<#49498#>[<#49498#><#49499#>(zero?<#49499#> <#49500#>x)<#49500#> <#49501#>1]<#49501#>
<#49502#>[<#49502#><#49503#>else<#49503#> <#49504#>(g<#49504#> <#49505#>(sub1<#49505#> <#49506#>x))]<#49506#><#49507#>))<#49507#>
<#49508#>=<#49508#> <#49509#>(d<#49509#><#49510#>efine<#49510#> <#49511#>g<#49511#>
<#49512#>(l<#49512#><#49513#>ambda<#49513#> <#49514#>(x)<#49514#>
<#49515#>(c<#49515#><#49516#>ond<#49516#>
<#49517#>[<#49517#><#49518#>(zero?<#49518#> <#49519#>x)<#49519#> <#49520#>1]<#49520#>
<#49521#>[<#49521#><#49522#>else<#49522#> <#49523#>(g<#49523#> <#49524#>(sub1<#49524#> <#49525#>x))]<#49525#><#49526#>)))<#49526#>
All other rules, especially, the rule for replacing variables with their
values remain the same.
Figure~#figadvvalues#49530> <#72367#>
The key difference is that the definition of <#68992#><#49646#>g<#49646#><#68992#> directly associates
the variable with a function representation, not just a name for a
function.
The following program shows the effects of <#68993#><#49647#>set!<#49647#>-expression<#68993#>s on functions with an extreme
example:
<#49652#>(d<#49652#><#49653#>efine<#49653#> <#49654#>(f<#49654#> <#49655#>x)<#49655#>
<#49656#>(c<#49656#><#49657#>ond<#49657#>
<#49658#>[<#49658#><#49659#>(zero?<#49659#> <#49660#>x)<#49660#> <#49661#>'<#49661#><#49662#>done]<#49662#>
<#49663#>[<#49663#><#49664#>else<#49664#> <#49665#>(f<#49665#> <#49666#>(sub1<#49666#> <#49667#>x))]<#49667#><#49668#>))<#49668#>
<#49669#>(define<#49669#> <#49670#>g<#49670#> <#49671#>f)<#49671#>
<#49672#>(b<#49672#><#49673#>egin<#49673#>
<#49674#>(set!<#49674#> <#49675#>f<#49675#> <#49676#>(lambda<#49676#> <#49677#>(x)<#49677#> <#49678#>'<#49678#><#49679#>ouch))<#49679#>
<#49680#>(symbol=?<#49680#> <#49681#>(g<#49681#> <#49682#>1)<#49682#> <#49683#>'<#49683#><#49684#>ouch))<#49684#>
The function <#68994#><#49688#>f<#49688#><#68994#> is recursive on natural numbers and always produces
<#68995#><#49689#>'<#49689#><#49690#>done<#49690#><#68995#>. Initially, <#68996#><#49691#>g<#49691#><#68996#> is defined to be <#68997#><#49692#>f<#49692#><#68997#>. The
final <#49693#>begin<#49693#>-expression\ first modifies <#68998#><#49694#>f<#49694#><#68998#> and then uses <#68999#><#49695#>g<#49695#><#68999#>.
At first, we must rewrite the function definitions according to our
modified rules:
<#49700#>...<#49700#>
<#49701#>=<#49701#> <#49702#>(d<#49702#><#49703#>efine<#49703#> <#49704#>f<#49704#>
<#49705#>(l<#49705#><#49706#>ambda<#49706#> <#49707#>(x)<#49707#>
<#49708#>(c<#49708#><#49709#>ond<#49709#>
<#49710#>[<#49710#><#49711#>(zero?<#49711#> <#49712#>x)<#49712#> <#49713#>'<#49713#><#49714#>done]<#49714#>
<#49715#>[<#49715#><#49716#>else<#49716#> <#49717#>(f<#49717#> <#49718#>(sub1<#49718#> <#49719#>x))]<#49719#><#49720#>)))<#49720#>
<#49721#>(define<#49721#> <#49722#>g<#49722#> <#72298#>
Rewriting the definition of <#69002#><#49799#>f<#49799#><#69002#> is straightforward. The major change
concerns the definition of <#69003#><#49800#>g<#49800#><#69003#>. Instead of <#69004#><#49801#>f<#49801#><#69004#> it now
contains a copy of the value for which <#69005#><#49802#>f<#49802#><#69005#> currently stands. This
value contains a reference to <#69006#><#49803#>f<#49803#><#69006#>, but that is not unusual.
Next, the <#49804#>set!<#49804#>-expression\ modifies the definition of <#69007#><#49805#>f<#49805#><#69007#>, but nothing
else:
<#49810#>...<#49810#>
<#49811#>=<#49811#> <#49812#>(d<#49812#><#49813#>efine<#49813#> <#49814#>f<#49814#>
<#49815#>(l<#49815#><#49816#>ambda<#49816#> <#49817#>(x)<#49817#>
<#49818#>'<#49818#><#49819#>ouch))<#49819#>
<#49820#>(d<#49820#><#49821#>efine<#49821#> <#49822#>g<#49822#>
<#49823#>(l<#49823#><#49824#>ambda<#49824#> <#49825#>(x)<#49825#>
<#49826#>(c<#49826#><#49827#>ond<#49827#>
<#49828#>[<#49828#><#49829#>(zero?<#49829#> <#49830#>x)<#49830#> <#49831#>'<#49831#><#49832#>done]<#49832#>
<#49833#>[<#49833#><#49834#>else<#49834#> <#49835#>(f<#49835#> <#49836#>(sub1<#49836#> <#49837#>x))]<#49837#><#49838#>)))<#49838#>
<#49839#>(b<#49839#><#49840#>egin<#49840#>
<#49841#>(<#49841#><#49842#>void<#49842#><#49843#>)<#49843#>
<#49844#>(symbol=?<#49844#> <#72373#>
In particular, the definition of <#69009#><#49852#>g<#49852#><#69009#> remains the same, though the
<#69010#><#49853#>f<#49853#><#69010#> inside of <#69011#><#49854#>g<#49854#><#69011#>'s value now refers to a new value. But we
have seen this phenomenon before. The next two steps follow the basic rules
of intermezzo~1 and yield this program:
<#49859#>=<#49859#> <#49860#>(d<#49860#><#49861#>efine<#49861#> <#49862#>f<#49862#>
<#49863#>(l<#49863#><#49864#>ambda<#49864#> <#49865#>(x)<#49865#>
<#49866#>'<#49866#><#49867#>ouch))<#49867#>
<#49868#>(d<#49868#><#49869#>efine<#49869#> <#49870#>g<#49870#>
<#49871#>(l<#49871#><#49872#>ambda<#49872#> <#49873#>(x)<#49873#>
<#49874#>(c<#49874#><#49875#>ond<#49875#>
<#49876#>[<#49876#><#49877#>(zero?<#49877#> <#49878#>x)<#49878#> <#49879#>'<#49879#><#49880#>done]<#49880#>
<#49881#>[<#49881#><#49882#>else<#49882#> <#49883#>(f<#49883#> <#49884#>(sub1<#49884#> <#49885#>x))]<#49885#><#49886#>)))<#49886#>
<#49887#>(b<#49887#><#49888#>egin<#49888#>
<#49889#>(<#49889#><#49890#>void<#49890#><#49891#>)<#49891#>
<#49892#>(symbol=?<#49892#> <#49893#>(f<#49893#> <#49894#>0)<#49894#> <#49895#>'<#49895#><#49896#>ouch))<#49896#>
<#49897#>=<#49897#> <#49898#>(d<#49898#><#49899#>efine<#49899#> <#49900#>f<#49900#>
<#49901#>(l<#49901#><#49902#>ambda<#49902#> <#49903#>(x)<#49903#>
<#49904#>'<#49904#><#49905#>ouch))<#49905#>
<#49906#>(d<#49906#><#49907#>efine<#49907#> <#49908#>g<#49908#>
<#49909#>(l<#49909#><#49910#>ambda<#49910#> <#49911#>(x)<#49911#>
<#49912#>(c<#49912#><#49913#>ond<#49913#>
<#49914#>[<#49914#><#49915#>(zero?<#49915#> <#49916#>x)<#49916#> <#49917#>'<#49917#><#49918#>done]<#49918#>
<#49919#>[<#49919#><#49920#>else<#49920#> <#49921#>(f<#49921#> <#49922#>(sub1<#49922#> <#49923#>x))]<#49923#><#49924#>)))<#49924#>
<#49925#>(b<#49925#><#49926#>egin<#49926#>
<#49927#>(<#49927#><#49928#>void<#49928#><#49929#>)<#49929#>
<#49930#>(symbol=?<#49930#> <#49931#>'<#49931#><#49932#>ouch<#49932#> <#49933#>'<#49933#><#49934#>ouch))<#49934#>
That is, the application of <#69012#><#49938#>g<#49938#><#69012#> eventually applies <#69013#><#49939#>f<#49939#><#69013#> to
<#69014#><#49940#>0<#49940#><#69014#>, which yields <#69015#><#49941#>'<#49941#><#49942#>ouch<#49942#><#69015#>. Hence the final result is
<#69016#><#49943#>true<#49943#><#69016#>.
<#49946#>Exercise 38.3.4<#49946#>
<#49953#>(d<#49953#><#49954#>efine<#49954#> <#49955#>(make-box<#49955#> <#49956#>x)<#49956#>
<#49957#>(l<#49957#><#49958#>ocal<#49958#> <#49959#>(<#49959#><#49960#>(define<#49960#> <#49961#>contents<#49961#> <#49962#>x)<#49962#>
<#49963#>(define<#49963#> <#49964#>(new<#49964#> <#49965#>y)<#49965#> <#49966#>(set!<#49966#> <#49967#>x<#49967#> <#49968#>y))<#49968#>
<#49969#>(define<#49969#> <#49970#>(peek)<#49970#> <#49971#>x))<#49971#>
<#49972#>(list<#49972#> <#49973#>new<#49973#> <#49974#>peek)))<#49974#>
<#49975#>(define<#49975#> <#49976#>B<#49976#> <#49977#>(make-box<#49977#> <#49978#>55))<#49978#>
<#49979#>(define<#49979#> <#49980#>C<#49980#> <#49981#>B)<#49981#>
<#49982#>(a<#49982#><#49983#>nd<#49983#>
<#49984#>(b<#49984#><#49985#>egin<#49985#>
<#49986#>((first<#49986#> <#49987#>B)<#49987#> <#49988#>33)<#49988#>
<#49989#>true)<#49989#>
<#49990#>(=<#49990#> <#49991#>(second<#49991#> <#49992#>C)<#49992#> <#49993#>33)<#49993#>
<#49994#>(b<#49994#><#49995#>egin<#49995#>
<#49996#>(set!<#49996#> <#49997#>B<#49997#> <#49998#>(make-box<#49998#> <#49999#>44))<#49999#>
<#50000#>(=<#50000#> <#50001#>(second<#50001#> <#50002#>C)<#50002#> <#50003#>33)))<#50003#>
Underline for each step the subexpression that must be evaluated next.
Only show those steps that involve a <#50007#>local<#50007#>-expression\ or a
<#50008#>set!<#50008#>-expression.~ Solution<#69018#><#69018#>
While we decided to rewrite function definitions so that they contain
<#69019#><#50016#>lambda<#50016#>-expression<#69019#>s, we stuck with a function application rule that assumes
function definitions in the style of <#50017#>Beginning Student<#50017#> Scheme. More
concretely, if the definition context contains a definition such as
<#50022#>(define<#50022#> <#50023#>f<#50023#> <#50024#>(lambda<#50024#> <#50025#>(x<#50025#> <#50026#>y)<#50026#> <#50027#>(+<#50027#> <#50028#>x<#50028#> <#50029#>y)))<#50029#>
and the expression is
<#50037#>(*<#50037#> <#50038#>(f<#50038#> <#50039#>1<#50039#> <#50040#>2)<#50040#> <#50041#>5)<#50041#>
then the next step in the evaluation is
<#50049#>(*<#50049#> <#50050#>(+<#50050#> <#50051#>1<#50051#> <#50052#>2)<#50052#> <#50053#>5)<#50053#>
For other occasions, however, we just replace variables with the values in
the respective definitions. If we followed that rule, we would rewrite
<#50061#>(*<#50061#> <#50062#>(f<#50062#> <#50063#>1<#50063#> <#50064#>2)<#50064#> <#50065#>5)<#50065#>
to
<#50073#>(*<#50073#> <#50074#>(<#50074#><#50075#>(lambda<#50075#> <#50076#>(x<#50076#> <#50077#>y)<#50077#> <#50078#>(+<#50078#> <#50079#>x<#50079#> <#50080#>y))<#50080#>
<#50081#>1<#50081#> <#50082#>2)<#50082#>
<#50083#>5)<#50083#>
At first glance, this exploration route ends here, because there are no
laws for this application.
We can reconcile the two ideas with a new law, suggested by the last
expression:
<#50091#>(<#50091#><#50092#>(lambda<#50092#> <#50093#>(x-1<#50093#> <#50094#>...<#50094#> <#50095#>x-n)<#50095#> <#50096#>exp)<#50096#>
<#50097#>v-1<#50097#> <#50098#>...<#50098#> <#50099#>v-n)<#50099#>
<#50100#>=<#50100#> <#50101#>exp<#50101#> <#69020#>
The law serves as a replacement of the law of application from algebra in
the study of the foundations of computing. By convention, this law is
called the ``beta value'' rule.