<#52175#>(d<#52175#><#52176#>efine<#52176#> <#52177#>(fm-make-posn<#52177#> <#52178#>x0<#52178#> <#52179#>y0)<#52179#>
<#52180#>(l<#52180#><#52181#>ocal<#52181#> <#52182#>(<#52182#><#52183#>(define<#52183#> <#52184#>x<#52184#> <#52185#>y0)<#52185#>
<#52186#>(define<#52186#> <#52187#>y<#52187#> <#52188#>y0)<#52188#>
<#52189#>(d<#52189#><#52190#>efine<#52190#> <#52191#>(service-manager<#52191#> <#52192#>msg)<#52192#>
<#52193#>(c<#52193#><#52194#>ond<#52194#>
<#52195#>[<#52195#><#52196#>(symbol=?<#52196#> <#52197#>msg<#52197#> <#52198#>'<#52198#><#52199#>x)<#52199#> <#52200#>x]<#52200#>
<#52201#>[<#52201#><#52202#>(symbol=?<#52202#> <#52203#>msg<#52203#> <#52204#>'<#52204#><#52205#>y)<#52205#> <#52206#>y]<#52206#>
<#52207#>[<#52207#><#52208#>(symbol=?<#52208#> <#52209#>msg<#52209#> <#52210#>'<#52210#><#52211#>set-x)<#52211#> <#52212#>(lambda<#52212#> <#52213#>(x-new)<#52213#> <#52214#>(set!<#52214#> <#52215#>x<#52215#> <#52216#>x-new))]<#52216#>
<#52217#>[<#52217#><#52218#>(symbol=?<#52218#> <#52219#>msg<#52219#> <#52220#>'<#52220#><#52221#>set-y)<#52221#> <#52222#>(lambda<#52222#> <#52223#>(y-new)<#52223#> <#52224#>(set!<#52224#> <#52225#>y<#52225#> <#52226#>y-new))]<#52226#>
<#52227#>[<#52227#><#52228#>else<#52228#> <#52229#>(error<#52229#> <#52230#>'<#52230#><#52231#>posn<#52231#> <#52232#>``...'')]<#52232#><#52233#>)))<#52233#>
<#52234#>service-manager))<#52234#>
<#52235#>(d<#52235#><#52236#>efine<#52236#> <#52237#>(fm-posn-x<#52237#> <#52238#>p)<#52238#>
<#52239#>(p<#52239#> <#52240#>'<#52240#><#52241#>x))<#52241#>
<#52242#>(d<#52242#><#52243#>efine<#52243#> <#52244#>(fm-posn-y<#52244#> <#52245#>p)<#52245#>
<#52246#>(p<#52246#> <#52247#>'<#52247#><#52248#>y))<#52248#>
<#52249#>(d<#52249#><#52250#>efine<#52250#> <#52251#>(fm-set-posn-x!<#52251#> <#52252#>p<#52252#> <#52253#>new-value)<#52253#>
<#52254#>((p<#52254#> <#52255#>'<#52255#><#52256#>set-x)<#52256#> <#52257#>new-value))<#52257#>
<#52258#>(d<#52258#><#52259#>efine<#52259#> <#52260#>(fm-set-posn-y!<#52260#> <#52261#>p<#52261#> <#52262#>new-value)<#52262#>
<#52263#>((p<#52263#> <#52264#>'<#52264#><#52265#>set-y)<#52265#> <#52266#>new-value))<#52266#>
<#69275#>Figure: An implementation of <#52270#>posn<#52270#>s with mutators<#69275#>
Together, sections~#secencapsulate#52272>
and~#secstructfunc#52273> suggest that structures are mutable. That is, we
should be able to change the values of some field in a structure. After
all, we introduced the service managers in section~#secencapsulate#52274> to
hide state variables, not just ordinary variable definitions.
Figure~#figimperativeposn#52275> shows how a small change to the
definitions of figure~#figfunctionalposn#52276> turns the <#69276#><#52277#>local<#52277#><#69276#>ly
hidden variables into state variables. The modified service manager offers
two services per state variable: one for looking up the current value and
one for changing it.
Consider the following definition and expression:
<#52282#>(define<#52282#> <#52283#>a-posn<#52283#> <#52284#>(fm-make-posn<#52284#> <#52285#>3<#52285#> <#52286#>4))<#52286#>
<#52287#>(b<#52287#><#52288#>egin<#52288#>
<#52289#>(fm-set-posn-x!<#52289#> <#52290#>a-posn<#52290#> <#52291#>5)<#52291#>
<#52292#>(+<#52292#> <#52293#>(posn-x<#52293#> <#52294#>a-posn)<#52294#> <#52295#>8))<#52295#>
Evaluating them by hand shows how structures change. Here is the first
step:
<#52303#>...<#52303#>
<#52304#>=<#52304#>
<#52305#>(define<#52305#> <#52306#>x-for-a-posn<#52306#> <#52307#>3)<#52307#>
<#52308#>(define<#52308#> <#52309#>y-for-a-posn<#52309#> <#52310#>4)<#52310#>
<#52311#>(d<#52311#><#52312#>efine<#52312#> <#52313#>(service-manager-for-a-posn<#52313#> <#52314#>msg)<#52314#>
<#52315#>(c<#52315#><#52316#>ond<#52316#>
<#52317#>[<#52317#><#52318#>(symbol=?<#52318#> <#52319#>msg<#52319#> <#52320#>'<#52320#><#52321#>x)<#52321#> <#52322#>x-for-a-posn]<#52322#>
<#52323#>[<#52323#><#52324#>(symbol=?<#52324#> <#52325#>msg<#52325#> <#52326#>'<#52326#><#52327#>y)<#52327#> <#52328#>y-for-a-posn]<#52328#>
<#52329#>[<#52329#><#52330#>(symbol=?<#52330#> <#52331#>msg<#52331#> <#52332#>'<#52332#><#52333#>set-x)<#52333#>
<#52334#>(lambda<#52334#> <#52335#>(x-new)<#52335#> <#52336#>(set!<#52336#> <#52337#>x-for-a-posn<#52337#> <#52338#>x-new))]<#52338#>
<#52339#>[<#52339#><#52340#>(symbol=?<#52340#> <#52341#>msg<#52341#> <#52342#>'<#52342#><#52343#>set-y)<#52343#>
<#52344#>(lambda<#52344#> <#52345#>(y-new)<#52345#> <#52346#>(set!<#52346#> <#52347#>y-for-a-posn<#52347#> <#52348#>y-new))]<#52348#>
<#52349#>[<#52349#><#52350#>else<#52350#> <#52351#>(error<#52351#> <#52352#>'<#52352#><#52353#>posn<#52353#> <#52354#>``...'')]<#52354#><#52355#>))<#52355#>
<#52356#>(define<#52356#> <#52357#>a-posn<#52357#> <#52358#>service-manager-for-a-posn)<#52358#>
<#52359#>(b<#52359#><#52360#>egin<#52360#>
<#52361#>(fm-set-posn-x!<#52361#> <#52362#>a-posn<#52362#> <#52363#>5)<#52363#>
<#52364#>(+<#52364#> <#52365#>(posn-x<#52365#> <#52366#>a-posn)<#52366#> <#52367#>8))<#52367#>
It renames and lifts the local definitions from inside of
<#69277#><#52371#>fm-make-posn<#52371#><#69277#>. Because the function definition doesn't change for
the rest of the evaluation, we focus on just the variable definitions:
<#52376#>(define<#52376#> <#52377#>x-for-a-posn<#52377#> <#52378#>3)<#52378#>
<#52379#>(define<#52379#> <#52380#>y-for-a-posn<#52380#> <#52381#>4)<#52381#>
<#52382#>(b<#52382#><#52383#>egin<#52383#>
<#52384#>(fm-set-posn-x!<#52384#> <#52385#>a-posn<#52385#> <#52386#>5)<#52386#>
<#52387#>(+<#52387#> <#52388#>(posn-x<#52388#> <#52389#>a-posn)<#52389#> <#52390#>8))<#52390#>
<#52391#>=<#52391#> <#52392#>(define<#52392#> <#52393#>x-for-a-posn<#52393#> <#52394#>3)<#52394#>
<#52395#>(define<#52395#> <#52396#>y-for-a-posn<#52396#> <#52397#>4)<#52397#>
<#52398#>(b<#52398#><#52399#>egin<#52399#>
<#52400#>(fm-set-posn-x!<#52400#> <#52401#>service-manager-for-a-posn<#52401#> <#52402#>5)<#52402#>
<#52403#>(+<#52403#> <#52404#>(posn-x<#52404#> <#52405#>a-posn)<#52405#> <#52406#>8))<#52406#>
<#52407#>=<#52407#> <#52408#>(define<#52408#> <#52409#>x-for-a-posn<#52409#> <#52410#>3)<#52410#>
<#52411#>(define<#52411#> <#52412#>y-for-a-posn<#52412#> <#52413#>4)<#52413#>
<#52414#>(b<#52414#><#52415#>egin<#52415#>
<#52416#>((service-manager-for-a-posn<#52416#> <#52417#>'<#52417#><#52418#>set-x)<#52418#> <#52419#>5)<#52419#>
<#52420#>(+<#52420#> <#52421#>(posn-x<#52421#> <#52422#>a-posn)<#52422#> <#52423#>8))<#52423#>
<#52424#>=<#52424#> <#52425#>(define<#52425#> <#52426#>x-for-a-posn<#52426#> <#52427#>3)<#52427#>
<#52428#>(define<#52428#> <#52429#>y-for-a-posn<#52429#> <#52430#>4)<#52430#>
<#52431#>(b<#52431#><#52432#>egin<#52432#>
<#52433#>(set!<#52433#> <#52434#>x-for-a-posn<#52434#> <#52435#>5)<#52435#>
<#52436#>(+<#52436#> <#52437#>(posn-x<#52437#> <#52438#>a-posn)<#52438#> <#52439#>8))<#52439#>
<#52440#>=<#52440#> <#52441#>(define<#52441#> <#52442#>x-for-a-posn<#52442#> <#52443#>5)<#52443#>
<#52444#>(define<#52444#> <#52445#>y-for-a-posn<#52445#> <#52446#>4)<#52446#>
<#52447#>(+<#52447#> <#52448#>(posn-x<#52448#> <#52449#>a-posn)<#52449#> <#52450#>8)<#52450#>
At this point, the definition of <#69278#><#52454#>x-for-a-posn<#52454#><#69278#> has been modified in
the expected manner. From now on every reference to this state variable,
which represents the (simulated) <#69279#><#52455#>x<#52455#><#69279#> field <#69280#><#52456#>a-posn<#52456#><#69280#>, stands
for <#69281#><#52457#>5<#52457#><#69281#>. Every further reference to <#69282#><#52458#>x-for-a-posn<#52458#><#69282#> produces
<#69283#><#52459#>5<#52459#><#69283#>.
<#52462#>Exercise 40.2.1<#52462#>
Develop a functional representation for the following structure definition:
<#52468#>(define-struct<#52468#> <#52469#>boyfriend<#52469#> <#52470#>(name<#52470#> <#52471#>hair<#52471#> <#52472#>eyes<#52472#> <#52473#>phone))<#52473#>
such that the fields of the simulated structure can be changed.~ Solution<#69284#><#69284#>
<#52482#>Exercise 40.2.2<#52482#>
Here is a modification of the function-based implementation of
<#69285#><#52484#>posn<#52484#><#69285#> structures in exercise~#exfuncstruct1#52485>:
<#52490#>(d<#52490#><#52491#>efine<#52491#> <#52492#>(ffm-make-posn<#52492#> <#52493#>x0<#52493#> <#52494#>y0)<#52494#>
<#52495#>(local<#52495#> <#52496#>(<#52496#><#52497#>(define<#52497#> <#52498#>x<#52498#> <#52499#>x0)<#52499#>
<#52500#>(define<#52500#> <#52501#>(set-x<#52501#> <#52502#>new-x)<#52502#> <#52503#>(set!<#52503#> <#52504#>x<#52504#> <#52505#>new-x))<#52505#>
<#52506#>(define<#52506#> <#52507#>y<#52507#> <#52508#>y0)<#52508#>
<#52509#>(define<#52509#> <#52510#>(set-y<#52510#> <#52511#>new-y)<#52511#> <#52512#>(set!<#52512#> <#52513#>y<#52513#> <#52514#>new-y)))<#52514#>
<#52515#>(l<#52515#><#52516#>ambda<#52516#> <#52517#>(select)<#52517#>
<#52518#>(select<#52518#> <#52519#>x<#52519#> <#52520#>y<#52520#> <#52521#>set-x<#52521#> <#52522#>set-y))))<#52522#>
<#52523#>(d<#52523#><#52524#>efine<#52524#> <#52525#>(ffm-posn-x<#52525#> <#52526#>a-ffm-posn)<#52526#>
<#52527#>(a-ffm-posn<#52527#> <#52528#>(lambda<#52528#> <#52529#>(x<#52529#> <#52530#>y<#52530#> <#52531#>sx<#52531#> <#52532#>sy)<#52532#> <#52533#>x)))<#52533#>
<#52534#>(d<#52534#><#52535#>efine<#52535#> <#52536#>(ffm-posn-y<#52536#> <#52537#>a-ffm-posn)<#52537#>
<#52538#>(a-ffm-posn<#52538#> <#52539#>(lambda<#52539#> <#52540#>(x<#52540#> <#52541#>y<#52541#> <#52542#>sx<#52542#> <#52543#>sy)<#52543#> <#52544#>y)))<#52544#>
<#52545#>(d<#52545#><#52546#>efine<#52546#> <#52547#>(ffm-set-posn-x!<#52547#> <#52548#>a-ffm-posn<#52548#> <#52549#>new-value)<#52549#>
<#52550#>(a-ffm-posn<#52550#> <#52551#>(lambda<#52551#> <#52552#>(x<#52552#> <#52553#>y<#52553#> <#52554#>sx<#52554#> <#52555#>sy)<#52555#> <#52556#>(sx<#52556#> <#52557#>new-value))))<#52557#>
<#52558#>(d<#52558#><#52559#>efine<#52559#> <#52560#>(ffm-set-posn-y!<#52560#> <#52561#>a-ffm-posn<#52561#> <#52562#>new-value)<#52562#>
<#52563#>(a-ffm-posn<#52563#> <#52564#>(lambda<#52564#> <#52565#>(x<#52565#> <#52566#>y<#52566#> <#52567#>sx<#52567#> <#52568#>sy)<#52568#> <#52569#>(sy<#52569#> <#52570#>new-value))))<#52570#>
Demonstrate how to modify a structure like <#69286#><#52574#>(ffm-make-posn<#52574#>\ <#52575#>3<#52575#>\ <#52576#>4)<#52576#><#69286#> so
that its <#69287#><#52577#>y<#52577#><#69287#> field contains <#69288#><#52578#>5<#52578#><#69288#>.~ Solution<#69289#><#69289#>