Extended Exercise: Evaluating Scheme, Part 2

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.~ external 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:
  1. the function's name,
  2. the parameter name, and
  3. 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:
  1. <#64347#><#21606#>(define<#21606#>\ <#21607#>(f<#21607#>\ <#21608#>x)<#21608#>\ <#21609#>(+<#21609#>\ <#21610#>3<#21610#>\ <#21611#>x))<#21611#><#64347#>
  2. <#64348#><#21612#>(define<#21612#>\ <#21613#>(g<#21613#>\ <#21614#>x)<#21614#>\ <#21615#>(*<#21615#>\ <#21616#>3<#21616#>\ <#21617#>x))<#21617#><#64348#>
  3. <#64349#><#21618#>(define<#21618#>\ <#21619#>(h<#21619#>\ <#21620#>u)<#21620#>\ <#21621#>(f<#21621#>\ <#21622#>(*<#21622#>\ <#21623#>2<#21623#>\ <#21624#>u)))<#21624#><#64349#>
  4. <#64350#><#21625#>(define<#21625#>\ <#21626#>(i<#21626#>\ <#21627#>v)<#21627#>\ <#21628#>(+<#21628#>\ <#21629#>(*<#21629#>\ <#21630#>v<#21630#>\ <#21631#>v)<#21631#>\ <#21632#>(*<#21632#>\ <#21633#>v<#21633#>\ <#21634#>v)))<#21634#><#64350#>
  5. <#64351#><#21635#>(define<#21635#>\ <#21636#>(k<#21636#>\ <#21637#>w)<#21637#>\ <#21638#>(*<#21638#>\ <#21639#>(h<#21639#>\ <#21640#>w)<#21640#>\ <#21641#>(i<#21641#>\ <#21642#>w)))<#21642#><#64351#>
Make up more examples and translate them, too.~ external Solution<#64352#><#64352#> external ~<#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#>
  1. evaluates the argument,
  2. substitutes the value of the argument for the function parameter in the function's body; and
  3. evaluates the new expression via recursion. Here is a sketch of the idea:
    <#21665#>(interpret-with-one-def<#21665#> <#21666#>(substitute<#21666#> <#21667#>val-of-arg<#21667#> <#21668#>fun-para<#21668#> <#21669#>fun-body)<#21669#>
                            <#21670#>a-fun-def)<#21670#> 
    
For all other function applications, <#64359#><#21675#>interpret-with-one-def<#21675#><#64359#> signals an error.~ external 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#>
  1. evaluates the argument,
  2. looks up the definition of the function in <#64365#><#21691#>defs<#21691#><#64365#>,
  3. substitutes the value of the argument for the function parameter in the function's body; and
  4. 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.~ external Solution<#64367#><#64367#>