<#10450#>empty<#10450#> <#10451#>(cons<#10451#> <#10452#>1.22<#10452#> <#10453#>empty)<#10453#> <#10454#>(cons<#10454#> <#10455#>2.59<#10455#> <#10456#>empty)<#10456#> <#10457#>(cons<#10457#> <#10458#>1.22<#10458#> <#10459#>(cons<#10459#> <#10460#>2.59<#10460#> <#10461#>empty))<#10461#> <#10462#>(cons<#10462#> <#10463#>17.05<#10463#> <#10464#>(cons<#10464#> <#10465#>1.22<#10465#> <#10466#>(cons<#10466#> <#10467#>2.59<#10467#> <#10468#>empty)))<#10468#>Again, for a real store, we cannot place an arbitrary limit on the size of such a list, and functions that process such cost lists must be prepared to consume lists of arbitrary size. Suppose the toy store needs a function that computes the value of an inventory from the cost of the individual toys. We call this function <#62231#><#10472#>sum<#10472#><#62231#>. Before we can define <#62232#><#10473#>sum<#10473#><#62232#>, we must figure out how to describe all possible lists of numbers that the function may consume. In short, we need a data definition that precisely defines what an arbitrarily large list of numbers is. We can obtain this definition by replacing ``symbol'' with ``number'' in the definition of lists of symbols:
A <#62233#><#10475#>list of numbers<#10475#><#62233#> (<#62234#><#10476#>list-of-numbers<#10476#><#62234#>) is eitherGiven that this data definition is self-referential again, we must first confirm that it actually defines some lists and that it defines all those inventories that we wish to represent. All of the examples from above are lists of numbers. The first one, <#62239#><#10486#>empty<#10486#><#62239#>, is included explicitly. The second and third are <#62240#><#10487#>cons<#10487#><#62240#>tructed by adding the numbers <#62241#><#10488#>1.22<#10488#><#62241#> and <#62242#><#10489#>2.59<#10489#><#62242#>, respectively, to the empty list. The others are lists of numbers for similar reasons. As always, we start the development of the function with a contract, header, and purpose statement:
- the empty list, <#62235#><#10478#>empty<#10478#><#62235#>, or
- <#62236#><#10479#>(cons<#10479#>\ <#10480#>n<#10480#>\ <#10481#>lon)<#10481#><#62236#> where <#62237#><#10482#>n<#10482#><#62237#> is a number and <#62238#><#10483#>lon<#10483#><#62238#> is a list of numbers.
<#70968#>;; <#62243#><#10494#>sum<#10494#> <#10495#>:<#10495#> <#10496#>list-of-numbers<#10496#> <#10497#><#10497#><#10498#>-;SPMgt;<#10498#><#10499#><#10499#> <#10500#>number<#10500#><#62243#><#70968#> <#70969#>;; to compute the sum of the numbers on <#62244#><#10501#>a-list-of-nums<#10501#><#62244#><#70969#> <#10502#>(define<#10502#> <#10503#>(sum<#10503#> <#10504#>a-list-of-nums)<#10504#> <#10505#>...)<#10505#>Then we continue with function examples:
<#10513#>(sum<#10513#> <#10514#>empty)<#10514#> <#10515#>=<#10515#> <#10516#>0<#10516#>
<#10524#>(sum<#10524#> <#10525#>(cons<#10525#> <#10526#>1.00<#10526#> <#10527#>empty))<#10527#> <#10528#>=<#10528#> <#10529#>1.0<#10529#>
<#10537#>(sum<#10537#> <#10538#>(cons<#10538#> <#10539#>17.05<#10539#> <#10540#>(cons<#10540#> <#10541#>1.22<#10541#> <#10542#>(cons<#10542#> <#10543#>2.59<#10543#> <#10544#>empty))))<#10544#> <#10545#>=<#10545#> <#10546#>20.86<#10546#>If <#62245#><#10550#>sum<#10550#><#62245#> is applied to <#62246#><#10551#>empty<#10551#><#62246#>, the store has no inventory and the result should be <#62247#><#10552#>0<#10552#><#62247#>. If the input is <#62248#><#10553#>(cons<#10553#>\ <#10554#>1.00<#10554#><#10555#> <#10555#><#10556#>empty)<#10556#><#62248#>, the inventory contains only one toy, and the cost of the toy is the cost of the inventory. Hence, the result is <#62249#><#10557#>1.00<#10557#><#62249#>. Finally, for <#62250#><#10558#>(cons<#10558#>\ <#10559#>17.05<#10559#>\ <#10560#>(cons<#10560#>\ <#10561#>1.22<#10561#>\ <#10562#>(cons<#10562#>\ <#10563#>2.59<#10563#>\ <#10564#>empty)))<#10564#><#62250#>, <#62251#><#10565#>sum<#10565#><#62251#> should yield
For the design of <#62252#><#10566#>sum<#10566#><#62252#>'s template, we follow the design recipe,
step by step. First, we add the <#62253#><#10567#>cond<#10567#>-expression<#62253#>:
<#10871#>Refinement<#10871#>:\ First develop a function that works on non-empty lists.
Then produce a checked function (see section~#secinputerrors#10872><#10572#>(d<#10572#><#10573#>efine<#10573#> <#10574#>(sum<#10574#> <#10575#>a-list-of-nums)<#10575#>
<#10576#>(c<#10576#><#10577#>ond<#10577#>
<#10578#>[<#10578#><#10579#>(empty?<#10579#> <#10580#>a-list-of-nums)<#10580#> <#10581#>...]<#10581#>
<#10582#>[<#10582#><#10583#>(cons?<#10583#> <#10584#>a-list-of-nums)<#10584#> <#10585#>...]<#10585#><#10586#>))<#10586#>
The second clause indicates with a comment that it deals with
<#62254#><#10590#>cons<#10590#><#62254#>tructed lists. Second, we add the appropriate selector
expressions for each clause:
<#10595#>(d<#10595#><#10596#>efine<#10596#> <#10597#>(sum<#10597#> <#10598#>a-list-of-nums)<#10598#>
<#10599#>(c<#10599#><#10600#>ond<#10600#>
<#10601#>[<#10601#><#10602#>(empty?<#10602#> <#10603#>a-list-of-nums)<#10603#> <#10604#>...]<#10604#>
<#10605#>[<#10605#><#10606#>(cons?<#10606#> <#10607#>a-list-of-nums)<#10607#>
<#10608#>...<#10608#> <#10609#>(first<#10609#> <#10610#>a-list-of-nums)<#10610#> <#10611#>...<#10611#> <#10612#>(rest<#10612#> <#10613#>a-list-of-nums)<#10613#> <#10614#>...]<#10614#><#10615#>))<#10615#>
Finally, we add the natural recursion of <#62255#><#10619#>sum<#10619#><#62255#> that reflects the
self-reference in the data definition:
<#10624#>(d<#10624#><#10625#>efine<#10625#> <#10626#>(sum<#10626#> <#10627#>a-list-of-nums)<#10627#>
<#10628#>(c<#10628#><#10629#>ond<#10629#>
<#10630#>[<#10630#><#10631#>(empty?<#10631#> <#10632#>a-list-of-nums)<#10632#> <#10633#>...]<#10633#>
<#10634#>[<#10634#><#10635#>else<#10635#> <#10636#>...<#10636#> <#10637#>(first<#10637#> <#10638#>a-list-of-nums)<#10638#> <#10639#>...<#10639#> <#10640#>(sum<#10640#> <#10641#>(rest<#10641#> <#10642#>a-list-of-nums))<#10642#> <#10643#>...]<#10643#><#10644#>))<#10644#>
The final template reflects almost every aspect of the data definition: the
two clauses, the <#62256#><#10648#>cons<#10648#><#62256#>truction in the second clauses, and the
self-reference of the second clauses. The only part of the data definition
that the function template does not reflect is that the first item of a
<#62257#><#10649#>cons<#10649#><#62257#>ed input is a number.
Now that we have a template, let us define the answers for the
<#62258#><#10650#>cond<#10650#>-expression<#62258#> on on a clause-by-clause basis. In the first
clause, the input is <#62259#><#10651#>empty<#10651#><#62259#>, which means that the store has no
inventory. We already agreed that in this case the inventory is worth
nothing, which means the corresponding answer is <#62260#><#10652#>0<#10652#><#62260#>. In the second
clause of the template, we find two expressions:
From these two reminders of what the expressions already compute for us,
we see that the expression
<#10667#>(+<#10667#> <#10668#>(first<#10668#> <#10669#>a-list-of-nums)<#10669#> <#10670#>(sum<#10670#> <#10671#>(rest<#10671#> <#10672#>a-list-of-nums)))<#10672#>
computes the answer in the second <#62265#><#10676#>cond<#10676#><#62265#>-clause.
Here is the complete definition of <#62266#><#10677#>sum<#10677#><#62266#>:
<#10682#>(d<#10682#><#10683#>efine<#10683#> <#10684#>(sum<#10684#> <#10685#>a-list-of-nums)<#10685#>
<#10686#>(c<#10686#><#10687#>ond<#10687#>
<#10688#>[<#10688#><#10689#>(empty?<#10689#> <#10690#>a-list-of-nums)<#10690#> <#10691#>0]<#10691#>
<#10692#>[<#10692#><#10693#>else<#10693#> <#10694#>(+<#10694#> <#10695#>(first<#10695#> <#10696#>a-list-of-nums)<#10696#> <#10697#>(sum<#10697#> <#10698#>(rest<#10698#> <#10699#>a-list-of-nums)))]<#10699#><#10700#>))<#10700#>
A comparison of this definition with the template and the data definition
shows that the step from the data definition to the template is the major
step in the function development process. Once we have derived the template
from a solid understanding of the set of possible inputs, we can focus on
the creative part: combining values. For simple examples, this step is
easy; for others, it requires rigorous thinking.
We will see in future sections that this relationship between the shape of
the data definition and the function is not a coincidence. Defining the
class of data that a function consumes always determines to a large extent
the shape of the function.
<#10706#>Exercise 9.5.1<#10706#>
<#10713#>empty<#10713#>
<#10714#>(cons<#10714#> <#10715#>1.00<#10715#> <#10716#>empty)<#10716#>
<#10717#>(cons<#10717#> <#10718#>17.05<#10718#> <#10719#>(cons<#10719#> <#10720#>1.22<#10720#> <#10721#>(cons<#10721#> <#10722#>2.59<#10722#> <#10723#>empty)))<#10723#>
Compare the results with our specifications. Then apply <#62268#><#10727#>sum<#10727#><#62268#> to the
following examples:
<#10732#>empty<#10732#>
<#10733#>(cons<#10733#> <#10734#>2.59<#10734#> <#10735#>empty)<#10735#>
<#10736#>(cons<#10736#> <#10737#>1.22<#10737#> <#10738#>(cons<#10738#> <#10739#>2.59<#10739#> <#10740#>empty))<#10740#>
First determine what the result <#10744#>should<#10744#> be; then use DrScheme to
evaluate the expressions.
Solution<#62269#><#62269#>
<#10750#>Exercise 9.5.2<#10750#>
<#10770#>(dollar-store?<#10770#> <#10771#>empty)<#10771#>
<#10772#>=<#10772#> <#10773#>true<#10773#>
<#10781#>(dollar-store?<#10781#> <#10782#>(cons<#10782#> <#10783#>.75<#10783#> <#10784#>(cons<#10784#> <#10785#>1.95<#10785#> <#10786#>(cons<#10786#> <#10787#>.25<#10787#> <#10788#>empty))))<#10788#>
<#10789#>=<#10789#> <#10790#>false<#10790#>
<#10798#>(dollar-store?<#10798#> <#10799#>(cons<#10799#> <#10800#>.75<#10800#> <#10801#>(cons<#10801#> <#10802#>0.95<#10802#> <#10803#>(cons<#10803#> <#10804#>.25<#10804#> <#10805#>empty))))<#10805#>
<#10806#>=<#10806#> <#10807#>true<#10807#>
Generalize the function so that it consumes a list of prices (numbers) and
a threshold price (number) and checks that all prices in the list are below
the threshold. Solution<#62277#><#62277#>
<#10816#>Exercise 9.5.4<#10816#>
<#10846#>(repl-for-list<#10846#> <#10847#>5<#10847#> <#10848#>check-guess-for-list)<#10848#>
<#10852#>after<#10852#> the functions have been thoroughly developed.~ Solution<#62290#><#62290#>
<#10858#>Exercise 9.5.6<#10858#>