Processing Natural Numbers of Arbitrary Size

Let us develop the function <#62574#><#12350#>hellos<#12350#><#62574#>. It consumes a natural number <#62575#><#12351#>n<#12351#><#62575#> and produces a list of <#62576#><#12352#>n<#12352#><#62576#> copies of <#62577#><#12353#>'<#12353#><#12354#>hello<#12354#><#62577#>. We can write the contract for this function:
<#70994#>;; <#62578#><#12359#>hellos<#12359#> <#12360#>:<#12360#> <#12361#>N<#12361#> <#12362#><#12362#><#12363#>-;SPMgt;<#12363#><#12364#><#12364#> <#12365#>list-of-symbols<#12365#><#62578#><#70994#>
<#70995#>;; to create a list of <#62579#><#12366#>n<#12366#><#62579#> copies of <#62580#><#12367#>'<#12367#><#12368#>hello<#12368#><#62580#><#70995#> 
<#12369#>(define<#12369#> <#12370#>(hellos<#12370#> <#12371#>n)<#12371#> <#12372#>...)<#12372#> 
And we can make up examples:
  <#12380#>(hellos<#12380#> <#12381#>0)<#12381#> 
<#12382#>=<#12382#> <#12383#>empty<#12383#> 
  <#12391#>(hellos<#12391#> <#12392#>2)<#12392#>
<#12393#>=<#12393#> <#12394#>(cons<#12394#> <#12395#>'<#12395#><#12396#>hello<#12396#> <#12397#>(cons<#12397#> <#12398#>'<#12398#><#12399#>hello<#12399#> <#12400#>empty))<#12400#> 
The design of a template for <#62581#><#12404#>hellos<#12404#><#62581#> follows the design recipe for self-referential data definitions. We immediately see that <#62582#><#12405#>hellos<#12405#><#62582#> is a conditional function, that its <#62583#><#12406#>cond<#12406#>-expression<#62583#> has two clauses, and that the first clause must distinguish <#62584#><#12407#>0<#12407#><#62584#> from other possible inputs:
<#12412#>(d<#12412#><#12413#>efine<#12413#> <#12414#>(hellos<#12414#> <#12415#>n)<#12415#>
  <#12416#>(c<#12416#><#12417#>ond<#12417#> 
    <#12418#>[<#12418#><#12419#>(zero?<#12419#> <#12420#>n)<#12420#> <#12421#>...]<#12421#> 
    <#12422#>[<#12422#><#12423#>else<#12423#> <#12424#>...]<#12424#><#12425#>))<#12425#> 
Furthermore, the data definition says that <#62585#><#12429#>0<#12429#><#62585#> is an atomic value, and every other natural number is a compound value that ``contains'' the predecessor to which <#62586#><#12430#>1<#12430#><#62586#> was added. Hence, if <#62587#><#12431#>n<#12431#><#62587#> is not <#62588#><#12432#>0<#12432#><#62588#>, we subtract <#62589#><#12433#>1<#12433#><#62589#> from <#62590#><#12434#>n<#12434#><#62590#>. The result is also a natural number, so according to the design recipe we wrap the expression with <#62591#><#12435#>(hellos<#12435#>\ <#12436#>...)<#12436#><#62591#>:
<#12441#>(d<#12441#><#12442#>efine<#12442#> <#12443#>(hellos<#12443#> <#12444#>n)<#12444#>
  <#12445#>(c<#12445#><#12446#>ond<#12446#> 
    <#12447#>[<#12447#><#12448#>(zero?<#12448#> <#12449#>n)<#12449#> <#12450#>...]<#12450#> 
    <#12451#>[<#12451#><#12452#>else<#12452#> <#12453#>...<#12453#> <#12454#>(hellos<#12454#> <#12455#>(sub1<#12455#> <#12456#>n))<#12456#> <#12457#>...<#12457#> <#12458#>]<#12458#><#12459#>))<#12459#> 
Now we have exploited every hint in the data definition and are ready to proceed with the definition. Assume <#62592#><#12463#>(zero?<#12463#>\ <#12464#>n)<#12464#><#62592#> evaluates to true. Then the answer must be <#62593#><#12465#>empty<#12465#><#62593#>, as the examples illustrate. So assume the input is greater than <#62594#><#12466#>0<#12466#><#62594#>. For concreteness, let us say it is <#62595#><#12467#>2<#12467#><#62595#>. According to the suggestion in the template, <#62596#><#12468#>hellos<#12468#><#62596#> should use <#62597#><#12469#>(hellos<#12469#>\ <#12470#>1)<#12470#><#62597#> to compute a part of the answer. The purpose statement specifies that <#62598#><#12471#>(hellos<#12471#>\ <#12472#>1)<#12472#><#62598#> produces <#62599#><#12473#>(cons<#12473#>\ <#12474#>'<#12474#><#12475#>hello<#12475#>\ <#12476#>empty)<#12476#><#62599#>, a list with one <#62600#><#12477#>'<#12477#><#12478#>hello<#12478#><#62600#>. In general, <#62601#><#12479#>(hellos<#12479#>\ <#12480#>(sub1<#12480#>\ <#12481#>n))<#12481#><#62601#> produces a list that contains n - 1 occurrences of <#62602#><#12482#>'<#12482#><#12483#>hello<#12483#><#62602#>. Clearly, to produce a list with <#62603#><#12484#>n<#12484#><#62603#> occurrences, we must <#62604#><#12485#>cons<#12485#><#62604#> another <#62605#><#12486#>'<#12486#><#12487#>hello<#12487#><#62605#> onto this list:
<#12492#>(d<#12492#><#12493#>efine<#12493#> <#12494#>(hellos<#12494#> <#12495#>n)<#12495#>
  <#12496#>(c<#12496#><#12497#>ond<#12497#> 
    <#12498#>[<#12498#><#12499#>(zero?<#12499#> <#12500#>n)<#12500#> <#12501#>empty]<#12501#> 
    <#12502#>[<#12502#><#12503#>else<#12503#> <#12504#>(cons<#12504#> <#12505#>'<#12505#><#12506#>hello<#12506#> <#12507#>(hellos<#12507#> <#12508#>(sub1<#12508#> <#12509#>n)))]<#12509#><#12510#>))<#12510#> 
As usual, the final definition is just the template with a few extras. Let's test <#62606#><#12514#>hellos<#12514#><#62606#> with some hand-evaluations:
  <#12519#>(hellos<#12519#> <#12520#>0)<#12520#>
<#12521#>=<#12521#> <#12522#>(c<#12522#><#12523#>ond<#12523#> 
    <#12524#>[<#12524#><#12525#>(zero?<#12525#> <#12526#>0)<#12526#> <#12527#>empty]<#12527#> 
    <#12528#>[<#12528#><#12529#>else<#12529#> <#12530#>(cons<#12530#> <#12531#>'<#12531#><#12532#>hello<#12532#> <#12533#>(hellos<#12533#> <#12534#>(sub1<#12534#> <#12535#>0)))]<#12535#><#12536#>)<#12536#> 
<#12537#>=<#12537#> <#12538#>(c<#12538#><#12539#>ond<#12539#> 
    <#12540#>[<#12540#><#12541#>true<#12541#> <#12542#>empty]<#12542#> 
    <#12543#>[<#12543#><#12544#>else<#12544#> <#12545#>(cons<#12545#> <#12546#>'<#12546#><#12547#>hello<#12547#> <#12548#>(hellos<#12548#> <#12549#>(sub1<#12549#> <#12550#>0)))]<#12550#><#12551#>)<#12551#> 
<#12552#>=<#12552#> <#12553#>empty<#12553#> 
It confirms that <#62607#><#12557#>hellos<#12557#><#62607#> works properly for the first example. Here is another example:
  <#12562#>(hellos<#12562#> <#12563#>1)<#12563#>
<#12564#>=<#12564#> <#12565#>(c<#12565#><#12566#>ond<#12566#> 
    <#12567#>[<#12567#><#12568#>(zero?<#12568#> <#12569#>1)<#12569#> <#12570#>empty]<#12570#> 
    <#12571#>[<#12571#><#12572#>else<#12572#> <#12573#>(cons<#12573#> <#12574#>'<#12574#><#12575#>hello<#12575#> <#12576#>(hellos<#12576#> <#12577#>(sub1<#12577#> <#12578#>1)))]<#12578#><#12579#>)<#12579#> 
<#12580#>=<#12580#> <#12581#>(c<#12581#><#12582#>ond<#12582#> 
    <#12583#>[<#12583#><#12584#>false<#12584#> <#12585#>empty]<#12585#> 
    <#12586#>[<#12586#><#12587#>else<#12587#> <#12588#>(cons<#12588#> <#12589#>'<#12589#><#12590#>hello<#12590#> <#12591#>(hellos<#12591#> <#12592#>(sub1<#12592#> <#12593#>1)))]<#12593#><#12594#>)<#12594#> 
<#12595#>=<#12595#> <#12596#>(cons<#12596#> <#12597#>'<#12597#><#12598#>hello<#12598#> <#12599#>(hellos<#12599#> <#12600#>(sub1<#12600#> <#12601#>1)))<#12601#> 
<#12602#>=<#12602#> <#12603#>(cons<#12603#> <#12604#>'<#12604#><#12605#>hello<#12605#> <#72336#>#tex2html_wrap_inline73020#<#72336#><#12608#>)<#12608#> 
<#12609#>=<#12609#> <#12610#>(cons<#12610#> <#12611#>'<#12611#><#12612#>hello<#12612#> <#12613#>empty)<#12613#> 
For the last step in the calculation, we can exploit that we already know that <#62609#><#12617#>(hellos<#12617#>\ <#12618#>0)<#12618#><#62609#> evaluates to <#62610#><#12619#>empty<#12619#><#62610#> and replace the (underlined) expression with its result. The last hand-evaluation shows that <#62611#><#12620#>hellos<#12620#><#62611#> works for the second example:
  <#12625#>(hellos<#12625#> <#12626#>2)<#12626#>
<#12627#>=<#12627#> <#12628#>(c<#12628#><#12629#>ond<#12629#> 
    <#12630#>[<#12630#><#12631#>(zero?<#12631#> <#12632#>2)<#12632#> <#12633#>empty]<#12633#> 
    <#12634#>[<#12634#><#12635#>else<#12635#> <#12636#>(cons<#12636#> <#12637#>'<#12637#><#12638#>hello<#12638#> <#12639#>(hellos<#12639#> <#12640#>(sub1<#12640#> <#12641#>2)))]<#12641#><#12642#>)<#12642#> 
<#12643#>=<#12643#> <#12644#>(c<#12644#><#12645#>ond<#12645#> 
    <#12646#>[<#12646#><#12647#>false<#12647#> <#12648#>empty]<#12648#> 
    <#12649#>[<#12649#><#12650#>else<#12650#> <#12651#>(cons<#12651#> <#12652#>'<#12652#><#12653#>hello<#12653#> <#12654#>(hellos<#12654#> <#12655#>(sub1<#12655#> <#12656#>2)))]<#12656#><#12657#>)<#12657#> 
<#12658#>=<#12658#> <#12659#>(cons<#12659#> <#12660#>'<#12660#><#12661#>hello<#12661#> <#12662#>(hellos<#12662#> <#12663#>(sub1<#12663#> <#12664#>2)))<#12664#> 
<#12665#>=<#12665#> <#12666#>(cons<#12666#> <#12667#>'<#12667#><#12668#>hello<#12668#> <#72337#>#tex2html_wrap_inline73022#<#72337#><#12671#>)<#12671#> 
<#12672#>=<#12672#> <#12673#>(cons<#12673#> <#12674#>'<#12674#><#12675#>hello<#12675#> <#12676#>(cons<#12676#> <#12677#>'<#12677#><#12678#>hello<#12678#> <#12679#>empty))<#12679#> 
We can again exploit what we know about <#62613#><#12683#>(hellos<#12683#>\ <#12684#>1)<#12684#><#62613#>, which greatly shortens the hand-evaluation.
<#12687#>Exercise 11.2.1<#12687#> Generalize <#62614#><#12690#>hellos<#12690#><#62614#> to <#62615#><#12691#>repeat<#12691#><#62615#>, which consumes a natural number <#62616#><#12692#>n<#12692#><#62616#> and a symbol and produces a list with <#62617#><#12693#>n<#12693#><#62617#> occurrences of the symbol.~ external Solution<#62618#><#62618#> <#12699#>Exercise 11.2.2<#12699#> Develop the function <#62619#><#12701#>tabulate-f<#12701#><#62619#>, which tabulates the values of
<#70998#>;; <#62620#><#12706#>f<#12706#> <#12707#>:<#12707#> <#12708#>number<#12708#> <#12709#><#12709#><#12710#>-;SPMgt;<#12710#><#12711#><#12711#> <#12712#>number<#12712#><#62620#><#70998#>
<#12713#>(d<#12713#><#12714#>efine<#12714#> <#12715#>(f<#12715#> <#12716#>x)<#12716#> 
  <#12717#>(+<#12717#> <#12718#>(*<#12718#> <#12719#>3<#12719#> <#12720#>(*<#12720#> <#12721#>x<#12721#> <#12722#>x))<#12722#> 
     <#12723#>(+<#12723#> <#12724#>(*<#12724#> <#12725#>-6<#12725#> <#12726#>x)<#12726#> 
        <#12727#>-1)))<#12727#> 
for some natural numbers. Specifically, it consumes a natural number <#62621#><#12731#>n<#12731#><#62621#> and produces a list of <#62622#><#12732#>n<#12732#><#62622#> <#62623#><#12733#>posn<#12733#><#62623#>s. The first one combines <#62624#><#12734#>n<#12734#><#62624#> with <#62625#><#12735#>(f<#12735#>\ <#12736#>n)<#12736#><#62625#>, the second one <#62626#><#12737#>n-1<#12737#><#62626#> with <#62627#><#12738#>(f<#12738#>\ <#12739#>n-1)<#12739#><#62627#>, <#12740#>etc<#12740#>.~ external Solution<#62628#><#62628#> <#12746#>Exercise 11.2.3<#12746#> Develop <#62629#><#12749#>apply-n<#12749#><#62629#>. The function consumes a natural number, <#62630#><#12750#>n<#12750#><#62630#>. It applies the function <#62631#><#12751#>move<#12751#><#62631#> from exercise~#exmoving#12752> <#62632#><#12753#>n<#12753#><#62632#> times to <#62633#><#12754#>FACE<#12754#><#62633#>, the list of shapes from exercise~#exmovinglistdat#12755>. Each application should translate the shape by one pixel. The purpose of the function is to simulate a continuously moving shape on a canvas, the last missing piece of the extended exercise~#secmovefig#12756>.~ external Solution<#62634#><#62634#> <#12762#>Exercise 11.2.4<#12762#> Lists may contain lists that contain lists and so on. Here is a data definition that takes this idea to an extreme:
A <#62635#><#12765#>deep list<#12765#><#62635#> is either
  1. <#62636#><#12767#>s<#12767#><#62636#> where <#62637#><#12768#>s<#12768#><#62637#> is some symbol or
  2. <#62638#><#12769#>(cons<#12769#>\ <#12770#>dl<#12770#>\ <#12771#>empty)<#12771#><#62638#>, where <#62639#><#12772#>dl<#12772#><#62639#> is a deep list.
Develop the function <#62640#><#12775#>depth<#12775#><#62640#>, which consumes a deep list and determines how many <#62641#><#12776#>cons<#12776#><#62641#>es were used to construct it. Develop the function <#62642#><#12777#>make-deep<#12777#><#62642#>, which consumes a symbol <#62643#><#12778#>s<#12778#><#62643#> and a natural number and produces a deep list containing <#62644#><#12779#>s<#12779#><#62644#> and <#62645#><#12780#>cons<#12780#><#62645#>tructed with <#62646#><#12781#>n<#12781#><#62646#> <#62647#><#12782#>cons<#12782#><#62647#>es. external Solution<#62648#><#62648#>