Once you have functions and function calls working properly, you can convert
+ from special forms into function values. The way
we've been doing
+ so far is to do a special check for the
at the head of a list and do the proper operations. A better way to do
it is to define a function named
+ and put it in the initial environment.
That way it's no longer a special case, it's a regular function that
gets applied the regular way.
There are many advantages to doing things this way. It simplifies the
core part of the interpreter for one. Additionally, it lets the user
pass around the
+ function as a value. If it is a special case the
user can't do that.
+ as a function
+ as a function, you need to create a function value
that the function value is getting values as its input, not expressions.
So you should be able to set up your interpreter with an environment like this:
Go through and convert everything you can into a function that is bound in the initial environment rather than a special form. Your only special forms should be:
- variable references
(if _test _then _else)
(define _var _expr)
(set! _var _expr)
(lambda (_vars...) _body)
If you keep your original
lambda-one they should remain
special forms. If you implement
let as a generalized version of
let-one then it
should also be a special form:
(let ((_var _expr) ...) _body)
Everything else should be a function value that is setup in an initial
global environment. For example,
cdr should all
be function values. You've already implemented the operations,
now you just have to reorganize them as functions in the language.
Remove special forms that don't need to be special forms and convert them into function values in the initial environment.