Abstracting from Examples

Forming abstractions from examples is easy. As we have seen in section~#secsimilarities#28237>, we start from two concrete function definitions, compare them, mark the differences, and abstract. Let us formulate these steps as a recipe:
The comparison:
When we find two function definitions that are almost the same except at a few places and for their names, we compare them and mark the differences with boxes. If the boxes contain only values, we can abstract.

<#28239#>Warning: Abstracting over Non-values<#28239#>:\ <#28240#>The recipe requires a substantial modification for non-values.<#28240#>~<#65342#><#65342#> Here is a pair of similar function definitions:

<#71326#>;; <#65343#><#28247#>convertCF<#28247#> <#28248#>:<#28248#> <#28249#>lon<#28249#> <#28250#><#28250#><#28251#>-;SPMgt;<#28251#><#28252#><#28252#> <#28253#>lon<#28253#><#65343#><#71326#>
<#28254#>(d<#28254#><#28255#>efine<#28255#> <#28256#>(convertCF<#28256#> <#28257#>alon)<#28257#> 
  <#28258#>(c<#28258#><#28259#>ond<#28259#> 
    <#28260#>[<#28260#><#28261#>(empty?<#28261#> <#28262#>alon)<#28262#> <#28263#>empty]<#28263#> 
    <#28264#>[<#28264#><#28265#>e<#28265#><#28266#>lse<#28266#> 
      <#28267#>(c<#28267#><#28268#>ons<#28268#> <#28269#>(<#28269#>#tex2html_wrap73320# <#28275#>(first<#28275#> <#28276#>alon))<#28276#> 
        <#28277#>(convertCF<#28277#> <#28278#>(rest<#28278#> <#28279#>alon)))]<#28279#><#28280#>))<#28280#> 
<#71328#>;; <#65345#><#28286#>names<#28286#> <#28287#>:<#28287#> <#28288#>loIR<#28288#> <#28289#><#28289#><#28290#>-;SPMgt;<#28290#><#28291#><#28291#> <#28292#>los<#28292#><#65345#><#71328#>
<#28293#>(d<#28293#><#28294#>efine<#28294#> <#28295#>(names<#28295#> <#28296#>aloIR)<#28296#> 
  <#28297#>(c<#28297#><#28298#>ond<#28298#> 
    <#28299#>[<#28299#><#28300#>(empty?<#28300#> <#28301#>aloIR)<#28301#> <#28302#>empty]<#28302#> 
    <#28303#>[<#28303#><#28304#>e<#28304#><#28305#>lse<#28305#> 
      <#28306#>(c<#28306#><#28307#>ons<#28307#> <#28308#>(<#28308#>#tex2html_wrap73322# <#28310#>(first<#28310#> <#28311#>aloIR))<#28311#> 
        <#28312#>(names<#28312#> <#28313#>(rest<#28313#> <#28314#>aloIR)))]<#28314#><#28315#>))<#28315#> 
The two functions apply a function to each item in a list. They differ in only one aspect: what they apply to each item on the list. The two boxes emphasize the difference. Each contains a functional value, so we can abstract.
The abstraction:
Next we replace the contents of corresponding pairs of boxes with new names and add these names to the parameter list. For example, if there are three pairs of boxes, we need three new names. The two definitions must now be the same, except for the function name. To obtain the abstraction, we systematically replace the function names with one new name. For our running example, we obtain the following pair of functions:
<#28323#>(d<#28323#><#28324#>efine<#28324#> <#28325#>(convertCF<#28325#> <#28326#>f<#28326#> <#28327#>alon)<#28327#>
  <#28328#>(c<#28328#><#28329#>ond<#28329#> 
    <#28330#>[<#28330#><#28331#>(empty?<#28331#> <#28332#>alon)<#28332#> <#28333#>empty]<#28333#> 
    <#28334#>[<#28334#><#28335#>e<#28335#><#28336#>lse<#28336#> 
      <#28337#>(c<#28337#><#28338#>ons<#28338#> <#28339#>(<#28339#>#tex2html_wrap73324# <#28341#>(first<#28341#> <#28342#>alon))<#28342#> 
        <#28343#>(convertCF<#28343#> <#28344#>f<#28344#> <#28345#>(rest<#28345#> <#28346#>alon)))]<#28346#><#28347#>))<#28347#> 
<#28353#>(d<#28353#><#28354#>efine<#28354#> <#28355#>(names<#28355#> <#28356#>f<#28356#> <#28357#>aloIR)<#28357#>
  <#28358#>(c<#28358#><#28359#>ond<#28359#> 
    <#28360#>[<#28360#><#28361#>(empty?<#28361#> <#28362#>aloIR)<#28362#> <#28363#>empty]<#28363#> 
    <#28364#>[<#28364#><#28365#>e<#28365#><#28366#>lse<#28366#> 
      <#28367#>(c<#28367#><#28368#>ons<#28368#> <#28369#>(<#28369#>#tex2html_wrap73326# <#28371#>(first<#28371#> <#28372#>aloIR))<#28372#> 
        <#28373#>(names<#28373#> <#28374#>f<#28374#> <#28375#>(rest<#28375#> <#28376#>aloIR)))]<#28376#><#28377#>))<#28377#> 
We have replaced the boxed names with <#65349#><#28381#>f<#28381#><#65349#> and added <#65350#><#28382#>f<#28382#><#65350#> as a parameter. Now we replace <#65351#><#28383#>convertCF<#28383#><#65351#> and <#65352#><#28384#>names<#28384#><#65352#> with a new name and thus obtain the abstract function:
<#28389#>(d<#28389#><#28390#>efine<#28390#> <#28391#>(map<#28391#> <#28392#>f<#28392#> <#28393#>lon)<#28393#>
  <#28394#>(c<#28394#><#28395#>ond<#28395#> 
    <#28396#>[<#28396#><#28397#>(empty?<#28397#> <#28398#>lon)<#28398#> <#28399#>empty]<#28399#> 
    <#28400#>[<#28400#><#28401#>else<#28401#> <#28402#>(c<#28402#><#28403#>ons<#28403#> <#28404#>(f<#28404#> <#28405#>(first<#28405#> <#28406#>lon))<#28406#> 
            <#28407#>(map<#28407#> <#28408#>f<#28408#> <#28409#>(rest<#28409#> <#28410#>lon)))]<#28410#><#28411#>))<#28411#> 
We use the name <#65353#><#28415#>map<#28415#><#65353#> for the result in our running example, because it is the traditional name in programming languages for this specific function.
The test:
Now we must validate that the new function is a correct abstraction of the original concrete functions. The very definition of abstraction suggests that we define the original functions in terms of the abstract one and test the new versions with the original examples. In most cases, defining the original function based on the abstract one is straightforward. Suppose the abstract function is called <#65354#><#28416#>f-abstract<#28416#><#65354#> and furthermore suppose that one original function is called <#65355#><#28417#>f-original<#28417#><#65355#> and consumes one argument. If <#65356#><#28418#>f-original<#28418#><#65356#> differs from the other concrete function in the use of one value, say <#65357#><#28419#>boxed-value<#28419#><#65357#>, then we define the following function:
<#28424#>(d<#28424#><#28425#>efine<#28425#> <#28426#>(f-from-abstract<#28426#> <#28427#>x)<#28427#>
  <#28428#>(f-abstract<#28428#> <#28429#>boxed-value<#28429#> <#28430#>x))<#28430#> 
For every proper value <#65358#><#28434#>V<#28434#><#65358#>, <#65359#><#28435#>(f-from-abstract<#28435#>\ <#28436#>V)<#28436#><#65359#> now produces the same answer as <#65360#><#28437#>(f-original<#28437#>\ <#28438#>V)<#28438#><#65360#>. Let us return to our example. Here are the two new definitions:
<#71329#>;; <#65361#><#28443#>convertCF-from-map<#28443#> <#28444#>:<#28444#> <#28445#>lon<#28445#> <#28446#><#28446#><#28447#>-;SPMgt;<#28447#><#28448#><#28448#> <#28449#>lon<#28449#><#65361#><#71329#>
<#28450#>(d<#28450#><#28451#>efine<#28451#> <#28452#>(convertCF-from-map<#28452#> <#28453#>alon)<#28453#> 
  <#28454#>(map<#28454#> <#28455#>C<#28455#><#65362#><#28456#><#28456#><#28457#>-;SPMgt;<#28457#><#28458#><#28458#><#65362#><#28459#>F<#28459#> <#28460#>alon))<#28460#> 
<#71330#>;; <#65363#><#28466#>names-from-map<#28466#> <#28467#>:<#28467#> <#28468#>loIR<#28468#> <#28469#><#28469#><#28470#>-;SPMgt;<#28470#><#28471#><#28471#> <#28472#>los<#28472#><#65363#><#71330#>
<#28473#>(d<#28473#><#28474#>efine<#28474#> <#28475#>(names-from-map<#28475#> <#28476#>aloIR)<#28476#> 
  <#28477#>(map<#28477#> <#28478#>IR-name<#28478#> <#28479#>aloIR))<#28479#> 
To ensure that these two definitions are equivalent to the old one and, indirectly, that <#65364#><#28483#>map<#28483#><#65364#> is a correct abstraction, we now apply these two functions to the examples that we specified for the development of <#65365#><#28484#>convertCF<#28484#><#65365#> and <#65366#><#28485#>names<#28485#><#65366#>.
The contract:
To make the abstraction truly useful, we must also formulate a contract. If the boxed values in stage~2 of our recipe are functions, a contract requires the use of arrow types. Furthermore, to obtain a widely usable contract, we may have to develop or use parametric data definitions and formulate a parametric type. A case in point is the contract for <#65367#><#28486#>map<#28486#><#65367#>. On one hand, if we view <#65368#><#28487#>map<#28487#><#65368#> as an abstraction of <#65369#><#28488#>convertCF<#28488#><#65369#>, the contract could be construed as
<#71331#>;; <#65370#><#28493#>map<#28493#> <#28494#>:<#28494#> <#28495#>(number<#28495#> <#28496#><#28496#><#28497#>-;SPMgt;<#28497#><#28498#><#28498#> <#28499#>number)<#28499#> <#28500#>(listof<#28500#> <#28501#>number)<#28501#> <#28502#><#28502#><#28503#>-;SPMgt;<#28503#><#28504#><#28504#> <#28505#>(listof<#28505#> <#28506#>number)<#28506#><#65370#><#71331#>
On the other hand, if we view <#65371#><#28510#>map<#28510#><#65371#> as an abstraction of <#65372#><#28511#>names<#28511#><#65372#>, the contract could be construed as
<#71332#>;; <#65373#><#28516#>map<#28516#> <#28517#>:<#28517#> <#28518#>(IR<#28518#> <#28519#><#28519#><#28520#>-;SPMgt;<#28520#><#28521#><#28521#> <#28522#>symbol)<#28522#> <#28523#>(listof<#28523#> <#28524#>IR)<#28524#> <#28525#><#28525#><#28526#>-;SPMgt;<#28526#><#28527#><#28527#> <#28528#>(listof<#28528#> <#28529#>symbol)<#28529#><#65373#><#71332#>
But the first contract would be useless in the second case, and <#28533#>vice versa<#28533#>. To accommodate both cases, we must understand what <#65374#><#28534#>map<#28534#><#65374#> does and then fix a contract. By looking at the definition, we can see that map applies its first argument, a function, to every item on the second argument, a list. This implies that the function must consume the class of data that the list contains. That is, we know <#65375#><#28535#>f<#28535#><#65375#> has the contract
<#71333#>;; <#65376#><#28540#>f<#28540#> <#28541#>:<#28541#> <#28542#>X<#28542#> <#28543#><#28543#><#28544#>-;SPMgt;<#28544#><#28545#><#28545#> <#28546#>?<#28546#><#28547#>?<#28547#><#28548#>?<#28548#><#65376#><#71333#>
if <#65377#><#28552#>lon<#28552#><#65377#> contains <#65378#><#28553#>X<#28553#><#65378#>s. Furthermore, <#65379#><#28554#>map<#28554#><#65379#> creates a list from the results of applying <#65380#><#28555#>f<#28555#><#65380#> to each item. Thus, if <#65381#><#28556#>f<#28556#><#65381#> produces <#65382#><#28557#>Y<#28557#><#65382#>s, then <#65383#><#28558#>map<#28558#><#65383#> produces a list of <#65384#><#28559#>Y<#28559#><#65384#>s. Translated into our language of contracts we get this:
<#71334#>;; <#65385#><#28564#>map<#28564#> <#28565#>:<#28565#> <#28566#>(X<#28566#> <#28567#><#28567#><#28568#>-;SPMgt;<#28568#><#28569#><#28569#> <#28570#>Y)<#28570#> <#28571#>(listof<#28571#> <#28572#>X)<#28572#> <#28573#><#28573#><#28574#>-;SPMgt;<#28574#><#28575#><#28575#> <#28576#>(listof<#28576#> <#28577#>Y)<#28577#><#65385#><#71334#>
This contract says that <#65386#><#28581#>map<#28581#><#65386#> can produce a list of <#65387#><#28582#>Y<#28582#><#65387#>s from a list of <#65388#><#28583#>X<#28583#><#65388#>s and a function from <#65389#><#28584#>X<#28584#><#65389#> to <#65390#><#28585#>Y<#28585#><#65390#>---no matter for what collection of <#65391#><#28586#>X<#28586#><#65391#> and <#65392#><#28587#>Y<#28587#><#65392#> stand.
Once we have abstracted two (or more) functions, we should check whether there are other uses for the abstract function. In many cases, an abstract function is useful in a much broader array of contexts than we first anticipate and makes functions easier to read, understand, and maintain. For example, we can now use <#65393#><#28589#>map<#28589#><#65393#> every time we need a function to produce a new list by processing all items on an existing list. If that function is a primitive operation or a function we have defined, we don't even write a function. Instead, we simply write an expression that performs the task. Unfortunately, there is no recipe that guides this discovery process. We must practice it and develop an eye for matching abstract functions to situations.
<#28592#>Exercise 21.1.1<#28592#> Define <#65394#><#28594#>tabulate<#28594#><#65394#>, which is the abstraction of the following two functions:
<#71335#>;; <#65395#><#28599#>tabulate-sin<#28599#> <#28600#>:<#28600#> <#28601#>number<#28601#> <#28602#><#28602#><#28603#>-;SPMgt;<#28603#><#28604#><#28604#> <#28605#>lon<#28605#><#65395#><#71335#>
<#71336#>;; to tabulate <#65396#><#28606#>sin<#28606#><#65396#> between <#65397#><#28607#>n<#28607#><#65397#> <#71336#> 
<#71337#>;; and <#65398#><#28608#>0<#28608#><#65398#> (inclusive) in a list<#71337#> 
<#28609#>(d<#28609#><#28610#>efine<#28610#> <#28611#>(tabulate-sin<#28611#> <#28612#>n)<#28612#> 
  <#28613#>(c<#28613#><#28614#>ond<#28614#> 
    <#28615#>[<#28615#><#28616#>(=<#28616#> <#28617#>n<#28617#> <#28618#>0)<#28618#> <#28619#>(list<#28619#> <#28620#>(sin<#28620#> <#28621#>0))]<#28621#> 
    <#28622#>[<#28622#><#28623#>e<#28623#><#28624#>lse<#28624#> 
      <#28625#>(c<#28625#><#28626#>ons<#28626#> <#28627#>(sin<#28627#> <#28628#>n)<#28628#> 
        <#28629#>(tabulate-sin<#28629#> <#28630#>(sub1<#28630#> <#28631#>n)))]<#28631#><#28632#>))<#28632#> 
<#71338#>;; <#65399#><#28638#>tabulate-sqrt<#28638#> <#28639#>:<#28639#> <#28640#>number<#28640#> <#28641#><#28641#><#28642#>-;SPMgt;<#28642#><#28643#><#28643#> <#28644#>lon<#28644#><#65399#><#71338#>
<#71339#>;; to tabulate <#65400#><#28645#>sqrt<#28645#><#65400#> between <#65401#><#28646#>n<#28646#><#65401#> <#71339#> 
<#71340#>;; and <#65402#><#28647#>0<#28647#><#65402#> (inclusive) in a list<#71340#> 
<#28648#>(d<#28648#><#28649#>efine<#28649#> <#28650#>(tabulate-sqrt<#28650#> <#28651#>n)<#28651#> 
  <#28652#>(c<#28652#><#28653#>ond<#28653#> 
    <#28654#>[<#28654#><#28655#>(=<#28655#> <#28656#>n<#28656#> <#28657#>0)<#28657#> <#28658#>(list<#28658#> <#28659#>(sqrt<#28659#> <#28660#>0))]<#28660#> 
    <#28661#>[<#28661#><#28662#>e<#28662#><#28663#>lse<#28663#> 
      <#28664#>(c<#28664#><#28665#>ons<#28665#> <#28666#>(sqrt<#28666#> <#28667#>n)<#28667#> 
        <#28668#>(tabulate-sqrt<#28668#> <#28669#>(sub1<#28669#> <#28670#>n)))]<#28670#><#28671#>))<#28671#> 
Make sure to define the two functions in terms of <#65403#><#28675#>tabulate<#28675#><#65403#>. Also use <#65404#><#28676#>tabulate<#28676#><#65404#> to define a tabulation function for <#65405#><#28677#>square<#28677#><#65405#> and <#65406#><#28678#>tan<#28678#><#65406#>. What would be a good, general contract?~ external Solution<#65407#><#65407#> <#28684#>Exercise 21.1.2<#28684#> Define <#65408#><#28686#>fold<#28686#><#65408#>, which is the abstraction of the following two functions:
<#71341#>;; <#65409#><#28691#>sum<#28691#> <#28692#>:<#28692#> <#28693#>(listof<#28693#> <#28694#>number)<#28694#> <#28695#><#28695#><#28696#>-;SPMgt;<#28696#><#28697#><#28697#> <#28698#>number<#28698#><#65409#><#71341#>
<#28699#>;; to compute the sum of <#28699#> 
<#71342#>;; the numbers on <#65410#><#28700#>alon<#28700#><#65410#><#71342#> 
<#28701#>(d<#28701#><#28702#>efine<#28702#> <#28703#>(sum<#28703#> <#28704#>alon)<#28704#> 
  <#28705#>(c<#28705#><#28706#>ond<#28706#> 
    <#28707#>[<#28707#><#28708#>(empty?<#28708#> <#28709#>alon)<#28709#> <#28710#>0]<#28710#> 
    <#28711#>[<#28711#><#28712#>else<#28712#> <#28713#>(+<#28713#> <#28714#>(first<#28714#> <#28715#>alon)<#28715#> 
             <#28716#>(sum<#28716#> <#28717#>(rest<#28717#> <#28718#>alon)))]<#28718#><#28719#>))<#28719#> 
<#71343#>;; <#65411#><#28725#>product<#28725#> <#28726#>:<#28726#> <#28727#>(listof<#28727#> <#28728#>number)<#28728#> <#28729#><#28729#><#28730#>-;SPMgt;<#28730#><#28731#><#28731#> <#28732#>number<#28732#><#65411#><#71343#>
<#28733#>;; to compute the product of <#28733#> 
<#71344#>;; the numbers on <#65412#><#28734#>alon<#28734#><#65412#><#71344#> 
<#28735#>(d<#28735#><#28736#>efine<#28736#> <#28737#>(product<#28737#> <#28738#>alon)<#28738#> 
  <#28739#>(c<#28739#><#28740#>ond<#28740#> 
    <#28741#>[<#28741#><#28742#>(empty?<#28742#> <#28743#>alon)<#28743#> <#28744#>1]<#28744#> 
    <#28745#>[<#28745#><#28746#>else<#28746#> <#28747#>(*<#28747#> <#28748#>(first<#28748#> <#28749#>alon)<#28749#> 
             <#28750#>(product<#28750#> <#28751#>(rest<#28751#> <#28752#>alon)))]<#28752#><#28753#>))<#28753#> 
Don't forget to test <#65413#><#28757#>fold<#28757#><#65413#>. After <#65414#><#28758#>fold<#28758#><#65414#> is defined and tested, use it to define <#65415#><#28759#>append<#28759#><#65415#>, which juxtaposes the items of two lists or, equivalently, replaces <#65416#><#28760#>empty<#28760#><#65416#> in the first list with the second list:
  <#28765#>(append<#28765#> <#28766#>(list<#28766#> <#28767#>1<#28767#> <#28768#>2<#28768#> <#28769#>3)<#28769#> <#28770#>(list<#28770#> <#28771#>4<#28771#> <#28772#>5<#28772#> <#28773#>6<#28773#> <#28774#>7<#28774#> <#28775#>8))<#28775#>
<#28776#>=<#28776#> <#28777#>(list<#28777#> <#28778#>1<#28778#> <#28779#>2<#28779#> <#28780#>3<#28780#> <#28781#>4<#28781#> <#28782#>5<#28782#> <#28783#>6<#28783#> <#28784#>7<#28784#> <#28785#>8)<#28785#> 
Finally, define <#65417#><#28789#>map<#28789#><#65417#> using <#65418#><#28790#>fold<#28790#><#65418#>. Compare the four examples to formulate a contract.~ external Solution<#65419#><#65419#> <#28796#>Exercise 21.1.3<#28796#> Define <#65420#><#28798#>natural-f<#28798#><#65420#>, which is the abstraction of the following two functions:
<#71345#>;; <#65421#><#28803#>copy<#28803#> <#28804#>:<#28804#> <#28805#>N<#28805#> <#28806#>X<#28806#> <#28807#><#28807#><#28808#>-;SPMgt;<#28808#><#28809#><#28809#> <#28810#>(listof<#28810#> <#28811#>X)<#28811#><#65421#><#71345#>
<#28812#>;; to create a list that contains<#28812#> 
<#71346#>;; <#65422#><#28813#>obj<#28813#><#65422#> <#65423#><#28814#>n<#28814#><#65423#> times<#71346#> 
<#28815#>(d<#28815#><#28816#>efine<#28816#> <#28817#>(copy<#28817#> <#28818#>n<#28818#> <#28819#>obj)<#28819#> 
  <#28820#>(c<#28820#><#28821#>ond<#28821#> 
    <#28822#>[<#28822#><#28823#>(zero?<#28823#> <#28824#>n)<#28824#> <#28825#>empty]<#28825#> 
    <#28826#>[<#28826#><#28827#>else<#28827#> <#28828#>(cons<#28828#> <#28829#>obj<#28829#> 
                <#28830#>(copy<#28830#> <#28831#>(sub1<#28831#> <#28832#>n)<#28832#> <#28833#>obj))]<#28833#><#28834#>))<#28834#> 
~
<#71347#>;; <#65424#><#28840#>n-adder<#28840#> <#28841#>:<#28841#> <#28842#>N<#28842#> <#28843#>number<#28843#> <#28844#><#28844#><#28845#>-;SPMgt;<#28845#><#28846#><#28846#> <#28847#>number<#28847#><#65424#><#71347#>
<#71348#>;; to add <#65425#><#28848#>n<#28848#><#65425#> to <#65426#><#28849#>x<#28849#><#65426#> using<#71348#> 
<#71349#>;; <#65427#><#28850#>(+<#28850#> <#28851#>1<#28851#> <#28852#>...)<#28852#><#65427#> only<#71349#> 
<#28853#>(d<#28853#><#28854#>efine<#28854#> <#28855#>(n-adder<#28855#> <#28856#>n<#28856#> <#28857#>x)<#28857#> 
  <#28858#>(c<#28858#><#28859#>ond<#28859#> 
    <#28860#>[<#28860#><#28861#>(zero?<#28861#> <#28862#>n)<#28862#> <#28863#>x]<#28863#> 
    <#28864#>[<#28864#><#28865#>else<#28865#> <#28866#>(+<#28866#> <#28867#>1<#28867#> 
             <#28868#>(n-adder<#28868#> <#28869#>(sub1<#28869#> <#28870#>n)<#28870#> <#28871#>x))]<#28871#><#28872#>))<#28872#> 
Don't forget to test <#65428#><#28876#>natural-n<#28876#><#65428#>. Also use <#65429#><#28877#>natural-n<#28877#><#65429#> to define <#65430#><#28878#>n-multiplier<#28878#><#65430#>, which consumes <#65431#><#28879#>n<#28879#><#65431#> and <#65432#><#28880#>x<#28880#><#65432#> and produces <#65433#><#28881#>n<#28881#><#65433#> times <#65434#><#28882#>x<#28882#><#65434#> with additions only. Use the examples to formulate a contract. <#28883#>Hint:<#28883#> \ The two function differ more than, say, the functions <#65435#><#28884#>sum<#28884#><#65435#> and <#65436#><#28885#>product<#28885#><#65436#> in exercise~#exabssumprod#28886>. In particular, the base case in one instance is a argument of the function, in the other it is just a constant value. ~ external Solution<#65437#><#65437#>

<#28894#>Formulating General Contracts<#28894#>:\ To increase the usefulness of an abstract function, we must formulate a contract that describes its applicability in the most general terms possible. In principle, abstracting contracts follows the same recipe that we use for abstracting functions. We compare and contrast the old contracts; then we replace the differences by variables. But the process is complicated and requires a lot of practice. Let us start with our running example: <#65438#><#28895#>convertCF<#28895#><#65438#> and <#65439#><#28896#>names<#28896#><#65439#>: rawhtml30 Comparing the two contracts shows that they differ in two places. To the left of <#65440#><#28897#><#28897#><#28898#>-;SPMgt;<#28898#><#28899#><#28899#><#65440#>, we have <#65441#><#28900#>number<#28900#><#65441#> and <#65442#><#28901#>IR<#28901#><#65442#>; to the right, it is <#65443#><#28902#>number<#28902#><#65443#> versus <#65444#><#28903#>symbol<#28903#><#65444#>. Consider the second stage of our abstraction recipe. The most natural contracts are as follows: rawhtml31 These new contracts suggest a pattern. Specifically, they suggest that the first argument, a function, consumes the items on the second argument, a list, and furthermore, that the results produced by these applications make up the output. The second contract is particularly telling. If we replace <#65445#><#28904#>IR<#28904#><#65445#> and <#65446#><#28905#>symbol<#28905#><#65446#> with variables, we get an abstract contract, and it is indeed a contract for <#65447#><#28906#>map<#28906#><#65447#>: <#65448#><#28908#>map<#28908#>\ <#28909#>:<#28909#>\ <#28910#>(X<#28910#>\ <#28911#><#28911#><#28912#>-;SPMgt;<#28912#><#28913#><#28913#>\ <#28914#>Y)<#28914#>\ <#28915#>(listof<#28915#>\ <#28916#>X)<#28916#>\ <#28917#><#28917#><#28918#>-;SPMgt;<#28918#><#28919#><#28919#>\ <#28920#>(listof<#28920#>\ <#28921#>Y)<#28921#><#65448#> It is straightforward to check that by replacing <#65449#><#28923#>X<#28923#><#65449#> with <#65450#><#28924#>number<#28924#><#65450#> and <#65451#><#28925#>Y<#28925#><#65451#> with <#65452#><#28926#>number<#28926#><#65452#>, we get the first of the intermediate contracts. Here is a second pair of examples: rawhtml32 They are the contracts for <#65453#><#28927#>below<#28927#><#65453#> and <#65454#><#28928#>below-ir<#28928#><#65454#>. The contracts differ in two places: the lists consumed and produced. As usual, the functions of the second stage consume an additional argument: rawhtml33 The new argument is a function, which in the first case consumes a number, and in the second case an <#65455#><#28929#>IR<#28929#><#65455#>. A comparison of the two contracts suggests that <#65456#><#28930#>number<#28930#><#65456#> and <#65457#><#28931#>IR<#28931#><#65457#> occupy related positions and that we should replace them with a variable. Doing so makes the two contracts equal: rawhtml34 A closer inspection of <#65458#><#28932#>filter1<#28932#><#65458#>'s definition shows that we can also replace <#65459#><#28933#>number<#28933#><#65459#> with <#65460#><#28934#>Y<#28934#><#65460#> because the second argument is always just the first argument of <#65461#><#28935#>filter1<#28935#><#65461#>'s first argument. Here is the new contract: <#65462#><#28937#>filter1<#28937#>\ <#28938#>:<#28938#>\ <#28939#>(Y<#28939#>\ <#28940#>X<#28940#>\ <#28941#><#28941#><#28942#>-;SPMgt;<#28942#><#28943#><#28943#>\ <#28944#>boolean)<#28944#>\ <#28945#>Y<#28945#>\ <#28946#>(listof<#28946#>\ <#28947#>X)<#28947#>\ <#28948#><#28948#><#28949#>-;SPMgt;<#28949#><#28950#><#28950#>\ <#28951#>(listof<#28951#>\ <#28952#>X)<#28952#><#65462#> The result of the first argument must be <#65463#><#28954#>boolean<#28954#><#65463#>, because it is used as a condition. Hence, we have found the most general contract possible. The two examples illustrate how to find general contracts. We compare the contracts of the examples from which we create abstractions. By replacing specific, distinct classes in corresponding positions, one at a time, we make the contract gradually more general. To ensure that our generalized contract works, we check that the contract describes the specific instances of the abstracted function properly.~<#65464#><#65464#>