I know that Lisp and Scheme programmers usually say that eval
should be avoided unless strictly necessary. I’ve seen the same recommendation for several program
The canonical answer is to stay away. Which I find weird, because it's a primitive, and of the seven primitives (the others being cons, car, cdr, if, eq and quote), it gets far and away the least amount of use and love.
From On Lisp: "Usually, calling eval explicitly is like buying something in an airport gift-shop. Having waited till the last moment, you have to pay high prices for a limited selection of second-rate goods."
So when do I use eval? One normal use is to have an REPL within your REPL by evaluating (loop (print (eval (read))))
. Everyone is fine with that use.
But you can also define functions in terms of macros that will be evaluated after compilation by combining eval with backquote. You go
(eval `(macro ,arg0 ,arg1 ,arg2))))
and it will kill the context for you.
Swank (for emacs slime) is full of these cases. They look like this:
(defun toggle-trace-aux (fspec &rest args)
(cond ((member fspec (eval '(trace)) :test #'equal)
(eval `(untrace ,fspec))
(format nil "~S is now untraced." fspec))
(t
(eval `(trace ,@(if args `(:encapsulate nil) (list)) ,fspec ,@args))
(format nil "~S is now traced." fspec))))
I don't think it's a filthy hack. I use it all the time myself to reintegrate macros into functions.