Hacker News new | ask | show | jobs
by KazimirMajorinc 6006 days ago
If you use eval in your program, the program will macroexpand each time it evaluates code containing macros. As even standard operators like setf are macros in CL, it will practically macroexpand each time it uses eval.

So, macros really slow down all or practically all programs containing eval. One can avoid evals, but from my point of view that means avoiding the most powerful, the most fun code=data feature in Lisp. It doesn't look good to me. So, why should one avoid eval?

"Eval is to be avoided because most of the time there are are a lot of more structured ways to do exactly the same thing." I miss the point here.

2 comments

EVAL is most of the time not needed. Why add a complication. Write simpler code. There is little need to call EVAL over and over.

Using EVAL in Newlisp and any other Lisp slows down the execution. Any compiled Lisp code will run MUCH faster than any evaluated code in Newlisp (with Fexprs, or without).

Who cares if the Newlisp interpreter is faster than the CLISP interpreter, if Newlisp is anyway many times slower than compiled code in any other Lisp? Why should I burn useless cycles with Newlisp, when a simple compiler will speed up things much more?

Right, that is the reason that there is such a huge difference between the runtime for eval between the languages. Macros do slow down eval if you are doing macro-expansion. They are complicated enough that normally you do not write (or expect) them to expand quickly. This is obvious because macros and fexprs are much different. Overall, macros can speed up your program because you are allowed to do certain calculations ahead of time, if you are clever about it.

I am not saying that you should avoid eval completely, I am just saying that it shouldn't be your only tool. And when you do use it, if you put it in a tight loop, you are probably doing something wrong.

The main alternative that comes to mind for me is function passing. There is a lot that you can do with function passing that overlaps with eval, except the function passing version will be safer and faster.

We agree that is one of the most powerful, most fun aspects of using lisp (the power is what makes it fun!). I also hope we agree that the frequency of its use should be the inverse of its power.

Macros only really slow down things when you for some unknown reason call EVAL on source code many times.

When code is running using EVAL and an interpreter, macros can be expanded once and then the expanded code is used next time. For example in a loop it is not necessary to expand a macro each time it is used.

If one needs to EVAL new code all the time, then one may ask oneself if that is really necessary. For example if one is doing some kind of genetic programming. Otherwise it is basically a programmer error to do so.

I haven't seen any convincing example where it is really needed. My Symbolics Lisp Machine (which comes out of the MacLisp tradition, which had FEXPRs) got only limited FEXPRs (can't be compiled, can only be used at the top-level). Still the developers who had extensive FEXPR experience with Maclisp, were able to write the compiler, the garbage collector, the graphics driver, the window system, the network system, compilers and interpreters for various languages, text editors, mail clients, mail servers, and much more without using FEXPRs.