Re: [racket-users] eval PSA (was Sending Closures to Places)
On 04/08/2015 16:34, Alexis King wrote: And that, I think, is the problem: eval seems a lot like a “one size fits all” approach to problem solving. ... We write in high-level languages for a reason. There’s no reason to stunt their ability to abstract by directly calling eval. I do understand that attitude of staying on top of a platform and in the high levels of a high level language. Exactly for those reasons some have written that pityful subroutine called eval and others even maintain it from time to time - just to not get your feets wet ;-) if not for a very good reason. -- 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.
Re: [racket-users] eval PSA (was Sending Closures to Places)
One example of eval being used for extremely practical purposes is with SQL. Many practical programmers regularly generate SQL strings which are then passed to a remote server, which are then evaluated. Indeed, all the same sorts of arguments against eval may be made against SQL: 1. SQL is confusing: it is executed in a completely separate environment, it breaks lexical scope, and it has a wildly different everything from the Ruby I am used to, so why should we use it? 2. SQL is vulnerable to injection attacks. The programmer must be responsible for understanding this and know how to identify and address these faults. But why should we use it given these risks? 3. Even if 1 above wasn't true in many ways, it still introduces a layer of indirection. Do we really need that? Yet, SQL seems to enjoy some success. I might say: eval is a powerful tool that requires some thoughtful consideration, and should be used judiciously. Sent from my iPhone On Aug 5, 2015, at 7:11 AM, Michael Titke michael.tied...@o2online.de wrote: On 04/08/2015 16:34, Alexis King wrote: And that, I think, is the problem: eval seems a lot like a “one size fits all” approach to problem solving. ... We write in high-level languages for a reason. There’s no reason to stunt their ability to abstract by directly calling eval. I do understand that attitude of staying on top of a platform and in the high levels of a high level language. Exactly for those reasons some have written that pityful subroutine called eval and others even maintain it from time to time - just to not get your feets wet ;-) if not for a very good reason. -- 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.
Re: [racket-users] eval PSA (was Sending Closures to Places)
Josh, right you are, that a bare statement of don't use eval can come off as unhelpful or patronizing. I'll go meta... My day job is practitioner, not professor. Among many-many nits, I'm tired of seeing bad uses of eval in real-world code. Even more than that, I'm frustrated that eval is often presented to newbies such that they think it's something they should use, leading to future real-world messes. It's the ongoing bad influence that frustrates me, not each new enthusiastic and impressionable newbie. Someone more dedicated to this particular nit than I am *could* invest a lot of time in writing checklists of criteria for when to use and not use eval. And could invest another lot of time developing a suite of code pattern examples for numerous programming situations in which a newbie might conceivably think they need to use eval, but instead show a better way to do it. Personally, I don't have the time to develop all that sufficiently well (I fear the book would sell tens of copies), and I'm not sure the effect would be all upside, anyway.[*] If someone has the time and inclination to develop that, more power to them. Until such a volunteer emerges, I think the first step is to have the Racket documentation strongly discourage people from using eval. (Second step: go through all the copies of Scheme-based textbooks in libraries and bookstores, and stick a clarifying Pro Tip decal on the metacircular evaluator chapter.) Funny: One of the very first things that some CS 101 professors like to tell students about is eval. But, for practical software engineering, you might consider eval to be one of the *last* things you tell people about, after they're already experienced in using the other facilities. In the software engineering case, you then don't have much explaining to, because the programmer will have a solid foundation by that time. But, when they don't have that foundation, you can try to throw tons of relevant background at them, but they don't yet have much context for anchoring it, so they have to accept it on faith and memorizing the words of your teachings. If they're going to have to accept on faith anyway, I'd rather just have them accept the concise noble lie don't use eval on faith, until they've gone off and gotten the foundation to know how to develop without eval, and to immediately intuit some of the practical implications of eval. [*] Regarding not all upside to developing criteria and pattern examples: there seem to be relevant phenomena. One is the proliferating clerical worker type of programmer, who has been given the impression that programming is more about mechanically following checklists and copyingpasting solutions, than about understanding and reasoning about systems -- I don't want to encourage the mechanical thinking. Another phenomenon seems to be, when someone is new to a domain, they seem to often reason until they can think of *one* plausible solution, contrasted with someone more familiar, who might reason among many better solutions that come easily to mind -- I want to remove eval from the newbie's consideration. Another phenomenon seems to be that, when someone learns of some powerful feature or technique, they often seem overly anxious to apply it -- I fear that, the more eval is talked about, the more it will be used. This is mostly speculation, of course, but it's merely why I'm not sure the effect would be all upside. Neil V. -- 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.
Re: [racket-users] eval PSA (was Sending Closures to Places)
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). 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). But then /eval/ would need behave as expected and respect its current environment aka lexical scope. Maybe Racket does this right but a lot of Scheme implementation show their true nature when it comes to /eval/ and lexical scope: they revert back to Lisp mode and evaluate the forms in the top level environment. This unexpected behavior might explain why some people still feel uncomfortable with /eval./ As a matter of style one should use /eval/ where it means what it is good for: evaluating (sub) programs. Contrary to some advertisement material /eval/ doesn't really support sand boxing as it is only possible to restrict the name space of the evaluation but not the computing resources needed. Maybe you want to read in that SGML data as s-expression and evaluate it in the HTML environment - but maybe it would be better to traverse the data graph with your own algorithms ... On 03/08/2015 13:32, Josh Grams wrote: On 2015-08-03 01:22AM, Neil Van Dyke wrote: Eval might indeed be the perfect solution this time, iff every other conceivable alternative has been rejected. :) Shameless link to PSA on the topic of eval: http://lists.racket-lang.org/users/archive/2014-July/063597.html Suggestions for other forms for PSA are welcome: If people knew *why* and *how* to avoid eval, wouldn't they already be doing it? To be useful to your target audience, I think you *need* to back this up with a link to supporting documentation. I'd be looking for: - A *brief* high-level statement of why eval causes problems: maybe something like this? I'm sure there are better statements out there... eval takes code which was constructed in one context and assigns meaning to it in a different context. This can cause the code to have an unexpected meaning, or fail to work altogether. It can also cause security problems (if you pass it code from an untrusted source) or be unnecessarily slow (evaluating code at runtime which could have been fixed at compile time). - Rules of thumb for how to decide what to use instead, and when eval might be ok. This answer (http://stackoverflow.com/a/2571549/2426692) suggests asking: - Do I really need eval or does the compiler/evaluator already do what I want? - Does the code really need to be constructed at runtime or can it be constructed earlier? - Will funcall, reduce, or apply work instead? - Concrete examples of where beginners tend to use eval and how to code them without it. This is sort of the same as the previous one, but I like to see a short overview of the whole strategy by itself, so I would put the examples separately, e.g. HTDP has a *nice* clear overview of the design recipe, whereas HTDP 2e has no place where you can go for a quick refresher of what were the steps of the design recipe again? - That's my two cents. I always see these sorts of things getting brushed off as unhelpful or even patronizing, so I think you want to go out of your way to make it easy to dig into it and reach successively deeper levels of understanding. --Josh -- 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.
Re: [racket-users] eval PSA (was Sending Closures to Places)
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
Re: [racket-users] eval PSA (was Sending Closures to Places)
Sean Kanaley wrote on 08/04/2015 12:04 PM: 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. I think maintainability is relevant here. Just for the list: maintainability is a constant concern for most software engineering activity, for very practical, nonreligious, reasons. Maintainability is not just about whether the next programmer to come along will be able to read the code. It's about how easily and effectively you and your team can evolve the system over time, whether you can actually ever make a complex thing viable, whether and how often you get into debugging nightmares or failures, etc. Unless you're able to IPO or job-hop very early in a system lifecycle (and are a bad person), developing with maintainability as a consideration should be very important to you, for very practical reasons. That doesn't mean maintainability doesn't get traded off appropriately at times, but it should be a conscious and informed decision. 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. Very little code is purist-perfect, and that's OK. You might be able to find an academic purist who'd say, don't use eval, because blah blah blah denotational semantics blah blah blah my dissertation blah blah blah. But I think you'll have an easier time finding practical expert practitioners who'd tell a newbie, don't use eval, because it's usually a clusterfudge, for no good reason. If asked about a particular use of eval, a good practical expert practitioner should give thoughtful and nuanced consideration, not cling to don't use eval like an unthinking devotee. But for broadcasting general advice to newbies/students, I think the default practice of saying don't use eval is appropriate. Even better is to say, for the love of all that is good, textbook people, stop making newbies think that eval is in their toolkit, when they don't yet even know how to use the other tools. (define (confirmation target) (eval '(printf Are you sure you wish to nuke ~a? target) namespace) ...) To a purist, the above code is horrifying. (Excepting the horrifying application domain.) That example does show eval being used for no good reason. Though usually the needless uses of eval are much more dangerous, and/or expensive/encumbering to maintain. Neil V. -- 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.
Re: [racket-users] eval PSA (was Sending Closures to Places)
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
RE: [racket-users] eval PSA (was Sending Closures to Places)
Just an example where both source text and the compiled code are relevant: On some occasions I have fallen in the temptation of using eval. For example I had a metacircular interpreter. In order to check that the interpreter is metacurcular indeed, I need both the source text (a sexpr) and the interpeter itself (a procedure). I was tempted to do this as follows: #lang racket (define source-text (quote (a big sexpr))) (define interpreter (let ((ns (make-base-namespace))) (parameterize ((current-namespace ns)) (namespace-require 'racket)) (eval source-code ns))) (provide source-text interpeter) Where the interpeter is a procedure accepting a sexpr and evaluates it in its own internally defined top-level environment. For example: (interpreter (quote (add1 3))) - 4 But it can be done as well, may be better, without eval: #lang racket (define-syntax (source/value stx) ((_ source-text) (syntax (values (quote source-text) source-text (define-values (source-text interpreter) (source/value (a big sexpr))) Now let the interpreter use its own source text to test metacircularity. (interpreter (quasiquote ((unquote source-text) (quote some-sexpr The solution without eval allows use of DrRacket's debug in order to debug the interpreter. With the solution using eval, DrRacket's debug does nothing. There are more ways to do the same, for example by defining the interpreter in a separate file and using read to extract the source text from that file. PS: There is a lot more about testing metacircularity, but that is off topic here. Jos Koot -Original Message- From: racket-users@googlegroups.com [mailto:racket-users@googlegroups.com] On Behalf Of Neil Van Dyke Sent: martes, 04 de agosto de 2015 19:59 To: Sean Kanaley; Alexis King Cc: Michael Titke; racket users Subject: Re: [racket-users] eval PSA (was Sending Closures to Places) Sean Kanaley wrote on 08/04/2015 12:04 PM: 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. I think maintainability is relevant here. Just for the list: maintainability is a constant concern for most software engineering activity, for very practical, nonreligious, reasons. Maintainability is not just about whether the next programmer to come along will be able to read the code. It's about how easily and effectively you and your team can evolve the system over time, whether you can actually ever make a complex thing viable, whether and how often you get into debugging nightmares or failures, etc. Unless you're able to IPO or job-hop very early in a system lifecycle (and are a bad person), developing with maintainability as a consideration should be very important to you, for very practical reasons. That doesn't mean maintainability doesn't get traded off appropriately at times, but it should be a conscious and informed decision. 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. Very little code is purist-perfect, and that's OK. You might be able to find an academic purist who'd say, don't use eval, because blah blah blah denotational semantics blah blah blah my dissertation blah blah blah. But I think you'll have an easier time finding practical expert practitioners who'd tell a newbie, don't use eval, because it's usually a clusterfudge, for no good reason. If asked about a particular use of eval, a good practical expert practitioner should give thoughtful and nuanced consideration, not cling to don't use eval like an unthinking devotee. But for broadcasting general advice to newbies/students, I think the default practice of saying don't use eval is appropriate. Even better is to say, for the love of all that is good, textbook people, stop making newbies think that eval is in their toolkit, when they don't yet even know how to use the other tools. (define (confirmation target) (eval '(printf Are you sure you wish to nuke ~a? target) namespace) ...) To a purist, the above code is horrifying. (Excepting the horrifying application domain.) That example does show eval being used for no good reason. Though usually the needless uses of eval are much more dangerous, and/or expensive/encumbering to maintain. Neil V. -- 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
Re: [racket-users] eval PSA (was Sending Closures to Places)
On 2015-08-03 01:22AM, Neil Van Dyke wrote: Eval might indeed be the perfect solution this time, iff every other conceivable alternative has been rejected. :) Shameless link to PSA on the topic of eval: http://lists.racket-lang.org/users/archive/2014-July/063597.html Suggestions for other forms for PSA are welcome: If people knew *why* and *how* to avoid eval, wouldn't they already be doing it? To be useful to your target audience, I think you *need* to back this up with a link to supporting documentation. I'd be looking for: - A *brief* high-level statement of why eval causes problems: maybe something like this? I'm sure there are better statements out there... eval takes code which was constructed in one context and assigns meaning to it in a different context. This can cause the code to have an unexpected meaning, or fail to work altogether. It can also cause security problems (if you pass it code from an untrusted source) or be unnecessarily slow (evaluating code at runtime which could have been fixed at compile time). - Rules of thumb for how to decide what to use instead, and when eval might be ok. This answer (http://stackoverflow.com/a/2571549/2426692) suggests asking: - Do I really need eval or does the compiler/evaluator already do what I want? - Does the code really need to be constructed at runtime or can it be constructed earlier? - Will funcall, reduce, or apply work instead? - Concrete examples of where beginners tend to use eval and how to code them without it. This is sort of the same as the previous one, but I like to see a short overview of the whole strategy by itself, so I would put the examples separately, e.g. HTDP has a *nice* clear overview of the design recipe, whereas HTDP 2e has no place where you can go for a quick refresher of what were the steps of the design recipe again? - That's my two cents. I always see these sorts of things getting brushed off as unhelpful or even patronizing, so I think you want to go out of your way to make it easy to dig into it and reach successively deeper levels of understanding. --Josh -- 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.
Re: [racket-users] eval PSA (was Sending Closures to Places)
On eval in dynamic languages generally and in Racket specifically http://blog.racket-lang.org/2011/10/on-eval-in-dynamic-languages-generally.html Posted by Matthew Flatt http://blog.racket-lang.org/2011/10/on-eval-in-dynamic-languages-generally.html 2015-08-03 13:32 GMT+02:00 Josh Grams j...@qualdan.com: On 2015-08-03 01:22AM, Neil Van Dyke wrote: Eval might indeed be the perfect solution this time, iff every other conceivable alternative has been rejected. :) Shameless link to PSA on the topic of eval: http://lists.racket-lang.org/users/archive/2014-July/063597.html Suggestions for other forms for PSA are welcome: If people knew *why* and *how* to avoid eval, wouldn't they already be doing it? To be useful to your target audience, I think you *need* to back this up with a link to supporting documentation. I'd be looking for: - A *brief* high-level statement of why eval causes problems: maybe something like this? I'm sure there are better statements out there... eval takes code which was constructed in one context and assigns meaning to it in a different context. This can cause the code to have an unexpected meaning, or fail to work altogether. It can also cause security problems (if you pass it code from an untrusted source) or be unnecessarily slow (evaluating code at runtime which could have been fixed at compile time). - Rules of thumb for how to decide what to use instead, and when eval might be ok. This answer (http://stackoverflow.com/a/2571549/2426692) suggests asking: - Do I really need eval or does the compiler/evaluator already do what I want? - Does the code really need to be constructed at runtime or can it be constructed earlier? - Will funcall, reduce, or apply work instead? - Concrete examples of where beginners tend to use eval and how to code them without it. This is sort of the same as the previous one, but I like to see a short overview of the whole strategy by itself, so I would put the examples separately, e.g. HTDP has a *nice* clear overview of the design recipe, whereas HTDP 2e has no place where you can go for a quick refresher of what were the steps of the design recipe again? - That's my two cents. I always see these sorts of things getting brushed off as unhelpful or even patronizing, so I think you want to go out of your way to make it easy to dig into it and reach successively deeper levels of understanding. --Josh -- 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. -- -- Jens Axel Søgaard -- 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.