Page 1 of 1

(eval) and (compile) considered lame?

Posted: Tue Jul 15, 2008 6:33 pm
by fogus
I have often heard that explicitly calling (eval) or (compile) explicitly is considered bad form. I can (in theory) understand the knocks against eval as outlined in On Lisp (i.e. inefficient, devoid of lexical context), but it seems to me, as an outsider, that eval and compile would be perfect for building functions programmatically (although not closures if I understand correctly). What am I missing? Is there a better way?

This is all new to me (well, re-new), so please excuse my ignorance if I am way off base.
-m

Re: (eval) and (compile) considered lame?

Posted: Wed Jul 16, 2008 6:34 am
by reuben.cornel
I don't know if I have understood your question right. Are you trying to achieve what the code below does?

Code: Select all

(defmacro increment-function-generator(function-name increment)
  "Macro that generates a function that increments its input by a specific pre-determined value"
  `(defun ,function-name(x)
    (+ x ,increment)))

(incrementor-generator increment-by-two 2)
(increment-by-two 3) => 5

Re: (eval) and (compile) considered lame?

Posted: Wed Jul 16, 2008 9:29 am
by ramarren
fogus wrote:that eval and compile would be perfect for building functions programmatically (although not closures if I understand correctly). What am I missing? Is there a better way?
Building functions programmatically is usually achieved, as reuben.cornel shown, with macros. One reason use of eval and compile is usually discouraged is that in great majority of cases one does not need to build unconstrained functions at runtime, which is where eval/compile are necessary. This leads to brittle and hard to debug code.

Also, the more or less only reason the function can be not known at compile time, and so not be constructable with a macro, is if it depends on program input, and passing, even processed, input directly to compiler is obviously a security hole, and generally asking for trouble. Much better solution is either to write an interpreter or compile to closures (see for example: http://xach.livejournal.com/131456.html), which gives tight constraints to executed code.

Re: (eval) and (compile) considered lame?

Posted: Wed Jul 16, 2008 12:07 pm
by theclapp
fogus wrote:I have often heard that explicitly calling (eval) or (compile) explicitly is considered bad form. I can (in theory) understand the knocks against eval as outlined in On Lisp (i.e. inefficient, devoid of lexical context), but it seems to me, as an outsider, that eval and compile would be perfect for building functions programmatically (although not closures if I understand correctly). What am I missing? Is there a better way?
Not lame, so much as the wrong tool for the job, usually. If you read a line from the user and want to evaluate it, by all means, use EVAL. But for creating functions at compile time or run time, usually the most appropriate tool is a macro or a function that returns a closure.

If you come from a C background, it may be hard to wrap your head around a function or a closure as a first class object, meaning you can pass it around to other functions and do stuff with it. In C, you can take the address of a function, give that to somebody else, and they can call it, but not much else. In Lisp, a closure is a piece of code with certain variables "closed over", or left over (not a good description, but the best I can think of at the moment) from the lexical context of the closure definition.

My point being, in C a function is something only the compiler knows about. In Lisp, a function is just a symbol that points to a closure, and you can make closures yourself without using EVAL or COMPILE.

Last, if you can't think of how to do what you want to do without using EVAL, do it. As you learn more Lisp, you'll figure out better ways. No harm, no foul. (Just don't do it in production code for your boss or business, 'cause there it *will* harm you. :) )