[racket] Use of map and eval to evaluate symbol in namespace

From: Sean Kanaley (skanaley at gmail.com)
Date: Sat Aug 9 10:11:37 EDT 2014

Sorry, couple typos: mapply = map and l = lst.

On Sat, Aug 9, 2014 at 10:10 AM, Sean Kanaley <skanaley at gmail.com> wrote:

> There's a simple enough example I think: apply with keyword parameters.
> Apply has that built-in..sort of...but the list is supposed to be provided
> inline to APPLY, seemingly requiring apply to be applied (e.g. (apply apply
> (cons *thefunctiontoapply* params))), except keywords can't be expressions
> anyway. I have a bunch of card definitions for Dominion with many defaults:
> (struct card (... actions buys ...))
> (define (make-card ... #:actions actions #:buy buys ...)
>   ...)
> The non-keyword-requiring way is
> (define CARDS
>   (map (\ (lst) (apply make-card lst))
>           '([... 1 1 ...]
>            [... 2 0 ...])))
> The keyword way is
> ;ns is namespace
> (mapply (\ (lst) (eval `(apply make-card ',(car l) ,@(cdr l)) ns))
>         '([(...) #:actions 1 #:buys 1 ...]))
> Short of making a big macro to take some exact format and get it to work
> with keywords and all that, eval seems to be just what is needed.
> On Sat, Aug 9, 2014 at 8:27 AM, Neil Van Dyke <neil at neilvandyke.org>
> wrote:
>> Sounds like a good rule of thumb.  Two suggestions to add:
>> * Maybe there could also be a second rule of thumb, like, "If you need
>> arbitrary Racket expressions, then consider whether you can do it with one
>> of the following patterns: [list some patterns involving combinations of
>> syntax extension, custom #lang, dynamic requires, considering whether
>> config files can actually be compile-time #lang, etc.]"  This is less
>> important than the first rule of thumb.
>> * When we list typical newbie cases that don't actually require "eval",
>> we can expect that newbie will immediately want an example of the
>> non-"eval" way to do that typical thing.  At the very least, an example
>> showing, say, good use of hashes in parameters, with a sensible thin
>> abstraction layer over it, for that case.  These examples would be tedious
>> to work through and write up well, but someday some knowledgeable and
>> benevolent person will do it.  (I am not this person.  Book royalties
>> aren't enough to ease the pain. I'd rather that newbies just never heard of
>> "eval" or were scared away from it, rather than having to talk them down
>> off the ledge all the time.)
>> Neil V.
>> Eli Barzilay wrote at 08/09/2014 07:31 AM:
>>  I think that I ran into a nice way to discourage eval except when
>>> needed: the rule of thumb is to only use eval when you need to evaluate
>>> any arbitrary (Racket) expression.  It sounds simplistic but it covers
>>> lots of cases that make newbies run to eval:
>>> * I just want to get the value of a variable whose name is held in x
>>> * More common: I have a symbol/string that names a function, I just need
>>>    to call that function
>>> * I need to keep an update-able mapping from names to values, just like
>>>    what the toplevel does
>>> * I want to let people write an arithmetic expression instead of a
>>>    number
>>> In such cases questions like "do you need allow calling all functions",
>>> and "do you need to handle lambda expressions" have negative answers.
>>> On Sun, Jul 27, 2014 at 4:16 PM, Neil Van Dyke <neil at neilvandyke.org>
>>> wrote:
>>>> Maybe there should be a periodic public service announcement about not
>>>> using
>>>> "eval".  This time I will communicate in FAQ format:
>>>> Q: How do I use eval?
>>>> A: Don't use eval.
>>>> Q: But don't so many academic books feature eval prominently, so doesn't
>>>> that mean I should use try to eval?
>>>> A: Those books use eval for pedagogic reasons, or because the author is
>>>> enamored of some theoretical appeal of eval, or because the author
>>>> wants to
>>>> watch the world burn.  Don't use eval.
>>>> Q: But, but, but, I am just starting to learn, and eval seems to do
>>>> what I
>>>> need.
>>>> A: Eval is almost certainly not what you want.  Learn how to use the
>>>> other
>>>> basics effectively.  Don't use eval.
>>>> Q: I now am very comfortable with the language, I am aware that I should
>>>> avoid eval in almost all cases, and I can tell you why eval is actually
>>>> the
>>>> right thing in this highly unusual case.
>>>> A: Cool, that's why eval is there.
>>>> Neil V.
>> ____________________
>>  Racket Users list:
>>  http://lists.racket-lang.org/users
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20140809/554a5527/attachment-0001.html>

Posted on the users mailing list.