Programming Languages (CSC-302 99S)


Notes on Assignment 4: The Semantics of Scheme

1. The Semantics of Lambda

In the Scheme semantics, there is a formal definition for the meaning of a standard lambda expression. Explain what that definition says (including any helper functions).

The standard lambda expression reads

E[[(lambda (I*) C* E0 ]] =
   \ u k . \ s
      new s is in L then
         send
            (<
               new s | L,
               \ e* k' .
                  #e* = #I* then
                     tievals
                        (\ a* .
                           (\ u' . C[[C]] u' (E [[E0 ]] u' k'))
                           (extends u I* a*)
                        e*,
                     wrong ``wrong number of arugments''
               > in E)
            k
            (update (new s | L) unspecified s),
         wrong ``out of memory'' k

Taking it from the top:

\ u k
As a definition of E, the rule should have three parameters: an Exp (to the left of the equals), an environment (u), and an expression continuation (k).
\ s
Since we are expected to return a command continuation, which is a function from S to A, it is both valid and standard practice to make s is in S an explicit parameter of the continuation we return.
new s is in L
Is there space available to allocate a new location?
wrong ``out of memory'' k
If not, issue an error message.
send (...) k (...)
Package up the lambda expression (first parameter) and ``finish the program'' (send the packaged lambda expression to the continuation).
(update (new s | L) unspecified s)
By the way, the new continuation should work with a modified store; one in whice the location assigned to our function is now allocated and maps to the special value unspecified.
<...> in E
Create a function (a pair consisting of memory location and actual function) and treat it as an E.
new s | L
Allocate a new location. Takes advantage of the fact that every call to (new s) should return the same value (as long as we don't change s, and we haven't changed s).
\ e* k'
Every Scheme ``function'' is expected to take a sequence of evaluated expressions and a continuation as its parameters. Since a lambda expression represents a function, we need that.
#e* = #I*
This kind of lambda expression expects a fixed number of parameters. This makes sure that there are the correct number of parameters.
wrong ``wrong number of arugments''
The error that results if the comparison failed.
tievals ...
We need to tie each actual parameter to the corresponding formal parameter by (1) allocating memory in the store for each parameter and (2) updating the environment to map each formal to the corresponding memory location for the actual. The call to tievals does that (and some other things). (Note that tievals does the allocation of memory and extends does the update to the environment.)
(extends u I* a*)
Update the environment, as described above.
(\ u' . C[[C*]] u' (E [[E0 ]] u' k'))
Using the updated environment, u', created by extends, compute the meaning of the commands in the body of the lambda (C*) and execute the expression, and then continue. Note that the expression is evaluated in the same environment as the commands; this suggests that they cannot update the environment.

Looking at it another way: the meaning of a lambda is a function. That function requires a space in memory. When executed the function verifies the number of arguments (with the comparison), maps its actual parameters to its formal parameters (thereby updating the environment with extends and the store with tievals), excecutes all the statements in its body (with C[[C*]]), executes the final expression (with E[[E0 ]]), and returns the value of that expression (calling the continuation on that expression).

1a. Helper Functions

As you may have noted, the definition of lambda relies on five helper functions:

It may help us to consider these last two methods.

Answer forthcoming.

2. The Semantics of Expression Sequences

The Scheme semantics provides a definition for E*, which provides a meaning for sequences of expressions. Explain the equations that define E* and note any interesting implications.

E*[[]] = \u k . k <>
The meaning of the empty expression sequence is given by continuing with the rest of the program, using the empty sequence as a result.
E*[[E0 E]] =
The meaning of a expression sequence beginning with one expression is
\ u k
a function which requires an environment and expression continuation
E[[E0 ]] u ...
which begins by evaluating the expression in the current environment
(single (\ e0 ...))
and continues by using the value of that expression as e0 (single lets us treat it as a single value, rather than a sequence)
E*[[E*]] u ...
it next evaluates the rest of the sequence, in the same environment, and using these same rules
(\ e* ...)
it calls the result e*
(<e0 > & e*)
puts the value of e0 on the front
k (...)
and continues with the program.

What do we learn from all this?

3. ``Unused'' Helper Functions

A number of the helper functions from the Scheme semantics, such as cwcc, don't seem to appear in the definitions of the various meaning functions. List as many of these helper functions as you can, and explain why the semantics includes them.

Here are some of them: list, cons, less, add, car, cdr, setcar, eqv, apply, valueslist, cwcc, values, cwv

You will note that all of them have type E* -> K -> C, which is pretty close to the form of ``procedure values'' used in the report. In fact, these are definitions for the built-in procedures! cons, car, and the rest are so fundamental to Scheme that there definitions are given formally.

4. Truish

The equation that gives the meaning of conditional (if) expressions uses a helper called truish. Explain the name and purpose of truish.

The truish function returns true if its argument is not false. This permits us to use a wide variety of values as arguments to conditionals, and tells us what happens in every case (``if it's not false, it's true''). Since this is an approximate true, and not a true true, we use ``trueish'' to make it clear that it's approximate.

5. Cond Statements

Describe how the meaning of cond statements is given by the Scheme semantics, and what that meaning is.

The Scheme report uses macros to define cond; eventually, it is defined in terms of the core operations (lambda, if, and that ilk).

More details forthcoming.


Disclaimer Often, these pages were created ``on the fly'' with little, if any, proofreading. Any or all of the information on the pages may be incorrect. Please contact me if you notice errors.

This page may be found at http://www.math.grin.edu/~rebelsky/Courses/CS302/99S/Assignments/notes.04.html

Source text last modified Wed Apr 7 16:37:30 1999.

This page generated on Wed Apr 7 16:43:38 1999 by SiteWeaver. Validate this page's HTML.

Contact our webmaster at rebelsky@math.grin.edu