Substitution Model For Scheme Kernel
Substitution Model For Scheme Kernel
Grant I. Ho
Value?
Yes
Final Value
No
Reduce Expression
1 Formal Denitions
In designing a substitution model for the kernel of Scheme, it is necessary to dene the syntax for the functional Scheme kernel as described
in Revised4 Scheme Report [1]. The kernel syntax consists of 4 parts:
keywords, expressions, auxillaries and constants. Keywords include:
if, lambda, and letrec. Although there are only three keywords dened
in the functional kernel, extended Scheme grammar such as and, or,
begin, cond, and let, can be derived from these three essential keywords. From these keywords, Scheme expressions (denoted by N, M,
and B) can be formed: (if M N B), (lambda (<formals>) B), and (letrec (<bindings>) B). Formals and bindings are known as auxillaries.
Finally, constants consist of numerals (eg. 0, -1, 3.14159), booleans
(eg. #t, #f), and scheme-constants (eg. <<+>>, <<equal?>>, and
<<cons>> built-in procedures).
It is important to realize that the primitive procedure for addition,
+, is not a scheme-constant. Instead, it is a variable that identies the
primitive addition procedure built into the Scheme interpreter. Its associated symbol, <<+>>, is a scheme-constant because it represents
the actual addition operation. In the substitution model, variables
that represent primitive procedures have associated scheme-constants
that are dened by the programmer in the initial-global-environment
and enclosed between pointed brackets, <<>>.
Two types of values exist in the Scheme kernel: basic values and letrec values. A basic value is the set of numerals, booleans, schemeconstants, and lambda values: (lambda (<variable>) value). Letrec
values have the form: (letrec ((x1 basic-value1 ) (x2 basic-value2 ) (x3
basic-value3 )) value) [4]. Any expression that is not a value is reduced
by the rules of substitution model.
The main evaluation loop contains the kernel-eval and left-reduce procedures. Kernel-eval is the top-level evaluation loop that passes a Scheme
expression entered by the user, performs a top-level-garbage-collect on
the expression, and checks to see if the new expression is a value. If it
1
is a value, then the expression is returned and displayed. Otherwise, minimum number of suxes. The result is a cleaner expression that
the model returns the garbage-collected expression to the left-reduce can be more easily understood by the user.
The following example illustrates the substitution model in action
procedure for a one-step reduction. Left-reduce takes the garbagecollected expression and the initial-global-environment as arguments, on a simple Scheme expression:
checks the expression for its type, and returns the expression, based
User enters:
on type, to a specic reduction procedure. An expression continues to
(kernel-eval '(if (>2 1)
be left-reduced by one step until a value is returned.
((lambda (x y) (+ x y)) 3 4)
(+ 1 2))
2.1.3 Rewrite Rules
Substitution model returns:
== (0) ==>
There are ve main reduction procedures in the substitution
(if (> 2 1) ((lambda (x y) (+ x y)) 3 4) (+ 1 2))
model: reduce-if, reduce-letrec, reduce-lambda, reduce-inits, and reducecombination. Reduce-combination reduces expression combinations or
== (1) ==>
user-dened procedures applied to their arguments (eg. (+ 1 2 3) or
(if (<< > >> 2 1) ((lambda (x y) (+ x y)) 3 4) (+ 1 2))
(factorial 5), where factorial is dened with a letrec expression). All
== (2) ==>
reduction procedures in the substitution model employ the same idea
(if #t ((lambda (x y) (+ x y)) 3 4) (+ 1 2))
in rewriting to a new expression. The car, or leftmost element of a
given expression, is rst left-reduced by one step, and continues to be
== (3) ==>
reduced by only one step until it becomes a value. Then, left-reduce
((lambda (x y) (+ x y)) 3 4)
is called on the cdr of that expression such that the leftmost element
== (4) ==>
of the new subexpression is left-reduced, again by one step, until it
(letrec ((x 3) (y 4)) (+ x y))
becomes a value. The process continues until all elements in the original expression have become values or until a single evaluation of the
== (5) ==>
expression can take place according to expression-type [1].
(letrec ((x 3) (y 4)) (<< + >> x y))
To evaluate an expression or subexpression whose elements contain
== (6) ==>
all values, left-reduce calls a procedure named apply-proc. Apply-proc
(letrec ((y 4)) (<< + >> 3 y))
nds the primitive operator, in the lookup-table, that corresponds to
the car of the expression to be evaluated, and applies that built-in
== (7) ==>
operator to the cdr of the expression. This step returns a value for the
(<< + >> 3 4)
expression.
== (8) ==>
7
;Value; done
2.1.4 Garbage Collection
In the zeroth step, top-level garbage-collection takes place on the
The addition of a top-level-garbage-collect procedure to the main evaluation loop maps a generic garbage-collect procedure to the cdr of a given entire if expression and all overlapping variable names are enforced
expression, thereby forcing all subexpressions to be garbage-collected with fresh suxes. In the rst step, the variable > becomes instantibefore reduction takes place. The garbage-collect procedure, which ated with its kernel scheme-constant, << > >>, as dened in the
takes a letrec expression as an argument, ensures the removal of all initial-global-environment. Since the test of the if expression contains
bindings whose variables have already been instantiated into the body all values, apply-proc is called on the test expression which evaluates
the consequent of the if expression is returned as dened
of the letrec expression, and hence have no more bound occurences [4]. to #t. Thus,
To identify such variables, an auxillary procedure named free-variables in Revised4 Scheme [1]. In the fourth step, the lambda expression is
was dened. The strategy behind a top-level garbage-collection was desugared into a letrec expression by the rules of the reduce-lambda
returning a simpler expression to left-reduce and hence, providing a procedure and in the fth step, the variable + becomes instantiated
faster and more ecient substitution model. Garbage-collection in with its <<+>>. In the sixth step, the letrec init, (y 4), is garbagecollected since it is no longer has an occurence in the body of the
general, also returns cleaner and neater expressions to the user.
expression. The body of letrec, (<< + >> 3 4) is returned, and apply
-proc applies the primitive addition operator found in the lookup-table
to the operands, 3 and 4. A nal value of 7 is returned.
2.1.5 Variable Renaming
Two complementary variable-renaming procedures are dened in the
substitution model: enforce and relax. The enforce procedure takes a
letrec expression and adds a fresh sux number, starting from 1, to
the ends of all variables of the same name found in that expression. [1] Harold Abelson et al. Revised4 Report on the Algorithmic LanFor example, in the expression, (letrec ((x 1)) (+ x (letrec ((x 2)) x))),
guage Scheme. MIT Articial Intelligence Laboratory, November
the binding-variable x has two occurences, one nested inside the other
1991. A.I. Memo No. 848.
letrec. Thus, enforcing the expression returns (letrec ((x#1 1)) (+ x#1
(letrec ((x#2 2)) x#2))), where the variable x has been enforced to x#1 [2] Harold Abelson and Gerald J. Sussman with Julie Sussman. Structure and Interpretation of Computer Programs. MIT Press, Camin the outer letrec and x#2 for the inner letrec. The purpose behind
bridge, MA, 1985.
enforcing an expression is to avoid the possibility of variable-name
clashing. Since a letrec expression can be dened to contain nested [3] Matthias Felleisen and Robert Hieb. The revised report on the
letrecs and the use of the same variable more than once, enforcing an
syntactic theories of sequential control and state. Theoretical Comexpression at the top-level ensures that variables of the same name
puter Science 103:235-271, 1992.
(with dierent bindings) have dierent suxes . This avoids potential [4] Albert R. Meyer. A Substitution Model Draft for Scheme: Formal
errors in variable instantiation.
Denitions. MIT Laboratory for Computer Science, February 1994.
Relax works opposite to the enforce procedure. After the end of
the reduction process, relax takes the expression, which has already [5] Albert R. Meyer. User's Guide for the Substitution Model. MIT
Laboratory for Computer Science, April 1994.
been enforced and garbage-collected, and returns an expression with
free variables untouched and all bounded variables renamed with the
References