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

From: Henry Lenzi (henry.lenzi at gmail.com)
Date: Sun Jul 27 15:41:38 EDT 2014

By the way, just out of curiosity, why do I need to nest EVALs.
E.g., this won't work (notwithstanding the namespace issue in the
definitions panel, just using the REPL):

> (map eval '(*med-name* line *quant-str* pl))
'(hctz25 "-----------" "30" "pills")

Why wasn't the symbol "hctz25" expanded? I'm even more confused,
because this works (again, in the REPL).

> (eval *med-name*)
"Hydroclorothiazide 25mg"

TIA,

Henry Lenzi

On Sun, Jul 27, 2014 at 4:36 PM, Henry Lenzi <henry.lenzi at gmail.com> wrote:
> Thanks for your answers.
>
> - Henry Lenzi
>
> On Sun, Jul 27, 2014 at 2:36 AM, Matthew Butterick <mb at mbtype.com> wrote:
>> The REPL automatically uses the current namespace, which is why you can
>> casually use eval there without specifying a namespace. [1]
>>
>> But if you're using eval in the definitions window, you need to give it a
>> namespace, otherwise you'll get "unbound identifier" errors.
>>
>> In this case, the namespace you want is the one you're already in. So rather
>> than using (make-base-namespace), which will give you an new namespace [2],
>> you need a namespace anchor. To make an anchor, put this in your
>> definitions:
>>
>> (define-namespace-anchor a)
>>
>>
>> And then to use the anchor, change your `map` to this:
>>
>> (map (λ(str) (eval str (namespace-anchor->namespace a)))
>>     '((eval *med-name*) line *quant-str* pl) )
>>
>>
>> And it works.
>>
>> PS I assume you have a reason for preferring eval to, say, a hash.
>>
>>
>> [1]
>> http://docs.racket-lang.org/guide/eval.html?q=namespaces#%28part._namespaces%29
>>
>> [2]
>> http://docs.racket-lang.org/reference/Namespaces.html?q=make-base-namespace&q=namespaces#%28def._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._make-base-namespace%29%29
>>
>>
>>
>> On Jul 26, 2014, at 8:10 PM, Henry Lenzi <henry.lenzi at gmail.com> wrote:
>>
>> #lang racket
>>
>> #|
>>
>> Dear Racketeers -
>>
>> I would like to create a little function
>> that would write a line of a medical recipe.
>>
>> I would pass to "read" a shorthand form,
>> and the program would expand the text. Like so:
>>
>> When I answer "hctz25" and "30", it would print:
>> "Hydrochlorothiazide 25mg ----------- 30 pills".
>>
>> But I'm facing problems related to:
>> - use of "map" with "eval" in the definition area (namespace issues...)
>> See below.
>> |#
>>
>>
>> (require scheme/base) ; Is this necessary?
>> (define this-namespace (make-base-namespace))
>>
>> (define hctz25 "Hydroclorothiazide 25mg")
>> (define  line "-----------")
>> (define pl "pills")
>>
>> (define *med-name* 'NIL) ; *med-name* has global scope - this is on purpose
>> (define *med-name-str* "") ; *med-name-str* has global scope
>>
>> (define (ask-med-name)
>>  (print "Medication") (newline)
>>  (set! *med-name* (read))
>>  (set! *med-name-str* (symbol->string *med-name*)))
>>
>> (define *quant* 0) (define *quant-str* " ")
>>
>> (define (ask-quant)
>>  (print "Quantity") (newline)
>>  (and
>>   (set! *quant* (read)) (unless (number? *quant*) (error "It's not a
>> number!")))
>>  (set! *quant-str* (number->string *quant*)))
>>
>> (define (ask)
>>  (ask-med-name)
>>  (ask-quant))
>> (ask)
>>
>> #|
>> Where's the problem?
>> In the REPL, I can do this:
>>
>> (map eval '((eval *med-name*) line *quant-str* pl))
>>
>> '("Hydrochlorothiazide 25mg" "-----------" "30" "pills")
>>
>> or this:
>>
>> (string-join (map eval '((eval *med-name*) line *quant-str* pl)))
>>
>>
>> "Hydrochlorothiazide 25mg ----------- 30 pills"
>>
>>
>> But, because of the namespace issues associated with "eval", I'm not
>> able to do it in the definition area.
>>
>> I have no clue as to what the syntax should be.
>>
>> Thanks for any help.
>>
>> Henry Lenzi
>>
>> |#
>> ____________________
>>  Racket Users list:
>>  http://lists.racket-lang.org/users
>>
>>
>>
>> ____________________
>>   Racket Users list:
>>   http://lists.racket-lang.org/users
>>


Posted on the users mailing list.