Higher-Order Programming » Lab Sessions
Session 9 (Solutions)
Assistant: Steven Keuchel (steven.keuchel@vub.be)
Section 1: Recap
Exercise 1: let*
First, expand eval
...
Then, implement let*?
and eval-let*
...
The procedure let*-loop
evaluates the expressions of the clauses sequentially
(from top-to-bottom), extending the current environment for every clause. Note
that extend-environment
expects as the first two arguments, a list of variable
names and a list of values to bind, therefore the result of evaluating a clause
must be wrapped in a list.
Section 2: Continuation Passing Style Evaluator
Exercise 2: let*
We have just implemented let*
in the basic metacircular evaluator. This time
the extension needs to be made in the CPS evaluator.
Note the difference between this solution and the other solution is that now the
result of evaluating (let*-clause expression clause)
in the env
environment
is given by evaluating the (lambda (result) ...)
procedure.
Section 3: Boolean Operators
Exercise 3: Boolean Operators
Boolean operators are special forms: since they only evaluate their arguments as
long as they need to. E.g. (or a b c)
does not need to evaluate b
and c
if
a
already evaluated to a #t
. (and a b c)
does not need to evaluate b
and
c
if a
already evaluates to #f
.
Thus there are two approaches: either we make use of syntactic sugar, or via
explicit evaluation. Note that simply transforming (or a b)
to (if a a b)
does not work, as expressions can contain side effects. E.g. if a
modifies a
variable, then it will modify it twice. This can be circumvented by caching an
evaluated expression in a variable, thus transforming (if a a b)
to (let ((e-a a)) (if e-a e-a b))
.
However, the solution in this exercise is to make use of explicit evaluation.
First, modify the definition of eval
.
Then implement and?
and eval-and
, as well as or?
and eval-or
. First
let's implement the support for and
.
The evaluation of an and
expression starts in eval-and
. It will first read
the constituent expressions of the and
expression. If there are none, it
immediately returns #t
. Otherwise, it will enter a loop to evaluate each
consituent in order until either: one of the evaluated constituent expressions
evaluates to #f
, the last constituent expression has been evaluated.
Similar for or
...
Note that difference in the definition of or-loop
. or
stops evaluating the
constituent expressions once it encounters at least one expression that
evaluated to #t
.
Exercise 4: CPS Boolean Operators
This is almost equivalent as the previous exercise, but using CPS style.
For and
:
For or
:
Note that instead of storing the result of eval
(or evaluate
) in a variable
using let
as before, it is now given by passing it to a lambda that binds the
result to a variable with the same name.