Contracts for Abstract and Polymorphic Functions

When we first abstracted <#65241#><#27795#>below<#27795#><#65241#> and <#65242#><#27796#>above<#27796#><#65242#> into <#65243#><#27797#>filter1<#27797#><#65243#>, we did not formulate a contract. Unlike the functions we had defined before, <#65244#><#27798#>filter1<#27798#><#65244#> consumed a type of values that we never before used as data: primitive operations and other functions. Still, we eventually agreed in plain English writing that <#65245#><#27799#>filter1<#27799#><#65245#>'s first argument, <#65246#><#27800#>rel-op<#27800#><#65246#>, would always be a function that consumes two numbers and produces a Boolean value. If, in the past, we had been asked to write a contract for <#65247#><#27801#>rel-op<#27801#><#65247#>, we would have written
<#71317#>;; <#65248#><#27806#>rel-op<#27806#> <#27807#>:<#27807#> <#27808#>number<#27808#> <#27809#>number<#27809#> <#27810#><#27810#><#27811#>-;SPMgt;<#27811#><#27812#><#27812#> <#27813#>boolean<#27813#><#65248#><#71317#>
Considering that functions and primitive operations are values, this contract says that an arrow symbol, <#65249#><#27817#><#27817#><#27818#>-;SPMgt;<#27818#><#27819#><#27819#><#65249#>, describes a class of values: functions and primitive operations. The names on the left of <#65250#><#27820#><#27820#><#27821#>-;SPMgt;<#27821#><#27822#><#27822#><#65250#> specify what each value in the class of functions must be applied to; the name on the right says what each value is going to produce if it is applied to proper values. In general, we say that
<#27827#>(A<#27827#> <#27828#>B<#27828#> <#27829#><#27829#><#27830#>-;SPMgt;<#27830#><#27831#><#27831#> <#27832#>C)<#27832#>
means the class of all functions and primitives that consume an element in <#65251#><#27836#>A<#27836#><#65251#> and an element in <#65252#><#27837#>B<#27837#><#65252#> and produce an element in <#65253#><#27838#>C<#27838#><#65253#>. Or more succinctly, they are functions ``from <#65254#><#27839#>A<#27839#><#65254#> and <#65255#><#27840#>B<#27840#><#65255#> to <#65256#><#27841#>C<#27841#><#65256#>.'' The arrow notation is like the <#65257#><#27842#>(listof<#27842#>\ <#27843#>...)<#27843#><#65257#> notation from the previous section. Both specify a class of data via a combination of other classes. For <#65258#><#27844#>listof<#27844#><#65258#>, we used data definitions to agree on what they mean. Others can follow the example and introduce their own abbreviations based on data definitions. For arrows, we just made an agreement, and it stays with us for good. Using the arrow notation, we can formulate a first contract and a proper purpose statement for <#65259#><#27845#>filter1<#27845#><#65259#>:
<#71318#>;; <#65260#><#27850#>filter1<#27850#> <#27851#>:<#27851#> <#27852#>(number<#27852#> <#27853#>number<#27853#> <#27854#><#27854#><#27855#>-;SPMgt;<#27855#><#27856#><#27856#> <#27857#>boolean)<#27857#> <#27858#>lon<#27858#> <#27859#>number<#27859#> <#27860#><#27860#><#27861#>-;SPMgt;<#27861#><#27862#><#27862#> <#27863#>lon<#27863#><#65260#> <#71318#>
<#71319#>;; to construct the list of those numbers <#65261#><#27864#>n<#27864#><#65261#> on <#65262#><#27865#>alon<#27865#><#65262#> for which<#71319#> 
<#71320#>;; <#65263#><#27866#>(rel-op<#27866#> <#27867#>n<#27867#> <#27868#>t)<#27868#><#65263#> evaluates to <#65264#><#27869#>true<#27869#><#65264#><#71320#> 
<#27870#>(define<#27870#> <#27871#>(filter1<#27871#> <#27872#>rel-op<#27872#> <#27873#>alon<#27873#> <#27874#>t)<#27874#> <#27875#>...)<#27875#> 
The unusual part of the contract is that it specifies the class to which the first argument must belong not with a name introduced by a data definition but with a direct data definition, using the arrow notation. More concretely, it specifies that the first argument must be a function or a primitive operation and, as discussed, what kind of arguments it consumes and what kind of value it produces.
<#27881#>Exercise 20.2.1<#27881#> Explain the following classes of functions:
  1. <#65265#><#27884#>(number<#27884#>\ <#27885#><#27885#><#27886#>-;SPMgt;<#27886#><#27887#><#27887#>\ <#27888#>boolean)<#27888#><#65265#>,
  2. <#65266#><#27889#>(boolean<#27889#>\ <#27890#>symbol<#27890#>\ <#27891#><#27891#><#27892#>-;SPMgt;<#27892#><#27893#><#27893#>\ <#27894#>boolean)<#27894#><#65266#>,
  3. <#65267#><#27895#>(number<#27895#>\ <#27896#>number<#27896#>\ <#27897#>number<#27897#>\ <#27898#><#27898#><#27899#>-;SPMgt;<#27899#><#27900#><#27900#>\ <#27901#>number)<#27901#><#65267#>,
  4. <#65268#><#27902#>(number<#27902#>\ <#27903#><#27903#><#27904#>-;SPMgt;<#27904#><#27905#><#27905#>\ <#27906#>(listof<#27906#>\ <#27907#>number))<#27907#><#65268#>, and
  5. <#65269#><#27908#>((listof<#27908#>\ <#27909#>number)<#27909#>\ <#27910#><#27910#><#27911#>-;SPMgt;<#27911#><#27912#><#27912#>\ <#27913#>boolean)<#27913#><#65269#>.~ external Solution<#65270#><#65270#>
<#27920#>Exercise 20.2.2<#27920#> Formulate contracts for the following functions:
  1. <#65271#><#27923#>sort<#27923#><#65271#>, which consumes a list of numbers and a function that consumes two numbers and produces a boolean; <#65272#><#27924#>sort<#27924#><#65272#> produces a list of numbers.
  2. <#65273#><#27925#>map<#27925#><#65273#>, which consumes a function from numbers to numbers and a list of numbers; it also produces a list of numbers.
  3. <#65274#><#27926#>project<#27926#><#65274#>, which consumes a list of lists of symbols and a function from lists of symbols to symbols; it produces a list of symbols.~ external Solution<#65275#><#65275#>
The second version of <#65276#><#27935#>filter1<#27935#><#65276#> was the result of abstracting <#65277#><#27936#>below<#27936#><#65277#> and <#65278#><#27937#>below-ir<#27937#><#65278#>. Its definition did not differ from the first version, but the process of abstracting from <#65279#><#27938#>below-ir<#27938#><#65279#> clarified that <#65280#><#27939#>filter1<#27939#><#65280#> could be applied to all kinds of lists, not just lists of numbers. To describe <#27940#>all kinds of lists<#27940#>, we use <#65281#><#27941#>(listof<#27941#>\ <#27942#>X)<#27942#><#65281#>. Here is a first attempt at a contract for <#65282#><#27943#>filter1<#27943#><#65282#>:
<#71321#>;; <#65283#><#27948#>filter1<#27948#> <#27949#>:<#27949#> <#27950#>...<#27950#> <#27951#>(listof<#27951#> <#27952#>X)<#27952#> <#27953#>number<#27953#> <#27954#><#27954#><#27955#>-;SPMgt;<#27955#><#27956#><#27956#> <#27957#>(listof<#27957#> <#27958#>X)<#27958#><#65283#> <#71321#>
The key to using <#65284#><#27962#>filter1<#27962#><#65284#> with different classes of lists is to use a comparison function that can compare the items on the list with the second argument, which is a number. That is, the first argument is a function in the class
<#27967#>(X<#27967#> <#27968#>number<#27968#> <#27969#><#27969#><#27970#>-;SPMgt;<#27970#><#27971#><#27971#> <#27972#>boolean)<#27972#>
which means it consumes an element of <#65285#><#27976#>X<#27976#><#65285#> and a number, and produces a boolean. Put together, we get the following contract for <#65286#><#27977#>filter1<#27977#><#65286#>:
<#71322#>;; <#65287#><#27982#>filter1<#27982#> <#27983#>:<#27983#> <#27984#>(X<#27984#> <#27985#>number<#27985#> <#27986#><#27986#><#27987#>-;SPMgt;<#27987#><#27988#><#27988#> <#27989#>boolean)<#27989#> <#27990#>(listof<#27990#> <#27991#>X)<#27991#> <#27992#>number<#27992#> <#27993#><#27993#><#27994#>-;SPMgt;<#27994#><#27995#><#27995#> <#27996#>(listof<#27996#> <#27997#>X)<#27997#><#65287#> <#71322#>
As in our contract for <#65288#><#28001#>length<#28001#><#65288#>, <#65289#><#28002#>X<#28002#><#65289#> here stands for an arbitrary collection of Scheme data. We can replace it with anything, as long as all three occurrences are replaced by the same thing. Hence, by using <#65290#><#28003#>X<#28003#><#65290#> in both the description of the first parameter, the second one, and the result, we ensure that <#65291#><#28004#>rel-op<#28004#><#65291#> consumes elements of <#65292#><#28005#>X<#28005#><#65292#>, which are the items on the second argument and that furthermore the result of <#65293#><#28006#>filter1<#28006#><#65293#> is a list that contains <#65294#><#28007#>X<#28007#><#65294#>s. When we wish to apply <#65295#><#28008#>filter1<#28008#><#65295#>, we must check that the arguments make sense. Consider we wish to evaluate
<#28013#>(filter1<#28013#> <#28014#>;SPMlt;<#28014#> <#28015#>(list<#28015#> <#28016#>3<#28016#> <#28017#>8<#28017#> <#28018#>10)<#28018#> <#28019#>2)<#28019#>
Before we do that, we should confirm that <#65296#><#28023#>filter1<#28023#><#65296#> can indeed consume <#65297#><#28024#>;SPMlt;<#28024#><#65297#> and <#65298#><#28025#>(list<#28025#>\ <#28026#>3<#28026#>\ <#28027#>8<#28027#>\ <#28028#>10)<#28028#><#65298#>, given its contract. A quick check shows that <#65299#><#28029#>;SPMlt;<#28029#><#65299#> makes sense because it belongs to the class
<#28034#>(number<#28034#> <#28035#>number<#28035#> <#28036#><#28036#><#28037#>-;SPMgt;<#28037#><#28038#><#28038#> <#28039#>boolean)<#28039#>
and <#65300#><#28043#>(list<#28043#>\ <#28044#>3<#28044#>\ <#28045#>8<#28045#>\ <#28046#>10)<#28046#><#65300#> makes sense because it belongs to
<#28051#>(listof<#28051#> <#28052#>number)<#28052#>
The two classes are identical to the first two argument parts of <#65301#><#28056#>filter1<#28056#><#65301#>'s contract if <#65302#><#28057#>X<#28057#><#65302#> is replaced by <#65303#><#28058#>number<#28058#><#65303#>. More generally, to ensure that arguments make sense, we must find replacements of the variables in contracts so that the functions contract and the classes of the arguments match. For a second example, consider
<#28063#>(filter1<#28063#> #tex2html_wrap_inline73316# <#28065#>LOIR<#28065#> <#28066#>10)<#28066#>
Here, we must replace <#65304#><#28070#>X<#28070#><#65304#> with <#65305#><#28071#>IR<#28071#><#65305#>, because <#65306#>#tex2html_wrap_inline73318#<#65306#> has the contract
<#28077#>(IR<#28077#> <#28078#>number<#28078#> <#28079#><#28079#><#28080#>-;SPMgt;<#28080#><#28081#><#28081#> <#28082#>boolean)<#28082#>
and <#65307#><#28086#>LOIR<#28086#><#65307#> belongs to <#65308#><#28087#>(listof<#28087#>\ <#28088#>IR)<#28088#><#65308#>. Again, the application is legitimate because all the arguments belong to the required collections of data. Let us look at one more example: the use of <#65309#><#28089#>filter1<#28089#><#65309#> to extract all toys with the same name from a list of inventory records:
<#71323#>;; <#65310#><#28094#>find<#28094#> <#28095#>:<#28095#> <#28096#>(listof<#28096#> <#28097#>IR)<#28097#> <#28098#>symbol<#28098#> <#28099#><#28099#><#28100#>-;SPMgt;<#28100#><#28101#><#28101#> <#28102#>(listof<#28102#> <#28103#>IR)<#28103#><#65310#><#71323#>
<#28104#>(d<#28104#><#28105#>efine<#28105#> <#28106#>(find<#28106#> <#28107#>aloir<#28107#> <#28108#>t)<#28108#> 
  <#28109#>(filter1<#28109#> <#28110#>eq-ir?<#28110#> <#28111#>aloir<#28111#> <#28112#>t))<#28112#> 
<#71324#>;; <#65311#><#28113#>eq-ir?<#28113#> <#28114#>:<#28114#> <#28115#>IR<#28115#> <#28116#>symbol<#28116#> <#28117#><#28117#><#28118#>-;SPMgt;<#28118#><#28119#><#28119#> <#28120#>boolean<#28120#><#65311#><#71324#> 
<#28121#>(d<#28121#><#28122#>efine<#28122#> <#28123#>(eq-ir?<#28123#> <#28124#>ir<#28124#> <#28125#>p)<#28125#> 
  <#28126#>(symbol=?<#28126#> <#28127#>(ir-name<#28127#> <#28128#>ir)<#28128#> <#28129#>p))<#28129#> 
It is straightforward to check with examples that the function works properly. Our task here is to understand how this agrees with <#65312#><#28133#>filter1<#28133#><#65312#>'s contract. The obvious problem is that the ``threshold'' argument is a symbol, not a number. The use of <#65313#><#28134#>filter1<#28134#><#65313#> is therefore in conflict with its current contract. To overcome this deficiency, we must introduce another variable, say <#65314#><#28135#>TH<#28135#><#65314#> for thresholds, that stands for some collection of data:
<#71325#>;; <#65315#><#28140#>filter1<#28140#> <#28141#>:<#28141#> <#28142#>(X<#28142#> <#28143#>TH<#28143#> <#28144#><#28144#><#28145#>-;SPMgt;<#28145#><#28146#><#28146#> <#28147#>boolean)<#28147#> <#28148#>(listof<#28148#> <#28149#>X)<#28149#> <#28150#>TH<#28150#> <#28151#><#28151#><#28152#>-;SPMgt;<#28152#><#28153#><#28153#> <#28154#>(listof<#28154#> <#28155#>X)<#28155#><#65315#> <#71325#>
Now we can replace <#65316#><#28159#>X<#28159#><#65316#> with the name of one data collection and <#65317#><#28160#>TH<#28160#><#65317#> with that of a second one or possibly the same. In particular, the application
<#28165#>(filter1<#28165#> <#28166#>eq-ir?<#28166#> <#28167#>LOIR<#28167#> <#28168#>'<#28168#><#28169#>doll)<#28169#>
works because a replacement of <#65318#><#28173#>X<#28173#><#65318#> by <#65319#><#28174#>IR<#28174#><#65319#> and <#65320#><#28175#>TH<#28175#><#65320#> by symbol in <#65321#><#28176#>filter1<#28176#><#65321#>'s contract shows that the arguments are legitimate.
<#28179#>Exercise 20.2.3<#28179#> Use <#65322#><#28181#>filter1<#28181#><#65322#> to develop a function that consumes a list of symbols and extracts all those that are <#28182#> not<#28182#> equal to <#65323#><#28183#>'<#28183#><#28184#>car<#28184#><#65323#>. Give <#65324#><#28185#>filter1<#28185#><#65324#>'s corresponding contract.~ external Solution<#65325#><#65325#> <#28191#>Exercise 20.2.4<#28191#> Formulate <#28193#> general<#28193#> contracts for the following functions:
  1. <#65326#><#28195#>sort<#28195#><#65326#>, which consumes a list and a function that consumes two items from the list and produces a boolean; it produces a list of numbers.
  2. <#65327#><#28196#>map<#28196#><#65327#>, which consumes a function from list items to <#65328#><#28197#>X<#28197#><#65328#>s and a list; it produces a list of <#65329#><#28198#>X<#28198#><#65329#>s.
  3. <#65330#><#28199#>project<#28199#><#65330#>, which consumes a list of lists and a function from lists to <#65331#><#28200#>X<#28200#><#65331#>s; it produces a list of <#65332#><#28201#>X<#28201#><#65332#>s.
Compare with exercise~#exfancycontracts#28203>.~ external Solution<#65333#><#65333#>

<#28211#>Contracts and Types<#28211#>:\ In summary, the contracts for functions are made up of types. A <#65334#><#28212#>TYPE<#28212#><#65334#> is either

  1. a basic type such as number, symbol, boolean, or <#65335#><#28214#>empty<#28214#><#65335#>;
  2. a defined type such as <#65336#><#28215#>inventory-record<#28215#><#65336#>, <#65337#><#28216#>list-of-numbers<#28216#><#65337#>, or <#65338#><#28217#>family-tree<#28217#><#65338#>;
  3. a function type such as <#65339#><#28218#>(number<#28218#>\ <#28219#><#28219#><#28220#>-;SPMgt;<#28220#><#28221#><#28221#>\ <#28222#>number)<#28222#><#65339#> or <#65340#><#28223#>(boolean<#28223#>\ <#28224#><#28224#><#28225#>-;SPMgt;<#28225#><#28226#><#28226#>\ <#28227#>symbol)<#28227#><#65340#>;
  4. a parametric type, which is either a defined type or a function type with type variables.
When we wish to use a function with a parametric type, we must first find a replacement for all the variables in the function's contract so that we know the arguments belong to proper classes. If this cannot be done, we must either revise the contract or question our decision to reuse this function.~<#65341#><#65341#>