Unfortunately, value-i3
doesn't work because (operator-i nexp)
returns a symbol, not a procedure object. Notice the difference between '+
and +
?
There's not really an easy way to get around that (if we rule out eval
, which is gross and disrecommended), other than using an alist to link the symbol with the procedure (or using case
or cond
as mentioned in Sylwester's answer):
(define symbol->procedure
(let ((opmap `((+ ,+)
(x ,x)
(^ ,^))))
(lambda (x)
(cond ((assq x opmap) => cadr)
(else #f)))))
Then use symbol->procedure
the same way as Sylwester's answer.
If you find quasiquotes too difficult to read, you can use list
and cons
directly;
(define symbol->procedure
(let ((opmap (list (cons '+ +)
(cons 'x x)
(cons '^ ^))))
(lambda (x)
(cond ((assq x opmap) => cdr)
(else #f)))))
The OP asked for more information about assq
and the like, so I thought I'd update the post directly. Basically, (assoc key alist)
returns the first item in alist
whose car
is equal?
to key
, or #f
otherwise; assq
and assv
are similar to assoc
but use eq?
and eqv?
as the comparison operator. So, here's a sample implementation (with R7RS/SRFI-1 semantics):
(define (find pred lst)
(cond ((null? lst) #f)
((pred (car lst)) (car lst))
(else (find pred (cdr lst)))))
(define assoc
(case-lambda
((key alist equal?)
(find (lambda (x)
(equal? key (car x)))
alist))
((key alist)
(assoc key alist equal?))))
(define (assq key alist)
(assoc key alist eq?))
(define (assv key alist)
(assoc key alist eqv?))