> I don't know why but at some point in the 20th century people really became 
> afraid of viewing programs as pure data (which they are) and started to call 
> it metacircular (which of course also refers to other properties of a list 
> processor treating each and every start of list, i.e. opening parenthese, as 
> an apply instruction).

*sigh* Okay, I’ll bite.

I think I can understand the appeal of wanting to love eval. It’s a Lisp 
tradition to have it, and indeed, it is still one of the first things that 
people mention when describing how Lisps are different from other languages. 
Turning around and admitting that one of our signature features should be 
avoided is not only confusing, it seems to reduce Lisp back to the level of any 
other language. If eval is out, what makes Lisps special anymore?

So of course it can seem freeing to come to the conclusion that all those 
people warning about eval are just “afraid of its power”, and we have so much 
to gain by “rediscovering” this tool, but that’s not really true. Eval may not 
be evil, but I’d consider it one of the worst possible code smells. I cannot 
think of any good uses for eval in Racket.

> One the one hand I reject any security concerns about eval which is as good 
> or bad as input data as are the key codes from your favorite event handling 
> loop determining your programs actions. A simple (send object message 
> arguments) could be implemented by evaluating message in the environment of 
> object, i.e. applying it to the arguments. The use of eval shouldn't be 
> restricted to proclaimed  designers of algorithmic notations but using it 
> correctly needs some understanding of Scheme and its specifications. That 
> necessary knowledge used to be conveyed in a lecture of one semester at the 
> MIT with SICP (I've read).

The argument that all (interesting) programs are input-driven, but to then draw 
the conclusion that eval is no more dangerous than other methods of input 
processing would be quite the fallacy. But I agree with some other people in 
this thread that it isn’t really explained why eval is bad, and really, I’ve 
never read an explanation that has wholly satisfied me.

I don’t think the real reason for spurning eval is to avoid security problems 
or to handle code evaluation in different contexts (though both of those things 
are highly related to the “core” problem with eval). I’d argue that the problem 
with eval is one of abstraction: eval is barely any better than writing 
directly to the underlying runtime or virtual machine.

Scheme is largely derived from one of the most powerful abstractions in the 
history of computer science, the closure. It goes by plenty of names, but the 
reason I pick “closure” is that it indicates precisely why the construct is far 
superior to eval: it keeps its context with it. When you pass closures around 
in code, they maintain the collection of values from their original scope, and 
when you call a closure, you can’t get at the values in the calling scope. 
Closures are more or less reified eval.

As programmers, it is incredibly important to have the guarantees that closures 
provide because that allows us to abstract upon them. We can go higher-order, 
and in doing so, it is possible to create entire DSLs without even so much as a 
macro system. Doing that with eval is almost impossible because eval is not 
*composable*. The solution is not “an eval that carries around its lexical 
context” because then you have pretty much reinvented closures.

So what was the original title of this thread again? Oh right, “Sending 
Closures to Places”. Obviously in that case, our nice little closure 
abstraction has failed us. Why? Because that context can’t be serialized in the 
general case. Dropping down into eval is throwing *everything* away, which may 
seem simpler, but it also means eschewing any level of abstraction that system 
was already giving you. This is a time when designing a domain-specific 
solution will almost certainly be better than just whipping out eval on a whim 
because our abstraction failed us.

And that, I think, is the problem: eval seems a lot like a “one size fits all” 
approach to problem solving. Need dynamism? Bash it with eval! But we have so 
many tools far better suited to the job without the pitfalls and problems of 
eval (all of which are built on top of it, in a sense). Need dynamic behavior 
at runtime? We have procedures. Need that behavior to be encapsulated into a 
first-class value? We have closures. Need to generate code itself at 
compile-time? We have hygienic macros (and I mention “hygienic” here very 
specifically—I leave figuring out why as an exercise to the reader).

We write in high-level languages for a reason. There’s no reason to stunt their 
ability to abstract by directly calling eval.

Alexis

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to