Consider the following contract, purpose statement, and header:
<#71125#>;; <#64057#><#19344#>replace-eol-with<#19344#> <#19345#>:<#19345#> <#19346#>list-of-numbers<#19346#> <#19347#>list-of-numbers<#19347#> <#19348#><#19348#><#19349#>-;SPMgt;<#19349#><#19350#><#19350#> <#19351#>list-of-numbers<#19351#><#64057#><#71125#>
<#71126#>;; to construct a new list by replacing <#64058#><#19352#>empty<#19352#><#64058#> in alon1 with alon2<#71126#>
<#19353#>(define<#19353#> <#19354#>(replace-eol-with<#19354#> <#19355#>alon1<#19355#> <#19356#>alon2)<#19356#> <#19357#>...)<#19357#>
The contract indicates that the function consumes two lists, something that
we have not seen in the past. Let's see how the design recipe works with
this kind of problem.
To begin with, we need to make up examples. Suppose the first input is
<#64059#><#19361#>empty<#19361#><#64059#>. Then <#64060#><#19362#>replace-eol-with<#19362#><#64060#> should produce the second
argument, no matter what it is:
<#19367#>(replace-eol-with<#19367#> <#19368#>empty<#19368#> <#19369#>L)<#19369#>
<#19370#>=<#19370#> <#19371#>L<#19371#>
In this equation, <#64061#><#19375#>L<#19375#><#64061#> stands for an arbitrary list of numbers, for
example, <#64062#><#19376#>empty<#19376#><#64062#>, <#64063#><#19377#>(cons<#19377#>\ <#19378#>1<#19378#>\ <#19379#>empty)<#19379#><#64063#>, or <#64064#><#19380#>(list<#19380#>\ <#19381#>10<#19381#>\ <#19382#>6<#19382#>\ <#19383#>11<#19383#><#19384#> <#19384#><#19385#>9<#19385#>\ <#19386#>1)<#19386#><#64064#>. Now suppose the first argument is not <#64065#><#19387#>empty<#19387#><#64065#>. Then, as the
name of function and the purpose statement require, we replace the end of the list
with the second argument:
<#19392#>(replace-eol-with<#19392#> <#19393#>(cons<#19393#> <#19394#>1<#19394#> <#19395#>empty)<#19395#> <#19396#>L)<#19396#>
<#19397#>=<#19397#> <#19398#>(cons<#19398#> <#19399#>1<#19399#> <#19400#>L)<#19400#>
<#19408#>(replace-eol-with<#19408#> <#19409#>(cons<#19409#> <#19410#>2<#19410#> <#19411#>(cons<#19411#> <#19412#>1<#19412#> <#19413#>empty))<#19413#> <#19414#>L)<#19414#>
<#19415#>=<#19415#> <#19416#>(cons<#19416#> <#19417#>2<#19417#> <#19418#>(cons<#19418#> <#19419#>1<#19419#> <#19420#>L))<#19420#>
<#19428#>(replace-eol-with<#19428#> <#19429#>(cons<#19429#> <#19430#>2<#19430#> <#19431#>(cons<#19431#> <#19432#>11<#19432#> <#19433#>(cons<#19433#> <#19434#>1<#19434#> <#19435#>empty)))<#19435#> <#19436#>L)<#19436#>
<#19437#>=<#19437#> <#19438#>(cons<#19438#> <#19439#>2<#19439#> <#19440#>(cons<#19440#> <#19441#>11<#19441#> <#19442#>(cons<#19442#> <#19443#>1<#19443#> <#19444#>L)))<#19444#>
Again, <#64066#><#19448#>L<#19448#><#64066#> stands for any list of numbers we can think of in these
examples.
<#71127#>;; <#64067#><#19453#>replace-eol-with<#19453#> <#19454#>:<#19454#> <#19455#>list-of-numbers<#19455#> <#19456#>list-of-numbers<#19456#> <#19457#><#19457#><#19458#>-;SPMgt;<#19458#><#19459#><#19459#> <#19460#>list-of-numbers<#19460#><#64067#><#71127#>
<#71128#>;; to construct a new list by replacing <#64068#><#19461#>empty<#19461#><#64068#> in alon1 with alon2<#71128#>
<#19462#>(d<#19462#><#19463#>efine<#19463#> <#19464#>(replace-eol-with<#19464#> <#19465#>alon1<#19465#> <#19466#>alon2)<#19466#>
<#19467#>(c<#19467#><#19468#>ond<#19468#>
<#19469#>((empty?<#19469#> <#19470#>alon1)<#19470#> <#19471#>alon2)<#19471#>
<#19472#>(else<#19472#> <#19473#>(cons<#19473#> <#19474#>(first<#19474#> <#19475#>alon1)<#19475#> <#19476#>(replace-eol-with<#19476#> <#19477#>(rest<#19477#> <#19478#>alon1)<#19478#> <#19479#>alon2)))))<#19479#>
<#64069#>Figure: The complete definition of <#19483#>replace-eol-with<#19483#><#64069#>
The examples suggest that it doesn't matter what the second argument
is---as long as it is a list. Otherwise, it doesn't even make sense to
replace <#64070#><#19485#>empty<#19485#><#64070#> with the second argument. This implies that the
template should be that of a list-processing function with respect to the
first argument:
<#19490#>(d<#19490#><#19491#>efine<#19491#> <#19492#>(replace-eol-with<#19492#> <#19493#>alon1<#19493#> <#19494#>alon2)<#19494#>
<#19495#>(c<#19495#><#19496#>ond<#19496#>
<#19497#>((empty?<#19497#> <#19498#>alon1)<#19498#> <#19499#>...)<#19499#>
<#19500#>(else<#19500#> <#19501#>...<#19501#> <#19502#>(first<#19502#> <#19503#>alon1)<#19503#> <#19504#>...<#19504#> <#19505#>(replace-eol-with<#19505#> <#19506#>(rest<#19506#> <#19507#>alon1)<#19507#> <#19508#>alon2)<#19508#> <#19509#>...<#19509#> <#19510#>)))<#19510#>
The second argument is treated as it were an atomic piece of data.
Let's fill the gaps in the template, following the design recipe and using
our examples. If <#64071#><#19514#>alon1<#19514#><#64071#> is <#64072#><#19515#>empty<#19515#><#64072#>,
<#64073#><#19516#>replace-eol-with<#19516#><#64073#> produces <#64074#><#19517#>alon2<#19517#><#64074#> according to our
examples. For the second <#64075#><#19518#>cond<#19518#><#64075#>-clause, when <#64076#><#19519#>alon1<#19519#><#64076#> is not
<#64077#><#19520#>empty<#19520#><#64077#>, we must proceed by inspecting the available expressions:
- <#64078#><#19522#>(first<#19522#>\ <#19523#>alon1)<#19523#><#64078#> evaluates to the first item on the list, and
- <#64079#><#19524#>(replace-eol-with<#19524#>\ <#19525#>(rest<#19525#>\ <#19526#>alon1)<#19526#>\ <#19527#>alon2)<#19527#><#64079#> replaces
<#64080#><#19528#>empty<#19528#><#64080#> in <#64081#><#19529#>(rest<#19529#>\ <#19530#>alon1)<#19530#><#64081#> with <#64082#><#19531#>alon2<#19531#><#64082#>.
To gain a better understanding of what this means, consider one of the
examples:
<#19537#>(replace-eol-with<#19537#> <#19538#>(cons<#19538#> <#19539#>2<#19539#> <#19540#>(cons<#19540#> <#19541#>11<#19541#> <#19542#>(cons<#19542#> <#19543#>1<#19543#> <#19544#>empty)))<#19544#> <#19545#>L)<#19545#>
<#19546#>=<#19546#> <#19547#>(cons<#19547#> <#19548#>2<#19548#> <#19549#>(cons<#19549#> <#19550#>11<#19550#> <#19551#>(cons<#19551#> <#19552#>1<#19552#> <#19553#>L)))<#19553#>
Here <#64083#><#19557#>(first<#19557#>\ <#19558#>alon1)<#19558#><#64083#> is <#64084#><#19559#>2<#19559#><#64084#>, <#64085#><#19560#>(rest<#19560#>\ <#19561#>alon1)<#19561#><#64085#> is
<#64086#><#19562#>(cons<#19562#>\ <#19563#>11<#19563#>\ <#19564#>(cons<#19564#>\ <#19565#>1<#19565#>\ <#19566#>empty))<#19566#><#64086#>, and <#64087#><#19567#>(replace-eol-with<#19567#>\ <#19568#>(rest<#19568#><#19569#> <#19569#><#19570#>alon1)<#19570#>\ <#19571#>alon2)<#19571#><#64087#> is <#64088#><#19572#>(cons<#19572#>\ <#19573#>11<#19573#>\ <#19574#>(cons<#19574#>\ <#19575#>1<#19575#>\ <#19576#>alon2))<#19576#><#64088#>. We can combine
<#64089#><#19577#>2<#19577#><#64089#> and the latter with <#64090#><#19578#>cons<#19578#><#64090#> and can thus obtain the
desired result. More generally,
<#19583#>(cons<#19583#> <#19584#>(first<#19584#> <#19585#>alon1)<#19585#> <#19586#>(replace-eol-with<#19586#> <#19587#>(rest<#19587#> <#19588#>alon1)<#19588#> <#19589#>alon2)<#19589#>
is the answer in the second <#64091#><#19593#>cond<#19593#><#64091#>-clause. Figure~#figappend#19594>
contains the complete definition.
<#19597#>Exercise 17.1.1<#19597#>
In several exercises, we have used the Scheme operation <#64092#><#19599#>append<#19599#><#64092#>,
which consumes three lists and juxtaposes their items:
<#19604#>(append<#19604#> <#19605#>(list<#19605#> <#19606#>'<#19606#><#19607#>a)<#19607#> <#19608#>(list<#19608#> <#19609#>'<#19609#><#19610#>b<#19610#> <#19611#>'<#19611#><#19612#>c)<#19612#> <#19613#>(list<#19613#> <#19614#>'<#19614#><#19615#>d<#19615#> <#19616#>'<#19616#><#19617#>e<#19617#> <#19618#>'<#19618#><#19619#>f))<#19619#>
<#19620#>=<#19620#> <#19621#>(list<#19621#> <#19622#>'<#19622#><#19623#>a<#19623#> <#19624#>'<#19624#><#19625#>b<#19625#> <#19626#>'<#19626#><#19627#>c<#19627#> <#19628#>'<#19628#><#19629#>d<#19629#> <#19630#>'<#19630#><#19631#>e<#19631#> <#19632#>'<#19632#><#19633#>f)<#19633#>
Use <#64093#><#19637#>replace-eol-with<#19637#><#64093#> to define <#64094#><#19638#>our-append<#19638#><#64094#>, which acts
just like Scheme's <#64095#><#19639#>append<#19639#><#64095#>.~ Solution<#64096#><#64096#>
<#19645#>Exercise 17.1.2<#19645#>
Develop <#64097#><#19647#>cross<#19647#><#64097#>. The function consumes a list of symbols and a list
of numbers and produces all possible pairs of symbols and numbers.
Example:
<#19652#>(cross<#19652#> <#19653#>'<#19653#><#19654#>(a<#19654#> <#19655#>b<#19655#> <#19656#>c)<#19656#> <#19657#>'<#19657#><#19658#>(1<#19658#> <#19659#>2))<#19659#>
<#19660#>=<#19660#> <#19661#>(list<#19661#> <#19662#>(list<#19662#> <#19663#>'<#19663#><#19664#>a<#19664#> <#19665#>1)<#19665#> <#19666#>(list<#19666#> <#19667#>'<#19667#><#19668#>a<#19668#> <#19669#>2)<#19669#> <#19670#>(list<#19670#> <#19671#>'<#19671#><#19672#>b<#19672#> <#19673#>1)<#19673#> <#19674#>(list<#19674#> <#19675#>'<#19675#><#19676#>b<#19676#> <#19677#>2)<#19677#> <#19678#>(list<#19678#> <#19679#>'<#19679#><#19680#>c<#19680#> <#19681#>1)<#19681#> <#19682#>(list<#19682#> <#19683#>'<#19683#><#19684#>c<#19684#> <#19685#>2))<#19685#>
Solution<#64098#><#64098#>