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?