<#6031#>(define-struct<#6031#> <#6032#>posn<#6032#> <#6033#>(x<#6033#> <#6034#>y))<#6034#> <#6035#>(define-struct<#6035#> <#6036#>star<#6036#> <#6037#>(last<#6037#> <#6038#>first<#6038#> <#6039#>dob<#6039#> <#6040#>ssn))<#6040#> <#6041#>(define-struct<#6041#> <#6042#>airplane<#6042#> <#6043#>(kind<#6043#> <#6044#>max-speed<#6044#> <#6045#>max-load<#6045#> <#6046#>price))<#6046#>Then, Scheme also knows the following three predicates:
A <#61469#><#6099#>pixel-2<#6099#><#61469#> is eitherStating the contract, purpose, and header is straightforward:
- a <#61470#><#6101#>number<#6101#><#61470#>, or
- a <#61471#><#6102#>posn<#6102#><#61471#> structure.
<#70781#>;; <#61472#><#6109#>distance-to-0<#6109#> <#6110#>:<#6110#> <#6111#>pixel-2<#6111#> <#6112#><#6112#><#6113#>-;SPMgt;<#6113#><#6114#><#6114#> <#6115#>number<#6115#><#61472#><#70781#> <#70782#>;; to compute the distance of <#61473#><#6116#>a-pixel<#6116#><#61473#> to the origin<#70782#> <#6117#>(define<#6117#> <#6118#>(distance-to-0<#6118#> <#6119#>a-pixel)<#6119#> <#6120#>...)<#6120#>As mentioned before, the function must distinguish among its two kinds of inputs, which can be accomplished with a <#61474#><#6124#>cond<#6124#>-expression<#61474#>:
<#6129#>(d<#6129#><#6130#>efine<#6130#> <#6131#>(distance-to-0<#6131#> <#6132#>a-pixel)<#6132#> <#6133#>(c<#6133#><#6134#>ond<#6134#> <#6135#>[<#6135#><#6136#>(number?<#6136#> <#6137#>a-pixel)<#6137#> <#6138#>...]<#6138#> <#6139#>[<#6139#><#6140#>(posn?<#6140#> <#6141#>a-pixel)<#6141#> <#6142#>...]<#6142#><#6143#>))<#6143#>The two conditions correspond to the two possible inputs of the new <#61475#><#6147#>distance-to-0<#6147#><#61475#> function. If the first one holds, the input is a pixel on the x-axis. Otherwise the pixel is a <#61476#><#6148#>posn<#6148#><#61476#> structure. For the second <#61477#><#6149#>cond<#6149#><#61477#>-line, we also know that the input contains two items: the <#6150#>x<#6150#> and <#6151#>y<#6151#> coordinates. To remind ourselves, we annotate the template with two selector expressions:
<#6156#>(d<#6156#><#6157#>efine<#6157#> <#6158#>(distance-to-0<#6158#> <#6159#>a-pixel)<#6159#> <#6160#>(c<#6160#><#6161#>ond<#6161#> <#6162#>[<#6162#><#6163#>(number?<#6163#> <#6164#>a-pixel)<#6164#> <#6165#>...]<#6165#> <#6166#>[<#6166#><#6167#>(posn?<#6167#> <#6168#>a-pixel)<#6168#> <#6169#>...<#6169#> <#6170#>(posn-x<#6170#> <#6171#>a-pixel)<#6171#> <#6172#>...<#6172#> <#6173#>(posn-y<#6173#> <#6174#>a-pixel)<#6174#> <#6175#>...<#6175#> <#6176#>]<#6176#><#6177#>))<#6177#>Completing the function is easy. If the input is a number, it <#6181#>is<#6181#> the distance to the origin. If it is a structure, we use the old formula for determining the distance to the origin:
<#6186#>(d<#6186#><#6187#>efine<#6187#> <#6188#>(distance-to-0<#6188#> <#6189#>a-pixel)<#6189#> <#6190#>(c<#6190#><#6191#>ond<#6191#> <#6192#>[<#6192#><#6193#>(number?<#6193#> <#6194#>a-pixel)<#6194#> <#6195#>a-pixel]<#6195#> <#6196#>[<#6196#><#6197#>(posn?<#6197#> <#6198#>a-pixel)<#6198#> <#6199#>(s<#6199#><#6200#>qrt<#6200#> <#6201#>(+<#6201#> <#6202#>(square<#6202#> <#6203#>(posn-x<#6203#> <#6204#>a-pixel))<#6204#> <#6205#>(square<#6205#> <#6206#>(posn-y<#6206#> <#6207#>a-pixel))))]<#6207#><#6208#>))<#6208#>Let us consider a second example. Suppose we are to write functions that deal with geometric shapes. One function might have to compute the area covered by a shape, another one the perimeter, and a third could draw the shape. For the sake of simplicity, let's assume that the class of shapes only includes squares and circles and that their description includes their location (a <#61478#><#6212#>posn<#6212#><#61478#>) and their size (a <#61479#><#6213#>number<#6213#><#61479#>).
<#6219#>(define-struct<#6219#> <#6220#>square<#6220#> <#6221#>(nw<#6221#> <#6222#>length<#6222#><#6223#>))<#6223#> <#6224#>(define-struct<#6224#> <#6225#>circle<#6225#> <#6226#>(center<#6226#> <#6227#>radius))<#6227#>and the matching data definition:
A <#61480#><#6232#>shape<#6232#><#61480#> is eitherTogether, the two classes make up the class of shapes: The next step of our design recipe requires that we make up examples. Let's start with input examples:
- a circle structure:
<#70783#><#61481#><#6234#>(make-circle<#6234#>\ <#6235#>p<#6235#>\ <#6236#>s)<#6236#><#61481#><#70783#> where <#61482#><#6237#>p<#6237#><#61482#> is a <#61483#><#6238#>posn<#6238#><#61483#> and <#61484#><#6239#>s<#6239#><#61484#> is a number; or
- a square structure:
<#70784#><#61485#><#6240#>(make-square<#6240#>\ <#6241#>p<#6241#>\ <#6242#>s)<#6242#><#61485#><#70784#> where <#61486#><#6243#>p<#6243#><#61486#> is a <#61487#><#6244#>posn<#6244#><#61487#> and <#61488#><#6245#>s<#6245#><#61488#> is a number.
<#70785#>;; <#61498#><#6276#>perimeter<#6276#> <#6277#>:<#6277#> <#6278#>shape<#6278#> <#6279#><#6279#><#6280#>-;SPMgt;<#6280#><#6281#><#6281#> <#6282#>number<#6282#><#61498#><#70785#> <#70786#>;; to compute the perimeter of <#61499#><#6283#>a-shape<#6283#><#61499#><#70786#> <#6284#>(d<#6284#><#6285#>efine<#6285#> <#6286#>(perimeter<#6286#> <#6287#>a-shape)<#6287#> <#6288#>(c<#6288#><#6289#>ond<#6289#> <#6290#>[<#6290#><#6291#>(square?<#6291#> <#6292#>a-shape)<#6292#> <#6293#>...<#6293#> <#6294#>]<#6294#> <#6295#>[<#6295#><#6296#>(circle?<#6296#> <#6297#>a-shape)<#6297#> <#6298#>...<#6298#> <#6299#>]<#6299#><#6300#>))<#6300#>because the function must first determine to which class <#61500#><#6304#>a-shape<#6304#><#61500#> belongs. Furthermore, each possible input is a structure, so we can also add two selector expressions to each <#61501#><#6305#>cond<#6305#><#61501#>-clause:
<#70787#>;; <#61502#><#6310#>perimeter<#6310#> <#6311#>:<#6311#> <#6312#>shape<#6312#> <#6313#><#6313#><#6314#>-;SPMgt;<#6314#><#6315#><#6315#> <#6316#>number<#6316#><#61502#><#70787#> <#70788#>;; to compute the perimeter of <#61503#><#6317#>a-shape<#6317#><#61503#><#70788#> <#6318#>(d<#6318#><#6319#>efine<#6319#> <#6320#>(perimeter<#6320#> <#6321#>a-shape)<#6321#> <#6322#>(c<#6322#><#6323#>ond<#6323#> <#6324#>[<#6324#><#6325#>(square?<#6325#> <#6326#>a-shape)<#6326#> <#6327#>...<#6327#> <#6328#>(square-nw<#6328#> <#6329#>a-shape)<#6329#> <#6330#>...<#6330#> <#6331#>(square-length<#6331#> <#6332#>a-shape)<#6332#> <#6333#>...]<#6333#> <#6334#>[<#6334#><#6335#>(circle?<#6335#> <#6336#>a-shape)<#6336#> <#6337#>...<#6337#> <#6338#>(circle-center<#6338#> <#6339#>a-shape)<#6339#> <#6340#>...<#6340#> <#6341#>(circle-radius<#6341#> <#6342#>a-shape)<#6342#> <#6343#>...]<#6343#><#6344#>))<#6344#>The selector expressions remind us of the available data. Now we are ready to finish the definition. We fill the gaps in the two answers by translating the mathematical formulae into Scheme notation:
<#6352#>(d<#6352#><#6353#>efine<#6353#> <#6354#>(perimeter<#6354#> <#6355#>a-shape)<#6355#> <#6356#>(c<#6356#><#6357#>ond<#6357#> <#6358#>[<#6358#><#6359#>(square?<#6359#> <#6360#>a-shape)<#6360#> <#6361#>(*<#6361#> <#6362#>(square-length<#6362#> <#6363#>a-shape)<#6363#> <#6364#>4)]<#6364#> <#6365#>[<#6365#><#6366#>(circle?<#6366#> <#6367#>a-shape)<#6367#> <#6368#>(*<#6368#> <#6369#>(*<#6369#> <#6370#>2<#6370#> <#6371#>(circle-radius<#6371#> <#6372#>a-shape))<#6372#> <#6373#>pi)]<#6373#><#6374#>))<#6374#>Since the position of a shape does not affect its perimeter, the template's selector expressions for <#61504#><#6378#>nw<#6378#><#61504#> and <#61505#><#6379#>center<#6379#><#61505#> disappear.