Extended Exercise: Evaluating Scheme

external ~<#63607#>This subsection provides first glimpse at how to implement a Scheme interpreter. Section~#secinterpreter2#17707> refines this material.<#63607#> DrScheme is itself a program, consisting of several parts. One function checks whether the definitions and expressions we wrote down are grammatical Scheme expressions. Another one evaluates Scheme expressions. With what we have learned in this section, we can now develop simple versions of these functions. Our first task is to agree on a data representation for Scheme programs. In other words, we must figure out how to represent a Scheme expression as a piece of Scheme data. This sounds unusual, but it is not difficult. Suppose we just want to represent numbers, variables, additions, and multiplications for a start. Clearly, numbers can stand for numbers and symbols for variables. Additions and multiplications, however, call for a class of compound data because they consist of an operator and two subexpressions. A straightforward way to represent additions and multiplications is to use two structures: one for additions and another one for multiplications. Here are the structure definitions:
<#17712#>(define-struct<#17712#> <#17713#>add<#17713#> <#17714#>(left<#17714#> <#17715#>right))<#17715#>
<#17716#>(define-struct<#17716#> <#17717#>mul<#17717#> <#17718#>(left<#17718#> <#17719#>right))<#17719#> 
Each structure has two components. One represents the left expression and the other one the right expression of the operation. rawhtml26 Let's look at some examples: These examples cover all cases: numbers, variables, simple expressions, and nested expressions.
<#17725#>Exercise 14.4.1<#17725#> Provide a data definition for the representation of Scheme expressions. Then translate the following expressions into representations:
  1. <#63608#><#17728#>(+<#17728#>\ <#17729#>10<#17729#>\ <#17730#>-10)<#17730#><#63608#>
  2. <#63609#><#17731#>(+<#17731#>\ <#17732#>(*<#17732#>\ <#17733#>20<#17733#>\ <#17734#>3)<#17734#>\ <#17735#>33)<#17735#><#63609#>
  3. <#63610#><#17736#>(*<#17736#>\ <#17737#>3.14<#17737#>\ <#17738#>(*<#17738#>\ <#17739#>r<#17739#>\ <#17740#>r))<#17740#><#63610#>
  4. <#63611#><#17741#>(+<#17741#>\ <#17742#>(*<#17742#>\ <#17743#>9/5<#17743#>\ <#17744#>c)<#17744#>\ <#17745#>32)<#17745#><#63611#>
  5. <#63612#><#17746#>(+<#17746#>\ <#17747#>(*<#17747#>\ <#17748#>3.14<#17748#>\ <#17749#>(*<#17749#>\ <#17750#>o<#17750#>\ <#17751#>o))<#17751#>\ <#17752#>(*<#17752#>\ <#17753#>3.14<#17753#>\ <#17754#>(*<#17754#>\ <#17755#>i<#17755#>\ <#17756#>i)))<#17756#><#63612#>~~~ external Solution<#63613#><#63613#>
A Scheme evaluator is a function that consumes a representation of a Scheme expression and produces its value. For example, the expression <#63614#><#17763#>3<#17763#><#63614#> has the value <#63615#><#17764#>3<#17764#><#63615#>, <#63616#><#17765#>(+<#17765#>\ <#17766#>3<#17766#>\ <#17767#>5)<#17767#><#63616#> has the value <#63617#><#17768#>8<#17768#><#63617#>, <#63618#><#17769#>(+<#17769#>\ <#17770#>(*<#17770#>\ <#17771#>3<#17771#>\ <#17772#>3)<#17772#>\ <#17773#>(*<#17773#>\ <#17774#>4<#17774#>\ <#17775#>4))<#17775#><#63618#> has the value <#63619#><#17776#>25<#17776#><#63619#>, <#17777#>etc<#17777#>. Since we are ignoring definitions for now, an expression that contains a variable, for example, <#63620#><#17778#>(+<#17778#>\ <#17779#>3<#17779#>\ <#17780#>x)<#17780#><#63620#>, does not have a value; after all, we do not know what the variable stands for. In other words, our Scheme evaluator should only be applied to representations of expressions that do not contain variables. We say such expressions are <#17781#>numeric<#17781#>. <#17782#>Exercise 14.4.2<#17782#> Provide a data definition for numeric expressions. Develop the function <#63621#><#17784#>numeric?<#17784#><#63621#>, which consumes (the representation of) a Scheme expression and determines whether it is numeric.~ external Solution<#63622#><#63622#> <#17790#>Exercise 14.4.3<#17790#> Develop the function <#63623#><#17792#>evaluate<#17792#><#63623#>. The function consumes (the representation of) a Scheme expression. If the expression is numeric (see exercise~#exschemenumeric#17793>), it produces the number that DrScheme would produce for the actual Scheme expression. Otherwise, it returns <#63624#><#17794#>false<#17794#><#63624#>.~ external Solution<#63625#><#63625#> When people evaluate expressions with variables, they first replace the variables with values. Also, when people evaluate an application <#63626#><#17800#>(f<#17800#><#17801#> <#17801#><#17802#>a)<#17802#><#63626#> they replace <#63627#><#17803#>f<#17803#><#63627#>'s parameter with <#63628#><#17804#>a<#17804#><#63628#> in <#63629#><#17805#>f<#17805#><#63629#>'s body. The following exercise concerns the substitution of variables with values. <#17806#>Exercise 14.4.4<#17806#> Develop the function <#63630#><#17808#>subst<#17808#><#63630#>. The function consumes (the representation of) a variable (<#63631#><#17809#>V<#17809#><#63631#>), a number (<#63632#><#17810#>N<#17810#><#63632#>), and (the representation of) a Scheme expression. It produces a structurally equivalent expression in which all occurrences of <#63633#><#17811#>V<#17811#><#63633#> are substituted by <#63634#><#17812#>N<#17812#><#63634#>.~ external Solution<#63635#><#63635#>