The use of our design recipes entirely determines a function's template---or
basic organization---from the data definition for the input. Indeed, the
template is an alternative method of expressing what we know about the input
data. Not surprisingly, functions that consume the same kind of data look
alike.
<#71222#>;; <#64893#><#25459#>contains-doll?<#25459#> <#25460#>:<#25460#> <#25461#>los<#25461#> <#25462#><#25462#><#25463#>-;SPMgt;<#25463#><#25464#><#25464#> <#25465#>boolean<#25465#><#64893#><#71222#>
<#71223#>;; to determine whether <#64894#><#25466#>alos<#25466#><#64894#> contains <#71223#>
<#71224#>;; the symbol <#64895#><#25467#>'<#25467#><#25468#>doll<#25468#><#64895#><#71224#>
<#25469#>(d<#25469#><#25470#>efine<#25470#> <#25471#>(contains-doll?<#25471#> <#25472#>alos)<#25472#>
<#25473#>(c<#25473#><#25474#>ond<#25474#>
<#25475#>[<#25475#><#25476#>(empty?<#25476#> <#25477#>alos)<#25477#> <#25478#>false<#25478#><#25479#>]<#25479#>
<#25480#>[<#25480#><#25481#>e<#25481#><#25482#>lse<#25482#>
<#25483#>(c<#25483#><#25484#>ond<#25484#>
<#25485#>[<#25485#><#25486#>(symbol=?<#25486#> <#25487#>(first<#25487#> <#25488#>alos)<#25488#> #tex2html_wrap73194#<#25490#>)<#25490#>
<#25491#>true<#25491#><#25492#>]<#25492#>
<#25493#>[<#25493#><#25494#>else<#25494#>
<#25495#>(contains-doll?<#25495#> <#25496#>(rest<#25496#> <#25497#>alos))]<#25497#><#25498#>)]<#25498#><#25499#>))<#25499#>
<#71225#>;; <#64897#><#25505#>contains-car?<#25505#> <#25506#>:<#25506#> <#25507#>los<#25507#> <#25508#><#25508#><#25509#>-;SPMgt;<#25509#><#25510#><#25510#> <#25511#>boolean<#25511#><#64897#><#71225#>
<#71226#>;; to determine whether <#64898#><#25512#>alos<#25512#><#64898#> contains <#71226#>
<#71227#>;; the symbol <#64899#><#25513#>'<#25513#><#25514#>car<#25514#><#64899#><#71227#>
<#25515#>(d<#25515#><#25516#>efine<#25516#> <#25517#>(contains-car?<#25517#> <#25518#>alos)<#25518#>
<#25519#>(c<#25519#><#25520#>ond<#25520#>
<#25521#>[<#25521#><#25522#>(empty?<#25522#> <#25523#>alos)<#25523#> <#25524#>false<#25524#><#25525#>]<#25525#>
<#25526#>[<#25526#><#25527#>e<#25527#><#25528#>lse<#25528#>
<#25529#>(c<#25529#><#25530#>ond<#25530#>
<#25531#>[<#25531#><#25532#>(symbol=?<#25532#> <#25533#>(first<#25533#> <#25534#>alos)<#25534#> #tex2html_wrap73196#<#25536#>)<#25536#>
<#25537#>true<#25537#><#25538#>]<#25538#>
<#25539#>[<#25539#><#25540#>else<#25540#>
<#25541#>(contains-car?<#25541#> <#25542#>(rest<#25542#> <#25543#>alos))]<#25543#><#25544#>)]<#25544#><#25545#>))<#25545#>
<#25549#>Figure: Two similar functions<#25549#>
Take a look at the two functions in figure~#figcmpdollcar#25551>, which
consume lists of symbols (names of toys) and look for specific toys. The
function on the left looks for <#64901#><#25552#>'<#25552#><#25553#>doll<#25553#><#64901#>, the one on the right for
<#64902#><#25554#>'<#25554#><#25555#>car<#25555#><#64902#> in a list of symbols (los). The two functions are nearly
indistinguishable. Each consumes lists of symbols; each function body
consists of a <#64903#><#25556#>cond<#25556#>-expression<#64903#>s with two clauses. Each produces
<#64904#><#25557#>false<#25557#><#64904#> if the input is <#64905#><#25558#>empty<#25558#><#64905#>; each uses a second, nested
<#64906#><#25559#>cond<#25559#>-expression<#64906#> to determine whether the first item is the desired
item. The only difference is the symbol that is used in the comparison of
the nested <#64907#><#25560#>cond<#25560#>-expression<#64907#>: <#64908#><#25561#>contains-doll?<#25561#><#64908#> uses
<#64909#><#25562#>'<#25562#><#25563#>doll<#25563#><#64909#> and <#64910#><#25564#>contains-car?<#25564#><#64910#> uses <#64911#><#25565#>'<#25565#><#25566#>car<#25566#><#64911#>, of course. To
highlight the differences, the two symbols are boxed.
Good programmers are too lazy to define several closely related
functions. Instead they define a single function that can look for both a
<#64912#><#25567#>'<#25567#><#25568#>doll<#25568#><#64912#> and a <#64913#><#25569#>'<#25569#><#25570#>car<#25570#><#64913#> in a list of toys. This more general
function consumes an additional piece of data, the symbol that we are
looking for, but is otherwise like the two original functions:
<#71228#>;; <#64914#><#25575#>contains?<#25575#> <#25576#>:<#25576#> <#25577#>symbol<#25577#> <#25578#>los<#25578#> <#25579#><#25579#><#25580#>-;SPMgt;<#25580#><#25581#><#25581#> <#25582#>boolean<#25582#><#64914#><#71228#>
<#71229#>;; to determine whether <#64915#><#25583#>alos<#25583#><#64915#> contains the symbol <#64916#><#25584#>s<#25584#><#64916#><#71229#>
<#25585#>(d<#25585#><#25586#>efine<#25586#> <#25587#>(contains?<#25587#> <#25588#>s<#25588#> <#25589#>alos)<#25589#>
<#25590#>(c<#25590#><#25591#>ond<#25591#>
<#25592#>[<#25592#><#25593#>(empty?<#25593#> <#25594#>alos)<#25594#> <#25595#>false<#25595#><#25596#>]<#25596#>
<#25597#>[<#25597#><#25598#>else<#25598#> <#25599#>(c<#25599#><#25600#>ond<#25600#>
<#25601#>[<#25601#><#25602#>(symbol=?<#25602#> <#25603#>(first<#25603#> <#25604#>alos)<#25604#> #tex2html_wrap73198#<#25606#>)<#25606#>
<#25607#>true<#25607#><#25608#>]<#25608#>
<#25609#>[<#25609#><#25610#>else<#25610#>
<#25611#>(contains?<#25611#> <#25612#>s<#25612#> <#25613#>(rest<#25613#> <#25614#>alos))]<#25614#><#25615#>)]<#25615#><#25616#>))<#25616#>
We can now look for <#64918#><#25620#>'<#25620#><#25621#>doll<#25621#><#64918#> by applying <#64919#><#25622#>contains?<#25622#><#64919#> to
<#64920#><#25623#>'<#25623#><#25624#>doll<#25624#><#64920#> and a list of symbols. But <#64921#><#25625#>contains?<#25625#><#64921#> works for any
other symbol, too. Defining the single version has solved many related
problems at once.
The process of combining two related functions into a single definition is
called <#64922#><#25626#>FUNCTIONAL ABSTRACTION<#25626#><#64922#>. Defining abstract versions of
functions is highly beneficial. The first benefit is that a single function
can perform many different tasks. In our first example, <#64923#><#25627#>contains?<#25627#><#64923#>
can search for many different symbols instead of just one concrete
symbol.
<#71230#>;; <#64924#><#25633#>below<#25633#> <#25634#>:<#25634#> <#25635#>lon<#25635#> <#25636#>number<#25636#> <#25637#><#25637#><#25638#>-;SPMgt;<#25638#><#25639#><#25639#> <#25640#>lon<#25640#><#64924#><#71230#>
<#25641#>;; to construct a list of those numbers <#25641#>
<#71231#>;; on <#64925#><#25642#>alon<#25642#><#64925#> that are below <#64926#><#25643#>t<#25643#><#64926#><#71231#>
<#25644#>(d<#25644#><#25645#>efine<#25645#> <#25646#>(below<#25646#> <#25647#>alon<#25647#> <#25648#>t)<#25648#>
<#25649#>(c<#25649#><#25650#>ond<#25650#>
<#25651#>[<#25651#><#25652#>(empty?<#25652#> <#25653#>alon)<#25653#> <#25654#>empty]<#25654#>
<#25655#>[<#25655#><#25656#>e<#25656#><#25657#>lse<#25657#>
<#25658#>(c<#25658#><#25659#>ond<#25659#>
<#25660#>[<#25660#><#25661#>(<#25661#>#tex2html_wrap73200# <#25663#>(first<#25663#> <#25664#>alon)<#25664#> <#25665#>t)<#25665#>
<#25666#>(c<#25666#><#25667#>ons<#25667#> <#25668#>(first<#25668#> <#25669#>alon)<#25669#>
<#25670#>(below<#25670#> <#25671#>(rest<#25671#> <#25672#>alon)<#25672#> <#25673#>t))]<#25673#>
<#25674#>[<#25674#><#25675#>else<#25675#>
<#25676#>(below<#25676#> <#25677#>(rest<#25677#> <#25678#>alon)<#25678#> <#25679#>t)]<#25679#><#25680#>)]<#25680#><#25681#>))<#25681#>
<#71232#>;; <#64927#><#25687#>above<#25687#> <#25688#>:<#25688#> <#25689#>lon<#25689#> <#25690#>number<#25690#> <#25691#><#25691#><#25692#>-;SPMgt;<#25692#><#25693#><#25693#> <#25694#>lon<#25694#><#64927#><#71232#>
<#25695#>;; to construct a list of those numbers <#25695#>
<#71233#>;; on <#64928#><#25696#>alon<#25696#><#64928#> that are above <#64929#><#25697#>t<#25697#><#64929#><#71233#>
<#25698#>(d<#25698#><#25699#>efine<#25699#> <#25700#>(above<#25700#> <#25701#>alon<#25701#> <#25702#>t)<#25702#>
<#25703#>(c<#25703#><#25704#>ond<#25704#>
<#25705#>[<#25705#><#25706#>(empty?<#25706#> <#25707#>alon)<#25707#> <#25708#>empty]<#25708#>
<#25709#>[<#25709#><#25710#>e<#25710#><#25711#>lse<#25711#>
<#25712#>(c<#25712#><#25713#>ond<#25713#>
<#25714#>[<#25714#><#25715#>(<#25715#>#tex2html_wrap73202# <#25717#>(first<#25717#> <#25718#>alon)<#25718#> <#25719#>t)<#25719#>
<#25720#>(c<#25720#><#25721#>ons<#25721#> <#25722#>(first<#25722#> <#25723#>alon)<#25723#>
<#25724#>(above<#25724#> <#25725#>(rest<#25725#> <#25726#>alon)<#25726#> <#25727#>t))]<#25727#>
<#25728#>[<#25728#><#25729#>else<#25729#>
<#25730#>(above<#25730#> <#25731#>(rest<#25731#> <#25732#>alon)<#25732#> <#25733#>t)]<#25733#><#25734#>)]<#25734#><#25735#>))<#25735#>
<#25739#>Figure: Two similar functions<#25739#>
In the case of <#64930#><#25741#>contains-doll?<#25741#><#64930#> and <#64931#><#25742#>contains-car?<#25742#><#64931#>,
abstraction is uninteresting. There are, however, other, more interesting
cases: see figure~#figcmpabovebelow#25743>. The function on the left
consumes a list of numbers and a threshold and produces a list of all those
numbers that are below the threshold; the one on the right produces all
those that are above a threshold.
The difference between the two functions is the comparison operator. The
left uses ;SPMlt;, the right one ;SPMgt;. Following the first example, we abstract
over the two functions with an additional parameter that stands for the
concrete relational operator in <#64932#><#25744#>below<#25744#><#64932#> and <#64933#><#25745#>above<#25745#><#64933#>:
<#25750#>(d<#25750#><#25751#>efine<#25751#> <#25752#>(filter1<#25752#> <#25753#>rel-op<#25753#> <#25754#>alon<#25754#> <#25755#>t)<#25755#>
<#25756#>(c<#25756#><#25757#>ond<#25757#>
<#25758#>[<#25758#><#25759#>(empty?<#25759#> <#25760#>alon)<#25760#> <#25761#>empty]<#25761#>
<#25762#>[<#25762#><#25763#>else<#25763#> <#25764#>(c<#25764#><#25765#>ond<#25765#>
<#25766#>[<#25766#><#25767#>(<#25767#>#tex2html_wrap73204# <#25769#>(first<#25769#> <#25770#>alon)<#25770#> <#25771#>t)<#25771#>
<#25772#>(c<#25772#><#25773#>ons<#25773#> <#25774#>(first<#25774#> <#25775#>alon)<#25775#>
<#25776#>(filter1<#25776#> <#25777#>rel-op<#25777#> <#25778#>(rest<#25778#> <#25779#>alon)<#25779#> <#25780#>t))]<#25780#>
<#25781#>[<#25781#><#25782#>e<#25782#><#25783#>lse<#25783#>
<#25784#>(filter1<#25784#> <#25785#>rel-op<#25785#> <#25786#>(rest<#25786#> <#25787#>alon)<#25787#> <#25788#>t)]<#25788#><#25789#>)]<#25789#><#25790#>))<#25790#>
To apply this new function, we must supply three arguments: a relational
operator <#64935#><#25794#>R<#25794#><#64935#> that compares two numbers, a list <#64936#><#25795#>L<#25795#><#64936#> of
numbers, and a number <#64937#><#25796#>N<#25796#><#64937#>. The function then extracts all those items
<#64938#><#25797#>i<#25797#><#64938#> in <#64939#><#25798#>L<#25798#><#64939#> for which <#64940#><#25799#>(R<#25799#>\ <#25800#>i<#25800#>\ <#25801#>N)<#25801#><#64940#> evaluates to
true. Since we do not know how to write down contracts for functions like
<#64941#><#25802#>filter1<#25802#><#64941#>, we omit the contract for now. We will discuss the problem
of contracts in section~#secabscontracts#25803> below.
Let us see how <#64942#><#25804#>filter1<#25804#><#64942#> works with an example. Clearly, as long as
the input list is <#64943#><#25805#>empty<#25805#><#64943#>, the result is <#64944#><#25806#>empty<#25806#><#64944#>, too, no
matter what the other arguments are:
<#25811#>(filter1<#25811#> <#25812#>;SPMlt;<#25812#> <#25813#>empty<#25813#> <#25814#>5)<#25814#>
<#25815#>=<#25815#> <#25816#>empty<#25816#>
So next we look at a slightly more complicated case:
<#25824#>(filter1<#25824#> <#25825#>;SPMlt;<#25825#> <#25826#>(cons<#25826#> <#25827#>4<#25827#> <#25828#>empty)<#25828#> <#25829#>5)<#25829#>
The result should be <#64945#><#25833#>(cons<#25833#>\ <#25834#>4<#25834#>\ <#25835#>empty)<#25835#><#64945#> because the only item of this
list is <#64946#><#25836#>4<#25836#><#64946#> and <#64947#><#25837#>(;SPMlt;<#25837#>\ <#25838#>4<#25838#>\ <#25839#>5)<#25839#><#64947#> is true.
The first step of the hand-evaluation is based on the standard rule of
application:
<#25844#>(filter1<#25844#> <#25845#>;SPMlt;<#25845#> <#25846#>(cons<#25846#> <#25847#>4<#25847#> <#25848#>empty)<#25848#> <#25849#>5)<#25849#>
<#25850#>=<#25850#> <#25851#>(c<#25851#><#25852#>ond<#25852#>
<#25853#>[<#25853#><#25854#>(empty?<#25854#> <#25855#>(cons<#25855#> <#25856#>4<#25856#> <#25857#>empty))<#25857#> <#25858#>empty]<#25858#>
<#25859#>[<#25859#><#25860#>else<#25860#> <#25861#>(c<#25861#><#25862#>ond<#25862#>
<#25863#>[<#25863#><#25864#>(;SPMlt;<#25864#> <#25865#>(first<#25865#> <#25866#>(cons<#25866#> <#25867#>4<#25867#> <#25868#>empty))<#25868#> <#25869#>5)<#25869#>
<#25870#>(c<#25870#><#25871#>ons<#25871#> <#25872#>(first<#25872#> <#25873#>(cons<#25873#> <#25874#>4<#25874#> <#25875#>empty))<#25875#>
<#25876#>(filter1<#25876#> <#25877#>;SPMlt;<#25877#> <#25878#>(rest<#25878#> <#25879#>(cons<#25879#> <#25880#>4<#25880#> <#25881#>empty))<#25881#> <#25882#>5))]<#25882#>
<#25883#>[<#25883#><#25884#>e<#25884#><#25885#>lse<#25885#>
<#25886#>(filter1<#25886#> <#25887#>;SPMlt;<#25887#> <#25888#>(rest<#25888#> <#25889#>(cons<#25889#> <#25890#>4<#25890#> <#25891#>empty))<#25891#> <#25892#>5)]<#25892#><#25893#>)]<#25893#><#25894#>)<#25894#>
That is, it is the body of <#64948#><#25898#>filter1<#25898#><#64948#> with all occurrences of
<#64949#><#25899#>rel-op<#25899#><#64949#> replaced by <#64950#><#25900#>;SPMlt;<#25900#><#64950#>, t replaced by <#64951#><#25901#>5<#25901#><#64951#>, and
<#64952#><#25902#>alon<#25902#><#64952#> replaced by <#64953#><#25903#>(cons<#25903#>\ <#25904#>6<#25904#>\ <#25905#>empty)<#25905#><#64953#>.
The rest of the evaluation is straightforward and uses only the basic laws
of Scheme:
<#25910#>(c<#25910#><#25911#>ond<#25911#>
<#25912#>[<#25912#><#25913#>(empty?<#25913#> <#25914#>(cons<#25914#> <#25915#>4<#25915#> <#25916#>empty))<#25916#> <#25917#>empty]<#25917#>
<#25918#>[<#25918#><#25919#>else<#25919#> <#25920#>(c<#25920#><#25921#>ond<#25921#>
<#25922#>[<#25922#><#25923#>(;SPMlt;<#25923#> <#25924#>(first<#25924#> <#25925#>(cons<#25925#> <#25926#>4<#25926#> <#25927#>empty))<#25927#> <#25928#>5)<#25928#>
<#25929#>(c<#25929#><#25930#>ons<#25930#> <#25931#>(first<#25931#> <#25932#>(cons<#25932#> <#25933#>4<#25933#> <#25934#>empty))<#25934#>
<#25935#>(filter1<#25935#> <#25936#>;SPMlt;<#25936#> <#25937#>(rest<#25937#> <#25938#>(cons<#25938#> <#25939#>4<#25939#> <#25940#>empty))<#25940#> <#25941#>5))]<#25941#>
<#25942#>[<#25942#><#25943#>e<#25943#><#25944#>lse<#25944#>
<#25945#>(filter1<#25945#> <#25946#>;SPMlt;<#25946#> <#25947#>(rest<#25947#> <#25948#>(cons<#25948#> <#25949#>4<#25949#> <#25950#>empty))<#25950#> <#25951#>5)]<#25951#><#25952#>)]<#25952#><#25953#>)<#25953#>
<#25961#>=<#25961#> <#25962#>(c<#25962#><#25963#>ond<#25963#>
<#25964#>[<#25964#><#25965#>(;SPMlt;<#25965#> <#25966#>(first<#25966#> <#25967#>(cons<#25967#> <#25968#>4<#25968#> <#25969#>empty))<#25969#> <#25970#>5)<#25970#>
<#25971#>(c<#25971#><#25972#>ons<#25972#> <#25973#>(first<#25973#> <#25974#>(cons<#25974#> <#25975#>4<#25975#> <#25976#>empty))<#25976#>
<#25977#>(filter1<#25977#> <#25978#>;SPMlt;<#25978#> <#25979#>(rest<#25979#> <#25980#>(cons<#25980#> <#25981#>4<#25981#> <#25982#>empty))<#25982#> <#25983#>5))]<#25983#>
<#25984#>[<#25984#><#25985#>e<#25985#><#25986#>lse<#25986#>
<#25987#>(filter1<#25987#> <#25988#>;SPMlt;<#25988#> <#25989#>(rest<#25989#> <#25990#>(cons<#25990#> <#25991#>4<#25991#> <#25992#>empty))<#25992#> <#25993#>5)]<#25993#><#25994#>)<#25994#>
<#26002#>=<#26002#> <#26003#>(c<#26003#><#26004#>ond<#26004#>
<#26005#>[<#26005#><#26006#>(;SPMlt;<#26006#> <#26007#>4<#26007#> <#26008#>5)<#26008#>
<#26009#>(c<#26009#><#26010#>ons<#26010#> <#26011#>(first<#26011#> <#26012#>(cons<#26012#> <#26013#>4<#26013#> <#26014#>empty))<#26014#>
<#26015#>(filter1<#26015#> <#26016#>;SPMlt;<#26016#> <#26017#>(rest<#26017#> <#26018#>(cons<#26018#> <#26019#>4<#26019#> <#26020#>empty))<#26020#> <#26021#>5))]<#26021#>
<#26022#>[<#26022#><#26023#>e<#26023#><#26024#>lse<#26024#>
<#26025#>(filter1<#26025#> <#26026#>;SPMlt;<#26026#> <#26027#>(rest<#26027#> <#26028#>(cons<#26028#> <#26029#>4<#26029#> <#26030#>empty))<#26030#> <#26031#>5)]<#26031#><#26032#>)<#26032#>
<#26040#>=<#26040#> <#26041#>(c<#26041#><#26042#>ond<#26042#>
<#26043#>[<#26043#><#26044#>true<#26044#>
<#26045#>(c<#26045#><#26046#>ons<#26046#> <#26047#>(first<#26047#> <#26048#>(cons<#26048#> <#26049#>4<#26049#> <#26050#>empty))<#26050#>
<#26051#>(filter1<#26051#> <#26052#>;SPMlt;<#26052#> <#26053#>(rest<#26053#> <#26054#>(cons<#26054#> <#26055#>4<#26055#> <#26056#>empty))<#26056#> <#26057#>5))]<#26057#>
<#26058#>[<#26058#><#26059#>e<#26059#><#26060#>lse<#26060#>
<#26061#>(filter1<#26061#> <#26062#>;SPMlt;<#26062#> <#26063#>(rest<#26063#> <#26064#>(cons<#26064#> <#26065#>4<#26065#> <#26066#>empty))<#26066#> <#26067#>5)]<#26067#><#26068#>)<#26068#>
<#26076#>=<#26076#> <#26077#>(cons<#26077#> <#26078#>4<#26078#> <#26079#>(filter1<#26079#> <#26080#>;SPMlt;<#26080#> <#26081#>(rest<#26081#> <#26082#>(cons<#26082#> <#26083#>4<#26083#> <#26084#>empty))<#26084#> <#26085#>5))<#26085#>
<#26086#>=<#26086#> <#26087#>(cons<#26087#> <#26088#>4<#26088#> <#26089#>(filter1<#26089#> <#26090#>;SPMlt;<#26090#> <#26091#>empty<#26091#> <#26092#>5))<#26092#>
<#26093#>=<#26093#> <#26094#>(cons<#26094#> <#26095#>4<#26095#> <#26096#>empty)<#26096#>
The last step is the equation we discussed as our first case.
Our final example is an application of <#64954#><#26100#>filter1<#26100#><#64954#> to a list of two
items:
<#26105#>(filter1<#26105#> <#26106#>;SPMlt;<#26106#> <#26107#>(cons<#26107#> <#26108#>6<#26108#> <#26109#>(cons<#26109#> <#26110#>4<#26110#> <#26111#>empty))<#26111#> <#26112#>5)<#26112#>
<#26113#>=<#26113#> <#26114#>(filter1<#26114#> <#26115#>;SPMlt;<#26115#> <#26116#>(cons<#26116#> <#26117#>4<#26117#> <#26118#>empty)<#26118#> <#26119#>5)<#26119#>
<#26120#>=<#26120#> <#26121#>(cons<#26121#> <#26122#>4<#26122#> <#26123#>(filter1<#26123#> <#26124#>;SPMlt;<#26124#> <#26125#>empty<#26125#> <#26126#>5))<#26126#>
<#26127#>=<#26127#> <#26128#>(cons<#26128#> <#26129#>4<#26129#> <#26130#>empty)<#26130#>
The only new step is the first one. It says that <#64955#><#26134#>filter1<#26134#><#64955#>
determines that the first item on the list is not less than the threshold,
and that it therefore is not <#64956#><#26135#>cons<#26135#><#64956#>ed onto the result of the natural
recursion.
<#26138#>Exercise 19.1.1<#26138#>
Verify the equation
<#26144#>(filter1<#26144#> <#26145#>;SPMlt;<#26145#> <#26146#>(cons<#26146#> <#26147#>6<#26147#> <#26148#>(cons<#26148#> <#26149#>4<#26149#> <#26150#>empty))<#26150#> <#26151#>5)<#26151#>
<#26152#>=<#26152#> <#26153#>(filter1<#26153#> <#26154#>;SPMlt;<#26154#> <#26155#>(cons<#26155#> <#26156#>4<#26156#> <#26157#>empty)<#26157#> <#26158#>5)<#26158#>
with a hand-evaluation that shows every step. Solution<#64957#><#64957#>
<#26167#>Exercise 19.1.2<#26167#>
Evaluate the expression
<#26173#>(filter1<#26173#> <#26174#>;SPMgt;<#26174#> <#26175#>(cons<#26175#> <#26176#>8<#26176#> <#26177#>(cons<#26177#> <#26178#>6<#26178#> <#26179#>(cons<#26179#> <#26180#>4<#26180#> <#26181#>empty)))<#26181#> <#26182#>5)<#26182#>
by hand. Show only the essential steps.~ Solution<#64958#><#64958#>
The calculations show that <#64959#><#26193#>(filter1<#26193#>\ <#26194#>;SPMlt;<#26194#>\ <#26195#>alon<#26195#>\ <#26196#>t)<#26196#><#64959#> computes the same
result as <#64960#><#26197#>(below<#26197#>\ <#26198#>alon<#26198#>\ <#26199#>t)<#26199#><#64960#>, which is what we expected. Similar
reasoning shows that <#64961#><#26200#>(filter1<#26200#>\ <#26201#>;SPMgt;<#26201#>\ <#26202#>alon<#26202#>\ <#26203#>t)<#26203#><#64961#> produces the same output
as <#64962#><#26204#>(above<#26204#>\ <#26205#>alon<#26205#>\ <#26206#>t)<#26206#><#64962#>. So suppose we define the following:
<#71234#>;; <#64963#><#26211#>below1<#26211#> <#26212#>:<#26212#> <#26213#>lon<#26213#> <#26214#>number<#26214#> <#26215#><#26215#><#26216#>-;SPMgt;<#26216#><#26217#><#26217#> <#26218#>lon<#26218#><#64963#><#71234#>
<#26219#>(d<#26219#><#26220#>efine<#26220#> <#26221#>(below1<#26221#> <#26222#>alon<#26222#> <#26223#>t)<#26223#>
<#26224#>(filter1<#26224#> <#26225#>;SPMlt;<#26225#> <#26226#>alon<#26226#> <#26227#>t))<#26227#>
<#71235#>;; <#64964#><#26233#>above1<#26233#> <#26234#>:<#26234#> <#26235#>lon<#26235#> <#26236#>number<#26236#> <#26237#><#26237#><#26238#>-;SPMgt;<#26238#><#26239#><#26239#> <#26240#>lon<#26240#><#64964#><#71235#>
<#26241#>(d<#26241#><#26242#>efine<#26242#> <#26243#>(above1<#26243#> <#26244#>alon<#26244#> <#26245#>t)<#26245#>
<#26246#>(filter1<#26246#> <#26247#>;SPMgt;<#26247#> <#26248#>alon<#26248#> <#26249#>t))<#26249#>
Clearly, <#64965#><#26253#>below1<#26253#><#64965#> produces the same results as <#64966#><#26254#>below<#26254#><#64966#> when
given the same inputs, and <#64967#><#26255#>above1<#26255#><#64967#> is related to <#64968#><#26256#>above<#26256#><#64968#> in
the same manner. In short, we have defined <#64969#><#26257#>below<#26257#><#64969#> and
<#64970#><#26258#>above<#26258#><#64970#> as one-liners using <#64971#><#26259#>filter1<#26259#><#64971#>.
Better yet: once we have an <#26260#>abstract<#26260#> function like <#64972#><#26261#>filter1<#26261#><#64972#>, we
can put it to other uses, too. Here are three of them:
- <#64973#><#26263#>(filter1<#26263#>\ <#26264#>=<#26264#>\ <#26265#>alon<#26265#>\ <#26266#>t)<#26266#><#64973#>: This expression extracts all those
numbers in <#64974#><#26267#>alon<#26267#><#64974#> that are equal to <#64975#><#26268#>t<#26268#><#64975#>.
- <#64976#><#26269#>(filter1<#26269#>\ <#26270#>;SPMlt;=<#26270#>\ <#26271#>alon<#26271#>\ <#26272#>t)<#26272#><#64976#>: This one produces the list of numbers
in <#64977#><#26273#>alon<#26273#><#64977#> that are less or equal to <#64978#><#26274#>t<#26274#><#64978#>.
- <#64979#><#26275#>(filter1<#26275#>\ <#26276#>;SPMgt;=<#26276#>\ <#26277#>alon<#26277#>\ <#26278#>t)<#26278#><#64979#>: This last expression computes the list
of numbers that are greater or equal to the threshold.
In general, <#64980#><#26280#>filter1<#26280#><#64980#>'s first argument need not even be one of
Scheme's predefined operations; it can be any function that consumes two
numbers and produces a Boolean value. Consider the following example:
<#71236#>;; <#64981#><#26285#>squared;SPMgt;?<#26285#> <#26286#>:<#26286#> <#26287#>number<#26287#> <#26288#>number<#26288#> <#26289#><#26289#><#26290#>-;SPMgt;<#26290#><#26291#><#26291#> <#26292#>boolean<#26292#><#64981#><#71236#>
<#26293#>(d<#26293#><#26294#>efine<#26294#> <#26295#>(squared;SPMgt;?<#26295#> <#26296#>x<#26296#> <#26297#>c)<#26297#>
<#26298#>(;SPMgt;<#26298#> <#26299#>(*<#26299#> <#26300#>x<#26300#> <#26301#>x)<#26301#> <#26302#>c))<#26302#>
The function produces <#64982#><#26306#>true<#26306#><#64982#> whenever the area of a square with side
<#64983#><#26307#>x<#26307#><#64983#> is larger than some threshold <#64984#><#26308#>c<#26308#><#64984#>, that is, the function
tests whether the claim #tex2html_wrap_inline73190# holds. We now apply <#64985#><#26309#>filter1<#26309#><#64985#> to
this function and a list of numbers:
<#26314#>(filter1<#26314#> <#26315#>squared;SPMgt;?<#26315#> <#26316#>(list<#26316#> <#26317#>1<#26317#> <#26318#>2<#26318#> <#26319#>3<#26319#> <#26320#>4<#26320#> <#26321#>5)<#26321#> <#26322#>10)<#26322#>
This particular application extracts those numbers in <#64986#><#26326#>(list<#26326#>\ <#26327#>1<#26327#>\ <#26328#>2<#26328#>\ <#26329#>3<#26329#>\ <#26330#>4<#26330#><#26331#> <#26331#><#26332#>5)<#26332#><#64986#> whose square is larger than <#64987#><#26333#>10<#26333#><#64987#>.
Here is the beginning of a simple hand-evaluation:
<#26338#>(filter1<#26338#> <#26339#>squared;SPMgt;?<#26339#> <#26340#>(list<#26340#> <#26341#>1<#26341#> <#26342#>2<#26342#> <#26343#>3<#26343#> <#26344#>4<#26344#> <#26345#>5)<#26345#> <#26346#>10)<#26346#>
<#26347#>=<#26347#> <#26348#>(c<#26348#><#26349#>ond<#26349#>
<#26350#>[<#26350#><#26351#>(empty?<#26351#> <#26352#>(list<#26352#> <#26353#>1<#26353#> <#26354#>2<#26354#> <#26355#>3<#26355#> <#26356#>4<#26356#> <#26357#>5))<#26357#> <#26358#>empty]<#26358#>
<#26359#>[<#26359#><#26360#>else<#26360#> <#26361#>(c<#26361#><#26362#>ond<#26362#>
<#26363#>[<#26363#><#26364#>(squared;SPMgt;?<#26364#> <#26365#>(first<#26365#> <#26366#>(list<#26366#> <#26367#>1<#26367#> <#26368#>2<#26368#> <#26369#>3<#26369#> <#26370#>4<#26370#> <#26371#>5))<#26371#> <#26372#>10)<#26372#>
<#26373#>(c<#26373#><#26374#>ons<#26374#> <#26375#>(first<#26375#> <#26376#>(list<#26376#> <#26377#>1<#26377#> <#26378#>2<#26378#> <#26379#>3<#26379#> <#26380#>4<#26380#> <#26381#>5))<#26381#>
<#26382#>(filter1<#26382#> <#26383#>squared;SPMgt;?<#26383#> <#26384#>(rest<#26384#> <#26385#>(list<#26385#> <#26386#>1<#26386#> <#26387#>2<#26387#> <#26388#>3<#26388#> <#26389#>4<#26389#> <#26390#>5))<#26390#> <#26391#>10))]<#26391#>
<#26392#>[<#26392#><#26393#>e<#26393#><#26394#>lse<#26394#>
<#26395#>(filter1<#26395#> <#26396#>squared;SPMgt;?<#26396#> <#26397#>(rest<#26397#> <#26398#>(list<#26398#> <#26399#>1<#26399#> <#26400#>2<#26400#> <#26401#>3<#26401#> <#26402#>4<#26402#> <#26403#>5))<#26403#> <#26404#>10)]<#26404#><#26405#>)]<#26405#><#26406#>)<#26406#>
That is, we apply our standard law of application and calculate otherwise
as usual:
<#26414#>=<#26414#> <#26415#>(c<#26415#><#26416#>ond<#26416#>
<#26417#>[<#26417#><#26418#>(squared;SPMgt;?<#26418#> <#26419#>1<#26419#> <#26420#>10)<#26420#>
<#26421#>(c<#26421#><#26422#>ons<#26422#> <#26423#>(first<#26423#> <#26424#>(list<#26424#> <#26425#>1<#26425#> <#26426#>2<#26426#> <#26427#>3<#26427#> <#26428#>4<#26428#> <#26429#>5))<#26429#>
<#26430#>(filter1<#26430#> <#26431#>squared;SPMgt;?<#26431#> <#26432#>(rest<#26432#> <#26433#>(list<#26433#> <#26434#>1<#26434#> <#26435#>2<#26435#> <#26436#>3<#26436#> <#26437#>4<#26437#> <#26438#>5))<#26438#> <#26439#>10))]<#26439#>
<#26440#>[<#26440#><#26441#>else<#26441#>
<#26442#>(filter1<#26442#> <#26443#>squared;SPMgt;?<#26443#> <#26444#>(rest<#26444#> <#26445#>(list<#26445#> <#26446#>1<#26446#> <#26447#>2<#26447#> <#26448#>3<#26448#> <#26449#>4<#26449#> <#26450#>5))<#26450#> <#26451#>10)]<#26451#><#26452#>)<#26452#>
<#26460#>=<#26460#> <#26461#>(c<#26461#><#26462#>ond<#26462#>
<#26463#>[<#26463#><#26464#>false<#26464#>
<#26465#>(c<#26465#><#26466#>ons<#26466#> <#26467#>(first<#26467#> <#26468#>(list<#26468#> <#26469#>1<#26469#> <#26470#>2<#26470#> <#26471#>3<#26471#> <#26472#>4<#26472#> <#26473#>5))<#26473#>
<#26474#>(filter1<#26474#> <#26475#>squared;SPMgt;?<#26475#> <#26476#>(rest<#26476#> <#26477#>(list<#26477#> <#26478#>1<#26478#> <#26479#>2<#26479#> <#26480#>3<#26480#> <#26481#>4<#26481#> <#26482#>5))<#26482#> <#26483#>10))]<#26483#>
<#26484#>[<#26484#><#26485#>else<#26485#>
<#26486#>(filter1<#26486#> <#26487#>squared;SPMgt;?<#26487#> <#26488#>(rest<#26488#> <#26489#>(list<#26489#> <#26490#>1<#26490#> <#26491#>2<#26491#> <#26492#>3<#26492#> <#26493#>4<#26493#> <#26494#>5))<#26494#> <#26495#>10)]<#26495#><#26496#>)<#26496#>
The last step consists of several steps concerning <#64988#><#26500#>squared;SPMgt;?<#26500#><#64988#>, which
we can skip at this point:
<#26505#>=<#26505#> <#26506#>(filter1<#26506#> <#26507#>squared;SPMgt;?<#26507#> <#26508#>(list<#26508#> <#26509#>2<#26509#> <#26510#>3<#26510#> <#26511#>4<#26511#> <#26512#>5)<#26512#> <#26513#>10)<#26513#>
<#26514#>=<#26514#> <#26515#>(filter1<#26515#> <#26516#>squared;SPMgt;?<#26516#> <#26517#>(list<#26517#> <#26518#>3<#26518#> <#26519#>4<#26519#> <#26520#>5)<#26520#> <#26521#>10)<#26521#>
<#26522#>=<#26522#> <#26523#>(filter1<#26523#> <#26524#>squared;SPMgt;?<#26524#> <#26525#>(list<#26525#> <#26526#>4<#26526#> <#26527#>5)<#26527#> <#26528#>10)<#26528#>
We leave the remainder of the evaluation to the exercises.
<#26534#>Exercise 19.1.3<#26534#>
Show that
<#26540#>(filter1<#26540#> <#26541#>squared;SPMgt;?<#26541#> <#26542#>(list<#26542#> <#26543#>4<#26543#> <#26544#>5)<#26544#> <#26545#>10)<#26545#>
<#26546#>=<#26546#> <#26547#>(cons<#26547#> <#26548#>4<#26548#> <#26549#>(filter1<#26549#> <#26550#>squared;SPMgt;?<#26550#> <#26551#>(list<#26551#> <#26552#>5)<#26552#> <#26553#>10))<#26553#>
with a hand-evaluation. Act as if <#64989#><#26557#>squared;SPMgt;?<#26557#><#64989#> were
primitive. Solution<#64990#><#64990#>
<#26563#>Exercise 19.1.4<#26563#>
The use of <#64991#><#26565#>squared;SPMgt;?<#26565#><#64991#> also suggests that the following
function will work, too:
<#71237#>;; <#64992#><#26570#>squared10?<#26570#> <#26571#>:<#26571#> <#26572#>number<#26572#> <#26573#>number<#26573#> <#26574#><#26574#><#26575#>-;SPMgt;<#26575#><#26576#><#26576#> <#26577#>boolean<#26577#><#64992#><#71237#>
<#26578#>(d<#26578#><#26579#>efine<#26579#> <#26580#>(squared10?<#26580#> <#26581#>x<#26581#> <#26582#>c)<#26582#>
<#26583#>(;SPMgt;<#26583#> <#26584#>(*<#26584#> <#26585#>x<#26585#> <#26586#>x)<#26586#> <#26587#>10))<#26587#>
In other words, the relational function that <#64993#><#26591#>filter1<#26591#><#64993#> uses may
ignore its second argument. After all, we already know it and it stays
the same throughout the evaluation of <#64994#><#26592#>(filter1<#26592#>\ <#26593#>squared;SPMgt;?<#26593#>\ <#26594#>alon<#26594#>\ <#26595#>t)<#26595#><#64994#>.
This, in turn, implies another simplification of the function:
<#26600#>(d<#26600#><#26601#>efine<#26601#> <#26602#>(filter<#26602#> <#26603#>predicate<#26603#> <#26604#>alon)<#26604#>
<#26605#>(c<#26605#><#26606#>ond<#26606#>
<#26607#>[<#26607#><#26608#>(empty?<#26608#> <#26609#>alon)<#26609#> <#26610#>empty]<#26610#>
<#26611#>[<#26611#><#26612#>else<#26612#> <#26613#>(c<#26613#><#26614#>ond<#26614#>
<#26615#>[<#26615#><#26616#>(predicate<#26616#> <#26617#>(first<#26617#> <#26618#>alon))<#26618#>
<#26619#>(c<#26619#><#26620#>ons<#26620#> <#26621#>(first<#26621#> <#26622#>alon)<#26622#>
<#26623#>(filter<#26623#> <#26624#>predicate<#26624#> <#26625#>(rest<#26625#> <#26626#>alon)))]<#26626#>
<#26627#>[<#26627#><#26628#>else<#26628#>
<#26629#>(filter<#26629#> <#26630#>predicate<#26630#> <#26631#>(rest<#26631#> <#26632#>alon))]<#26632#><#26633#>)]<#26633#><#26634#>))<#26634#>
The function <#64995#><#26638#>filter<#26638#><#64995#> consumes only a relational function, called
<#64996#><#26639#>predicate<#26639#><#64996#>, and a list of numbers. Every item <#64997#><#26640#>i<#26640#><#64997#> on the
list is checked with <#64998#><#26641#>predicate<#26641#><#64998#>. If <#64999#><#26642#>(predicate<#26642#>\ <#26643#>i)<#26643#><#64999#> holds,
<#65000#><#26644#>i<#26644#><#65000#> is included in the output; if not, <#65001#><#26645#>i<#26645#><#65001#> does not appear in
the result.
Show how to use <#65002#><#26646#>filter<#26646#><#65002#> to define functions that are equivalent to
<#65003#><#26647#>below<#26647#><#65003#> and <#65004#><#26648#>above<#26648#><#65004#>. Test the definitions.~ Solution<#65005#><#65005#>
So far we have seen that abstracted function definitions are more flexible
and more widely usable than specialized definitions. A second, and in
practice equally important, advantage of abstracted definitions is that we
can change a single definition to fix and improve many different uses.
Consider the two variants of <#65006#><#26656#>filter1<#26656#><#65006#> in
figure~#figfilter1mod#26657>. The first variant flattened the nested
<#65007#><#26658#>cond<#26658#>-expression<#65007#>, something that an experienced programmer may wish
to do. The second variant uses a <#65008#><#26659#>local<#26659#>-expression<#65008#> that makes the
nested <#65009#><#26660#>cond<#26660#>-expression<#65009#> more readable.
<#26665#>(d<#26665#><#26666#>efine<#26666#> <#26667#>(filter1<#26667#> <#26668#>rel-op<#26668#> <#26669#>alon<#26669#> <#26670#>t)<#26670#>
<#26671#>(c<#26671#><#26672#>ond<#26672#>
<#26673#>[<#26673#><#26674#>(empty?<#26674#> <#26675#>alon)<#26675#> <#26676#>empty]<#26676#>
<#26677#>[<#26677#><#26678#>(rel-op<#26678#> <#26679#>(first<#26679#> <#26680#>alon)<#26680#> <#26681#>t)<#26681#>
<#26682#>(c<#26682#><#26683#>ons<#26683#> <#26684#>(first<#26684#> <#26685#>alon)<#26685#>
<#26686#>(filter1<#26686#> <#26687#>rel-op<#26687#> <#26688#>(rest<#26688#> <#26689#>alon)<#26689#> <#26690#>t))]<#26690#>
<#26691#>[<#26691#><#26692#>e<#26692#><#26693#>lse<#26693#>
<#26694#>(filter1<#26694#> <#26695#>rel-op<#26695#> <#26696#>(rest<#26696#> <#26697#>alon)<#26697#> <#26698#>t)]<#26698#><#26699#>))<#26699#>
<#26705#>(d<#26705#><#26706#>efine<#26706#> <#26707#>(filter1<#26707#> <#26708#>rel-op<#26708#> <#26709#>alon<#26709#> <#26710#>t)<#26710#>
<#26711#>(c<#26711#><#26712#>ond<#26712#>
<#26713#>[<#26713#><#26714#>(empty?<#26714#> <#26715#>alon)<#26715#> <#26716#>empty]<#26716#>
<#26717#>[<#26717#><#26718#>e<#26718#><#26719#>lse<#26719#>
<#26720#>(l<#26720#><#26721#>ocal<#26721#> <#26722#>(<#26722#><#26723#>(define<#26723#> <#26724#>first-item<#26724#> <#26725#>(first<#26725#> <#26726#>alon))<#26726#>
<#26727#>(d<#26727#><#26728#>efine<#26728#> <#26729#>rest-filtered<#26729#>
<#26730#>(filter1<#26730#> <#26731#>rel-op<#26731#> <#26732#>(rest<#26732#> <#26733#>alon)<#26733#> <#26734#>t)))<#26734#>
<#26735#>(c<#26735#><#26736#>ond<#26736#>
<#26737#>[<#26737#><#26738#>(rel-op<#26738#> <#26739#>first-item<#26739#> <#26740#>t)<#26740#>
<#26741#>(cons<#26741#> <#26742#>first-item<#26742#> <#26743#>rest-filtered)]<#26743#>
<#26744#>[<#26744#><#26745#>else<#26745#>
<#26746#>rest-filtered]<#26746#><#26747#>))]<#26747#><#26748#>))<#26748#>
<#65010#>Figure: Two modifications of <#26752#>filter1<#26752#><#65010#>
Although both of these changes are trivial, the key is that <#26754#> all<#26754#>
uses of <#65011#><#26755#>filter1<#26755#><#65011#>, including those to define the functions
<#65012#><#26756#>below1<#26756#><#65012#> and <#65013#><#26757#>above1<#26757#><#65013#>, benefit from this change. Similarly,
if the modification had fixed a logical mistake, all uses of the function
would be improved. Finally, it is even possible to add new tasks to
abstracted functions, for example, a mechanism for counting how many
elements are filtered. In that case all uses of the function would benefit
from the new functionality. We will encounter this form of improvement
later.
~<#26759#>These effects of abstraction are crucial for large, industrial programming projects. For that reason, programming language and software engineering research has focused on how to create single points of control in large projects. Of course, the same idea applies to all kinds of computer designs (word documents, spread sheets) and organizations in general.<#26759#>
<#26762#>Exercise 19.1.5<#26762#>
~<#65014#>These functions are designed by strictly following the design recipe and by ignoring the advice on using auxiliary functions. The problem is that they recur <#26765#> twice<#26765#> over the rest of the list, which means they perform up to #tex2html_wrap_inline73192# comparisons if the list contains <#26766#>n<#26766#> items in the wrong order. By improving the abstract function, we automatically get both correct.<#65014#>
Abstract the following two functions into a single function:
<#71238#>;; <#65015#><#26771#>min<#26771#> <#26772#>:<#26772#> <#26773#>nelon<#26773#> <#26774#><#26774#><#26775#>-;SPMgt;<#26775#><#26776#><#26776#> <#26777#>number<#26777#><#65015#><#71238#>
<#26778#>;; to determine the smallest number<#26778#>
<#71239#>;; on <#65016#><#26779#>alon<#26779#><#65016#><#71239#>
<#26780#>(d<#26780#><#26781#>efine<#26781#> <#26782#>(min<#26782#> <#26783#>alon)<#26783#>
<#26784#>(c<#26784#><#26785#>ond<#26785#>
<#26786#>[<#26786#><#26787#>(empty?<#26787#> <#26788#>(rest<#26788#> <#26789#>alon))<#26789#> <#26790#>(first<#26790#> <#26791#>alon)]<#26791#>
<#26792#>[<#26792#><#26793#>else<#26793#> <#26794#>(c<#26794#><#26795#>ond<#26795#>
<#26796#>[<#26796#><#26797#>(;SPMlt;<#26797#> <#26798#>(first<#26798#> <#26799#>alon)<#26799#>
<#26800#>(min<#26800#> <#26801#>(rest<#26801#> <#26802#>alon)))<#26802#>
<#26803#>(first<#26803#> <#26804#>alon)]<#26804#>
<#26805#>[<#26805#><#26806#>else<#26806#>
<#26807#>(min<#26807#> <#26808#>(rest<#26808#> <#26809#>alon))]<#26809#><#26810#>)]<#26810#><#26811#>))<#26811#>
<#71240#>;; <#65017#><#26817#>max<#26817#> <#26818#>:<#26818#> <#26819#>nelon<#26819#> <#26820#><#26820#><#26821#>-;SPMgt;<#26821#><#26822#><#26822#> <#26823#>number<#26823#><#65017#><#71240#>
<#26824#>;; to determine the largest number<#26824#>
<#71241#>;; on <#65018#><#26825#>alon<#26825#><#65018#><#71241#>
<#26826#>(d<#26826#><#26827#>efine<#26827#> <#26828#>(max<#26828#> <#26829#>alon)<#26829#>
<#26830#>(c<#26830#><#26831#>ond<#26831#>
<#26832#>[<#26832#><#26833#>(empty?<#26833#> <#26834#>(rest<#26834#> <#26835#>alon))<#26835#> <#26836#>(first<#26836#> <#26837#>alon)]<#26837#>
<#26838#>[<#26838#><#26839#>else<#26839#> <#26840#>(c<#26840#><#26841#>ond<#26841#>
<#26842#>[<#26842#><#26843#>(;SPMgt;<#26843#> <#26844#>(first<#26844#> <#26845#>alon)<#26845#>
<#26846#>(max<#26846#> <#26847#>(rest<#26847#> <#26848#>alon)))<#26848#>
<#26849#>(first<#26849#> <#26850#>alon)]<#26850#>
<#26851#>[<#26851#><#26852#>else<#26852#>
<#26853#>(max<#26853#> <#26854#>(rest<#26854#> <#26855#>alon))]<#26855#><#26856#>)]<#26856#><#26857#>))<#26857#>
Both consume non-empty lists of numbers and produce a single number. The
left one produces the smallest number in the list, the right one the
largest.
Define <#65019#><#26861#>min1<#26861#><#65019#> and <#65020#><#26862#>max1<#26862#><#65020#> in terms of the abstracted
function. Test each of them with the following two lists:
- <#65021#><#26864#>(list<#26864#>\ <#26865#>3<#26865#>\ <#26866#>7<#26866#>\ <#26867#>6<#26867#>\ <#26868#>2<#26868#>\ <#26869#>9<#26869#>\ <#26870#>8)<#26870#><#65021#>
- <#65022#><#26871#>(list<#26871#>\ <#26872#>20<#26872#>\ <#26873#>19<#26873#>\ <#26874#>18<#26874#>\ <#26875#>17<#26875#>\ <#26876#>16<#26876#>\ <#26877#>15<#26877#>\ <#26878#>14<#26878#>\ <#26879#>13<#26879#>\ <#26880#>12<#26880#>\ <#26881#>11<#26881#>\ <#26882#>10<#26882#>\ <#26883#>9<#26883#>\ <#26884#>8<#26884#>\ <#26885#>7<#26885#>\ <#26886#>6<#26886#>\ <#26887#>5<#26887#>\ <#26888#>4<#26888#>\ <#26889#>3<#26889#>\ <#26890#>2<#26890#>\ <#26891#>1)<#26891#><#65022#>
- <#65023#><#26892#>(list<#26892#>\ <#26893#>1<#26893#>\ <#26894#>2<#26894#>\ <#26895#>3<#26895#>\ <#26896#>4<#26896#>\ <#26897#>5<#26897#>\ <#26898#>6<#26898#>\ <#26899#>7<#26899#>\ <#26900#>8<#26900#>\ <#26901#>9<#26901#>\ <#26902#>10<#26902#>\ <#26903#>11<#26903#>\ <#26904#>12<#26904#>\ <#26905#>13<#26905#>\ <#26906#>14<#26906#>\ <#26907#>15<#26907#>\ <#26908#>16<#26908#>\ <#26909#>17<#26909#>\ <#26910#>18<#26910#>\ <#26911#>19<#26911#>\ <#26912#>20)<#26912#><#65023#>
Why are they slow on the long lists?
Improve the abstracted function. First, introduce a local name for the
result of the natural recursion. Then introduce a local, auxiliary function
that picks the ``interesting'' one of two numbers. Test <#65024#><#26914#>min1<#26914#><#65024#> and
<#65025#><#26915#>max1<#26915#><#65025#> with the same inputs again.~ Solution<#65026#><#65026#>
<#26921#>Exercise 19.1.6<#26921#>
Recall the definition of <#65027#><#26923#>sort<#26923#><#65027#>, which consumes a list of numbers
and produces a sorted version:
<#71242#>;; <#65028#><#26928#>sort<#26928#> <#26929#>:<#26929#> <#26930#>list-of-numbers<#26930#> <#26931#><#26931#><#26932#>-;SPMgt;<#26932#><#26933#><#26933#> <#26934#>list-of-numbers<#26934#><#65028#><#71242#>
<#71243#>;; to construct a list with all items from <#65029#><#26935#>alon<#26935#><#65029#> in descending order<#71243#>
<#26936#>(d<#26936#><#26937#>efine<#26937#> <#26938#>(sort<#26938#> <#26939#>alon)<#26939#>
<#26940#>(l<#26940#><#26941#>ocal<#26941#> <#26942#>(<#26942#><#26943#>(d<#26943#><#26944#>efine<#26944#> <#26945#>(sort<#26945#> <#26946#>alon)<#26946#>
<#26947#>(c<#26947#><#26948#>ond<#26948#>
<#26949#>[<#26949#><#26950#>(empty?<#26950#> <#26951#>alon)<#26951#> <#26952#>empty]<#26952#>
<#26953#>[<#26953#><#26954#>else<#26954#> <#26955#>(insert<#26955#> <#26956#>(first<#26956#> <#26957#>alon)<#26957#> <#26958#>(sort<#26958#> <#26959#>(rest<#26959#> <#26960#>alon)))]<#26960#><#26961#>))<#26961#>
<#26962#>(d<#26962#><#26963#>efine<#26963#> <#26964#>(insert<#26964#> <#26965#>an<#26965#> <#26966#>alon)<#26966#>
<#26967#>(c<#26967#><#26968#>ond<#26968#>
<#26969#>[<#26969#><#26970#>(empty?<#26970#> <#26971#>alon)<#26971#> <#26972#>(list<#26972#> <#26973#>an)]<#26973#>
<#26974#>[<#26974#><#26975#>else<#26975#> <#26976#>(c<#26976#><#26977#>ond<#26977#>
<#26978#>[<#26978#><#26979#>(;SPMgt;<#26979#> <#26980#>an<#26980#> <#26981#>(first<#26981#> <#26982#>alon))<#26982#> <#26983#>(cons<#26983#> <#26984#>an<#26984#> <#26985#>alon)]<#26985#>
<#26986#>[<#26986#><#26987#>else<#26987#> <#26988#>(cons<#26988#> <#26989#>(first<#26989#> <#26990#>alon)<#26990#> <#26991#>(insert<#26991#> <#26992#>an<#26992#> <#26993#>(rest<#26993#> <#26994#>alon)))]<#26994#><#26995#>)]<#26995#><#26996#>)))<#26996#>
<#26997#>(sort<#26997#> <#26998#>alon)))<#26998#>
Define an abstract version of <#65030#><#27002#>sort<#27002#><#65030#> that consumes the comparison
operation in addition to the list of numbers. Use the abstract version to
sort <#65031#><#27003#>(list<#27003#>\ <#27004#>2<#27004#>\ <#27005#>3<#27005#>\ <#27006#>1<#27006#>\ <#27007#>5<#27007#>\ <#27008#>4)<#27008#><#65031#> in ascending and descending
order.~ Solution<#65032#><#65032#>