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

From: Matthew Butterick (mb at mbtype.com)
Date: Sun Jul 27 01:36:33 EDT 2014

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

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20140726/6c5147f7/attachment.html>

Posted on the users mailing list.