Reputation: 71
In Emacs Lisp, lexical environment are represented by an alist, mapping symbols to their value. It can be passed to evaluators as a second argument of 'eval' function.
(eval '(+ 3 var)
'((var . 4)))
→ 7
However, I can't figure out how to pass functions, not variables, to the evaluator.
For example, either of the following expressions shows an error.
(eval '(func 3)
'((func . (lambda (x) (+ 4 x)))))
→ error: (void-function func)
(eval '(func 3)
'((func . (closure (t) (x) (+ 4 x)))))
→ error: (void-function func)
Any help is appreciated.
Upvotes: 2
Views: 349
Reputation: 28531
Here's how you can do it:
(defun my-eval (exp var-bindings fun-bindings)
(eval `(cl-flet ,(mapcar (lambda (x) (list (car x) `',(cdr x)))
fun-bindings)
(let ,(mapcar (lambda (x) (list (car x) `',(cdr x)))
var-bindings)
,exp))
t))
or, using eval
's builtin support for var-bindings
:
(defun my-eval (exp var-bindings fun-bindings)
(eval `(cl-flet ,(mapcar (lambda (x) (list (car x) `',(cdr x)))
fun-bindings)
,exp)
(or var-bindings t)))
[ BTW, note that it is not always true that in Emacs Lisp, lexical environment are represented by an alist: after byte-compilation, lexical variables don't have any name any more, they're stored on "the" stack and they're directly accessed via their position in the stack. ]
Upvotes: 1
Reputation: 3256
How about this :
(eval '(apply func (list 3))
'((func . (lambda (x) (+ 4 x)))))
Upvotes: 1