I'm working on a metacircular evaluator in Scheme for homework, and I need to allow the user to install special forms by adding them to a table. The idea is that, when the user enters something like (square 5)
, the evaluator will look up forms named square
. If it's found, it will return a lambda
statement, something like (lambda (x) (* x x))
.
I'm having a problem when the code returns the lambda
statement. I get the following error message:
Error: Bad function object:(lambda (x) (* x x))
The really strange part is that I can pass parameters into functions retrieved from my table, it's just that I have to previously define the procedure body as a lambda statement, not as a list that starts with lambda
For reference, here's the code that doesn't work. exp
will be something like (install-special-form 'square (lambda (x) (* x x)))
, so in this case, name
evaluates to square
and func
evaluates to (lambda (x) (* x x))
:
(define (install-eval exp)
(define name (cadadr exp))
(define func (caddr exp))
(if (special-form-lookup (list name func))
#f
(begin
(append! special-forms-table (list name func))
name)))
And here's some code that does work:
(define (install exp-list)
(append! special-forms-table exp-list))
(install (list 'square (lambda (x) (* x x))))
I'm guessing my problem is that, when using the code that doesn't work, lambda
is evaluated as a quote, rather than an actual lambda
? How can I get my user input to store an actual lambda
statement that can be retrieved and used?