<#3723#>(make-posn<#3723#> <#3724#>3<#3724#> <#3725#>4)<#3725#> <#3726#>(make-posn<#3726#> <#3727#>8<#3727#> <#3728#>6)<#3728#> <#3729#>(make-posn<#3729#> <#3730#>5<#3730#> <#3731#>12)<#3731#>are <#60951#><#3735#>posn<#3735#><#60951#> structures. Each of these structures has the same status as a number as far as computations are concerned. Both primitive operations and functions can consume and produce structures. Now consider a function that computes how far some pixel is from the origin. The contract, header, and purpose statement are easy to formulate:
<#70732#>;; <#60952#><#3740#>distance-to-0<#3740#> <#3741#>:<#3741#> <#3742#>posn<#3742#> <#3743#><#3743#><#3744#>-;SPMgt;<#3744#><#3745#><#3745#> <#3746#>number<#3746#><#60952#><#70732#> <#70733#>;; to compute the distance of <#60953#><#3747#>a-posn<#3747#><#60953#> to the origin <#70733#> <#3748#>(define<#3748#> <#3749#>(distance-to-0<#3749#> <#3750#>a-posn)<#3750#> <#3751#>...)<#3751#>In other words, <#60954#><#3755#>distance-to-0<#3755#><#60954#> consumes a single value, a <#60955#><#3756#>posn<#3756#><#60955#> structure, and produces a single value, a number. We already have some input examples, namely the three <#60956#><#3757#>posn<#3757#><#60956#> structures mentioned above. What we need next are examples that relate inputs and outputs. For points with <#60957#><#3758#>0<#3758#><#60957#> as one of the coordinates, the result is the other coordinate:
<#3763#>(distance-to-0<#3763#> <#3764#>(make-posn<#3764#> <#3765#>0<#3765#> <#3766#>5))<#3766#> <#3767#>=<#3767#> <#3768#>5<#3768#> <#3769#>;and<#3769#> <#3770#>(distance-to-0<#3770#> <#3771#>(make-posn<#3771#> <#3772#>7<#3772#> <#3773#>0))<#3773#> <#3774#>=<#3774#> <#3775#>7<#3775#>In general, we know from geometry that the distance from the origin to a position with coordinates <#60958#><#3779#>x<#3779#><#60958#> and <#60959#><#3780#>y<#3780#><#60959#> is distance
Thus,
<#3786#>(distance-to-0<#3786#> <#3787#>(make-posn<#3787#> <#3788#>3<#3788#> <#3789#>4))<#3789#>
<#3790#>=<#3790#> <#3791#>5<#3791#>
<#3792#>(distance-to-0<#3792#> <#3793#>(make-posn<#3793#> <#3794#>8<#3794#> <#3795#>6))<#3795#>
<#3796#>=<#3796#> <#3797#>10<#3797#>
<#3798#>(distance-to-0<#3798#> <#3799#>(make-posn<#3799#> <#3800#>5<#3800#> <#3801#>12))<#3801#>
<#3802#>=<#3802#> <#3803#>13<#3803#>
Once we have examples, we can turn our attention to the definition of the
function. The examples imply that the design of <#60960#><#3807#>distance-to-0<#3807#><#60960#>
doesn't need to distinguish between different situations. Still, we are
stuck now, because <#60961#><#3808#>distance-to-0<#3808#><#60961#> has a single parameter that
represents the entire pixel but we need the two coordinates to compute the
distance. Put differently, we know how to combine two numbers into a
<#60962#><#3809#>posn<#3809#><#60962#> structure using <#60963#><#3810#>make-posn<#3810#><#60963#> and we don't know how to
extract these numbers from a <#60964#><#3811#>posn<#3811#><#60964#> structure.
Scheme provides operations for extracting values from
structures. <#3823#>(posn-x<#3823#> <#3824#>(make-posn<#3824#> <#3825#>7<#3825#> <#3826#>0))<#3826#>
<#3827#>=<#3827#> <#3828#>7<#3828#>
and
<#3836#>(posn-y<#3836#> <#3837#>(make-posn<#3837#> <#3838#>7<#3838#> <#3839#>0))<#3839#>
<#3840#>=<#3840#> <#3841#>0<#3841#>
The equations only confirm what we already know. But suppose we introduce
the following definition:
<#3849#>(define<#3849#> <#3850#>a-posn<#3850#> <#3851#>(make-posn<#3851#> <#3852#>7<#3852#> <#3853#>0))<#3853#>
Then we can use the two operations as follows in the <#3857#>Interactions<#3857#>
window:
<#3862#>(posn-x<#3862#> <#3863#>a-posn)<#3863#>
<#3864#>=<#3864#> <#3865#>7<#3865#>
<#3866#>(posn-y<#3866#> <#3867#>a-posn)<#3867#>
<#3868#>=<#3868#> <#3869#>0<#3869#>
Naturally, we can nest such expressions:
<#3877#>(*<#3877#> <#3878#>(posn-x<#3878#> <#3879#>a-posn)<#3879#> <#3880#>7)<#3880#>
<#3881#>=<#3881#> <#3882#>49<#3882#>
<#3883#>(+<#3883#> <#3884#>(posn-y<#3884#> <#3885#>a-posn)<#3885#> <#3886#>13)<#3886#>
<#3887#>=<#3887#> <#3888#>13<#3888#>
Now we know enough to complete the definition of <#60971#><#3892#>distance-to-0<#3892#><#60971#>. We
know that the function's <#60972#><#3893#>a-posn<#3893#><#60972#> parameter is a <#60973#><#3894#>posn<#3894#><#60973#>
structure and that the structure contains two numbers which we can extract
with <#60974#><#3895#>(posn-x<#3895#>\ <#3896#>a-posn)<#3896#><#60974#> and <#60975#><#3897#>(posn-y<#3897#>\ <#3898#>a-posn)<#3898#><#60975#>. Let us add
this knowledge to our function outline:
<#3903#>(d<#3903#><#3904#>efine<#3904#> <#3905#>(distance-to-0<#3905#> <#3906#>a-posn)<#3906#>
<#3907#>...<#3907#> <#3908#>(posn-x<#3908#> <#3909#>a-posn)<#3909#> <#3910#>...<#3910#>
<#3911#>...<#3911#> <#3912#>(posn-y<#3912#> <#3913#>a-posn)<#3913#> <#3914#>...)<#3914#>
Using this outline and the examples, the rest is easy:
<#3922#>(d<#3922#><#3923#>efine<#3923#> <#3924#>(distance-to-0<#3924#> <#3925#>a-posn)<#3925#>
<#3926#>(s<#3926#><#3927#>qrt<#3927#>
<#3928#>(+<#3928#> <#3929#>(square<#3929#> <#3930#>(posn-x<#3930#> <#3931#>a-posn))<#3931#>
<#3932#>(square<#3932#> <#3933#>(posn-y<#3933#> <#3934#>a-posn)))))<#3934#>
The function squares <#60976#><#3938#>(posn-x<#3938#>\ <#3939#>a-posn)<#3939#><#60976#> and <#60977#><#3940#>(posn-y<#3940#>\ <#3941#>a-posn)<#3941#><#60977#>,
which represent the <#3942#>x<#3942#> and <#3943#>y<#3943#> coordinates, sums up the
results, and takes the square root. With DrScheme, we can also quickly
check that our new function produces the proper results for our examples.
<#3946#>Exercise 6.1.1<#3946#>
by hand. Show all steps. Assume that <#60981#><#3968#>square<#3968#><#60981#> performs its
computation in a single step. Check the results with DrScheme's
stepper.~ Solution<#60982#><#60982#>