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

From: Pierpaolo Bernardi (olopierpa at gmail.com)
Date: Sun Jul 27 00:51:29 EDT 2014

On Sun, Jul 27, 2014 at 5:10 AM, 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.

This is not a case where eval is useful (very few of such cases exist).

Here's a hint:

#lang racket

(define abbreviations
  (hash 'hctz25 "Hydroclorothiazide 25mg"
        ;; more abbreviations here
        ))

(define (print-a-line med quant)
  (printf "~a ---- ~a pills~n"
       (hash-ref abbreviations med "uh?")
       quant))

then:

> (print-a-line 'hctz25 30)
Hydroclorothiazide 25mg ---- 30 pills


I hope this will get you started

P.

Posted on the users mailing list.