I didn't really want to get involved in this kind of discussion but I need to 
take exception to this kind of statement. 

Code is not just written. Code is read. Code is read far more often than 
written. Code that uses a specific construct conveys a specific idea, and it 
thus helps the reader figure out what the point is. Code that uses a general 
tool for a specific purpose obstructs understanding, and it is thus bad. 

Racket provides general constructs because some situations call for their use. 
If a programmer carefully selects such a construct for a general situation, the 
code signals to any reader that a lot of care is needed to understand all the 
ramifications behind this point in the program. 

-- Matthias




On Aug 4, 2015, at 12:04 PM, Sean Kanaley <skana...@gmail.com> wrote:

> " I cannot think of any good uses for eval in Racket."
> 
> Any time the mental time spent using eval (or defmacro) is less than that of 
> figuring out how to not use eval or defmacro by using 
> let-parameterize-syntax-splicing-local-transformer-binding-apply-values 
> instead, which for the average programmer is probably always. Programming in 
> perfect Racket (or any language) is like finding the optimal solution to the 
> traveling salesman, or finding a large prime with 100% certainty. You are 
> spending disproportionate efforts for the ~same result. If I have a square 
> peg that has to go into a round hole, I can just apply a lot of force rather 
> than going to the store and buying a new peg. How bad this result is depends 
> on how gigantic the wall is that suffered the damage. A big enough program 
> will be sufficiently buggy that a clear use of eval is probably no big deal, 
> e.g.
> 
> <millions of lines of code>
> (define (launch-nukes target)
>   (for ([i 10])
>      (launch 'nuke 'civilian)))
> <millions of lines of code>
> (define (confirmation target)
>   (eval '(printf "Are you sure you wish to nuke ~a?" target) namespace)
>   ...)
> 
> To a purist, the above code is horrifying.
> 
> 
> On Tue, Aug 4, 2015 at 10:34 AM, Alexis King <lexi.lam...@gmail.com> wrote:
> > 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.
> 
> 
> -- 
> 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.

-- 
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