The goal of this section is to extend the interpreter of
section~#secinterpreter#21587> so that it can cope with function
applications and function definitions. In other words, the new interpreter
simulates what happens in DrScheme when we enter an expression in the
<#21588#>Interactions<#21588#> window after clicking <#21589#>Execute<#21589#>. To make
things simple, we assume that all functions in the <#21590#>Definitions<#21590#>
window consume one argument.
<#21593#>Exercise 17.7.1<#21593#>
Extend the data definition of exercise~#exschemedd#21595> so that we can
represent the application of a function to an expression. The application
should be represented as a structure with two fields. The first field
contains the name of the function, the second one the representation of the
argument expression.~ Solution<#64346#><#64346#>
A full-fledged evaluator can also deal with function definitions.
<#21601#>Exercise 17.7.2<#21601#>
Provide a structure definition and a data definition for definitions.
Recall that a function definition has three essential attributes:
the function's name,
the parameter name, and
the function's body.
This suggests the introduction of a structure with three fields. The first
two contain symbols, the last one a representation of the function's body,
which is an expression.
Translate the following definitions into Scheme values:
Make up more examples and translate them, too.~ Solution<#64352#><#64352#>
~<#64353#>These exercises are challenging. The evaluation of an application is a <#21650#>generative<#21650#> recursion and does not fit the design recipes we have seen so far. We will deal with this form of recursion in part~#partrecursion#21651>.<#64353#>
<#21652#>Exercise 17.7.3<#21652#>
Develop <#64354#><#21654#>interpret-with-one-def<#21654#><#64354#>. The function consumes (the
representation of) a Scheme expression and (the representation of) a single
function definition, <#64355#><#21655#>P<#21655#><#64355#>.
The remaining expressions from exercise~#exschemedd#21656> are interpreted
as before. For (the representation of) a variable, the function signals an
error. For an application of the function <#64356#><#21657#>P<#21657#><#64356#>,
<#64357#><#21658#>interpret-with-one-def<#21658#><#64357#>
evaluates the argument,
substitutes the value of the argument for the function parameter in the
function's body; and
evaluates the new expression via recursion. Here is a sketch of the
idea:
For all other function applications, <#64359#><#21675#>interpret-with-one-def<#21675#><#64359#> signals
an error.~ Solution<#64360#><#64360#>
<#21681#>Exercise 17.7.4<#21681#>
Develop the function <#64361#><#21683#>interpret-with-defs<#21683#><#64361#>. The function consumes (the
representation of) a Scheme expression and a list of (representations of)
function definitions, <#64362#><#21684#>defs<#21684#><#64362#>. The function produces the number that
DrScheme would produce if we were to evaluate the actual Scheme expression
in the <#21685#>Interactions<#21685#> window and if the <#21686#>Definitions<#21686#> window
contained the actual definitions.
The remaining expressions from exercise~#exschemedd#21687> are interpreted
as before. For an application of the function <#64363#><#21688#>P<#21688#><#64363#>,
<#64364#><#21689#>interpret-with-defs<#21689#><#64364#>
evaluates the argument,
looks up the definition of the function in <#64365#><#21691#>defs<#21691#><#64365#>,
substitutes the value of the argument for the function parameter in the
function's body; and
evaluates the new expression via recursion.
Like DrScheme, <#64366#><#21693#>interpret-with-defs<#21693#><#64366#> signals an error for a function
application whose function name is not on the list and for (the
representation of) a variable.~ Solution<#64367#><#64367#>