Structures from Functions


<#51818#>(define-struct<#51818#> <#51819#>posn<#51819#> <#51820#>(x<#51820#> <#51821#>y))<#51821#>














<#51827#>(d<#51827#><#51828#>efine<#51828#> <#51829#>(f-make-posn<#51829#> <#51830#>x0<#51830#> <#51831#>y0)<#51831#>
  <#51832#>(l<#51832#><#51833#>ocal<#51833#> <#51834#>(<#51834#><#51835#>(define<#51835#> <#51836#>x<#51836#> <#51837#>y0)<#51837#> 
          <#51838#>(define<#51838#> <#51839#>y<#51839#> <#51840#>y0)<#51840#> 
          <#51841#>(d<#51841#><#51842#>efine<#51842#> <#51843#>(service-manager<#51843#> <#51844#>msg)<#51844#> 
            <#51845#>(c<#51845#><#51846#>ond<#51846#> 
              <#51847#>[<#51847#><#51848#>(symbol=?<#51848#> <#51849#>msg<#51849#> <#51850#>'<#51850#><#51851#>x)<#51851#> <#51852#>x]<#51852#> 
              <#51853#>[<#51853#><#51854#>(symbol=?<#51854#> <#51855#>msg<#51855#> <#51856#>'<#51856#><#51857#>y)<#51857#> <#51858#>y]<#51858#> 
              <#51859#>[<#51859#><#51860#>else<#51860#> <#51861#>(error<#51861#> <#51862#>'<#51862#><#51863#>posn<#51863#> <#51864#>``...'')]<#51864#><#51865#>)))<#51865#> 
    <#51866#>service-manager))<#51866#> 

<#51867#>(d<#51867#><#51868#>efine<#51868#> <#51869#>(f-posn-x<#51869#> <#51870#>p)<#51870#> 
  <#51871#>(p<#51871#> <#51872#>'<#51872#><#51873#>x))<#51873#> 

<#51874#>(d<#51874#><#51875#>efine<#51875#> <#51876#>(f-posn-y<#51876#> <#51877#>p)<#51877#> 
  <#51878#>(p<#51878#> <#51879#>'<#51879#><#51880#>y))<#51880#> 
<#69242#>Figure: A functional analog of <#51884#>posn<#51884#><#69242#>
Take a look at figure~#figfunctionalposn#51886>. The left-hand side is the one-line definition of a <#69243#><#51887#>posn<#51887#><#69243#> structure. The right-hand side is a functional definition that provides almost all the same services. In particular, the definition provides a constructor that consumes two values and constructs a compound value, and two selectors for extracting the values that went into the construction of a compound value. To understand why <#69244#><#51888#>f-make-posn<#51888#><#69244#> is a constructor and why <#69245#><#51889#>f-posn-x<#51889#><#69245#> and <#69246#><#51890#>f-posn-y<#51890#><#69246#> are selectors, we can discuss how they work, and we can confirm that they validate the expected equations. Here we do both, because the definitions are unusual. The definition of <#69247#><#51891#>f-make-posn<#51891#><#69247#> encapsulates two variable definitions and one function definition. The two variables stand for the arguments of <#69248#><#51892#>f-make-posn<#51892#><#69248#> and the function is a service manager; it produces the value of <#69249#><#51893#>x<#51893#><#69249#> when given <#69250#><#51894#>'<#51894#><#51895#>x<#51895#><#69250#> and the value of <#69251#><#51896#>y<#51896#><#69251#> when given <#69252#><#51897#>'<#51897#><#51898#>y<#51898#><#69252#>. In the preceding section, we might have written something like
<#51903#>(define<#51903#> <#51904#>a-posn<#51904#> <#51905#>(f-make-posn<#51905#> <#51906#>3<#51906#> <#51907#>4))<#51907#>
<#51908#>(+<#51908#> <#51909#>(a-posn<#51909#> <#51910#>'<#51910#><#51911#>x)<#51911#> <#51912#>(a-posn<#51912#> <#51913#>'<#51913#><#51914#>y))<#51914#> 
to define and to compute with <#69253#><#51918#>f-make-posn<#51918#><#69253#>. Since selecting values is such a frequent operation, figure~#figfunctionalposn#51919> introduces the functions <#69254#><#51920#>f-posn-x<#51920#><#69254#> and <#69255#><#51921#>f-posn-y<#51921#><#69255#>, which perform these computations. When we first introduced structures rigorously in intermezzo~1, we said that the selectors and constructors can be described with equations. For a definition such as that for <#69256#><#51922#>posn<#51922#><#69256#>, the two relevant equations are:
  <#51927#>(posn-x<#51927#> <#51928#>(make-posn<#51928#> <#51929#>V-1<#51929#> <#51930#>V-2))<#51930#> 
<#51931#>=<#51931#> <#51932#>V-1<#51932#> 
<#51933#>;and<#51933#> 
  <#51934#>(posn-y<#51934#> <#51935#>(make-posn<#51935#> <#51936#>V-1<#51936#> <#51937#>V-2))<#51937#> 
<#51938#>=<#51938#> <#51939#>V-2<#51939#> 
where <#69257#><#51943#>V-1<#51943#><#69257#> and <#69258#><#51944#>V-2<#51944#><#69258#> are arbitrary values. To confirm that <#69259#><#51945#>f-posn-x<#51945#><#69259#> and <#69260#><#51946#>f-make-posn<#51946#><#69260#> are in the same relationship as <#69261#><#51947#>posn-x<#51947#><#69261#> and <#69262#><#51948#>make-posn<#51948#><#69262#>, we can validate that they satisfy the first equation:
  <#51953#>(f-posn-x<#51953#> <#51954#>(f-make-posn<#51954#> <#51955#>3<#51955#> <#51956#>4))<#51956#>
<#51957#>=<#51957#> <#51958#>(f-posn-x<#51958#> <#51959#>(local<#51959#> <#51960#>(<#51960#><#51961#>(define<#51961#> <#51962#>x<#51962#> <#51963#>3)<#51963#> 
                    <#51964#>(define<#51964#> <#51965#>y<#51965#> <#51966#>4)<#51966#> 
                    <#51967#>(d<#51967#><#51968#>efine<#51968#> <#51969#>(service-manager<#51969#> <#51970#>msg)<#51970#> 
                      <#51971#>(c<#51971#><#51972#>ond<#51972#> 
                        <#51973#>[<#51973#><#51974#>(symbol=?<#51974#> <#51975#>msg<#51975#> <#51976#>'<#51976#><#51977#>x)<#51977#> <#51978#>x]<#51978#> 
                        <#51979#>[<#51979#><#51980#>(symbol=?<#51980#> <#51981#>msg<#51981#> <#51982#>'<#51982#><#51983#>y)<#51983#> <#51984#>y]<#51984#> 
                        <#51985#>[<#51985#><#51986#>else<#51986#> <#51987#>(error<#51987#> <#51988#>'<#51988#><#51989#>posn<#51989#> <#51990#>``...'')]<#51990#><#51991#>)))<#51991#> 
            <#51992#>service-manager))<#51992#> 
<#52000#>=<#52000#> <#52001#>(f-posn-x<#52001#> <#52002#>service-manager)<#52002#>
  <#52003#>;; add to top-level definitions:<#52003#> 
  <#52004#>(define<#52004#> <#52005#>x<#52005#> <#52006#>3)<#52006#> 
  <#52007#>(define<#52007#> <#52008#>y<#52008#> <#52009#>4)<#52009#> 
  <#52010#>(d<#52010#><#52011#>efine<#52011#> <#52012#>(service-manager<#52012#> <#52013#>msg)<#52013#> 
    <#52014#>(c<#52014#><#52015#>ond<#52015#> 
      <#52016#>[<#52016#><#52017#>(symbol=?<#52017#> <#52018#>msg<#52018#> <#52019#>'<#52019#><#52020#>x)<#52020#> <#52021#>x]<#52021#> 
      <#52022#>[<#52022#><#52023#>(symbol=?<#52023#> <#52024#>msg<#52024#> <#52025#>'<#52025#><#52026#>y)<#52026#> <#52027#>y]<#52027#> 
      <#52028#>[<#52028#><#52029#>else<#52029#> <#52030#>(error<#52030#> <#52031#>'<#52031#><#52032#>posn<#52032#> <#52033#>``...'')]<#52033#><#52034#>))<#52034#> 
<#52042#>=<#52042#> <#52043#>(service-manager<#52043#> <#52044#>'<#52044#><#52045#>x)<#52045#>
<#52046#>=<#52046#> <#52047#>(c<#52047#><#52048#>ond<#52048#> 
    <#52049#>[<#52049#><#52050#>(symbol=?<#52050#> <#52051#>'<#52051#><#52052#>x<#52052#> <#52053#>'<#52053#><#52054#>x)<#52054#> <#52055#>x]<#52055#> 
    <#52056#>[<#52056#><#52057#>(symbol=?<#52057#> <#52058#>'<#52058#><#52059#>x<#52059#> <#52060#>'<#52060#><#52061#>y)<#52061#> <#52062#>y]<#52062#> 
    <#52063#>[<#52063#><#52064#>else<#52064#> <#52065#>(error<#52065#> <#52066#>'<#52066#><#52067#>posn<#52067#> <#52068#>``...'')]<#52068#><#52069#>)<#52069#> 
<#52070#>=<#52070#> <#52071#>x<#52071#> 
<#52072#>=<#52072#> <#52073#>3<#52073#> 
It is an exercise to show that <#69263#><#52077#>f-posn-y<#52077#><#69263#> and <#69264#><#52078#>f-make-posn<#52078#><#69264#> satisfy the analogous equation.
<#52081#>Exercise 40.1.1<#52081#> Which function does the simulation of structures not provide? Why not?~ external Solution<#69265#><#69265#> <#52088#>Exercise 40.1.2<#52088#> Here is yet another implementation of <#69266#><#52090#>posn<#52090#><#69266#> structures:
<#52095#>(d<#52095#><#52096#>efine<#52096#> <#52097#>(ff-make-posn<#52097#> <#52098#>x<#52098#> <#52099#>y)<#52099#>
  <#52100#>(l<#52100#><#52101#>ambda<#52101#> <#52102#>(select)<#52102#> 
    <#52103#>(select<#52103#> <#52104#>x<#52104#> <#52105#>y)))<#52105#> 
<#52106#>(d<#52106#><#52107#>efine<#52107#> <#52108#>(ff-posn-x<#52108#> <#52109#>a-ff-posn)<#52109#> 
  <#52110#>(a-ff-posn<#52110#> <#52111#>(lambda<#52111#> <#52112#>(x<#52112#> <#52113#>y)<#52113#> <#52114#>x)))<#52114#> 
<#52115#>(d<#52115#><#52116#>efine<#52116#> <#52117#>(ff-posn-y<#52117#> <#52118#>a-ff-posn)<#52118#> 
  <#52119#>(a-ff-posn<#52119#> <#52120#>(lambda<#52120#> <#52121#>(x<#52121#> <#52122#>y)<#52122#> <#52123#>y)))<#52123#> 
Evaluate <#69267#><#52127#>(ff-posn-x<#52127#>\ <#52128#>(ff-make-posn<#52128#>\ <#52129#>V-1<#52129#>\ <#52130#>V2))<#52130#><#69267#> in this context. What does the calculation demonstrate?~ external Solution<#69268#><#69268#> <#52136#>Exercise 40.1.3<#52136#> Provide functional implementations for these structure definitions:
  1. <#69269#><#52139#>(define-struct<#52139#>\ <#52140#>movie<#52140#>\ <#52141#>(title<#52141#>\ <#52142#>producer))<#52142#><#69269#>
  2. <#69270#><#52143#>(define-struct<#52143#>\ <#52144#>boyfriend<#52144#>\ <#52145#>(name<#52145#>\ <#52146#>hair<#52146#>\ <#52147#>eyes<#52147#>\ <#52148#>phone))<#52148#><#69270#>
  3. <#69271#><#52149#>(define-struct<#52149#>\ <#52150#>cheerleader<#52150#>\ <#52151#>(name<#52151#>\ <#52152#>number))<#52152#><#69271#>
  4. <#69272#><#52153#>(define-struct<#52153#>\ <#52154#>CD<#52154#>\ <#52155#>(artist<#52155#>\ <#52156#>title<#52156#>\ <#52157#>price))<#52157#><#69272#>
  5. <#69273#><#52158#>(define-struct<#52158#>\ <#52159#>sweater<#52159#>\ <#52160#>(material<#52160#>\ <#52161#>size<#52161#>\ <#52162#>producer))<#52162#><#69273#>~ external Solution<#69274#><#69274#>