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

From: Daniel Prager (daniel.a.prager at gmail.com)
Date: Thu Jul 31 09:47:58 EDT 2014

Hi Henry

I'm taking a similar approach to Galler for a proof-of-concept, but without
the macrology. This should make the ideas more widely accessible (and my
skill with macros is limited).

First, thank-you again for supplying the example. By comparing input and
output readers can infer the kinds of things your DSL does, even with only
a smattering of Forth.

The first thing to do is to devise a more Lispy representation of the DSL.
Let's take the original:

: NAME S"John Doe"
   CU4
   HCTZ25 30P 1CPM
   OMZ20 30P 1CPM INSTOMZ
   SIMVA20 30P 1CPN
   L/D;


and re-cast it using parentheses and prefix notation. I've chosen to notate
as follows, adapting from Galler:

'(script
  (name "John Doe")
  (directions (CU 4))
  (medication (HCTZ 25) (P 30) (CPM 1))
  (medication (OMZ 20) (P 30) (CPM 1) (INSTOMZ))
  (medication (SIMVA 20) (P 30) (CPN 1)))


[I've left off the L/D because I didn't follow the mapping, but you get the
idea.]

Now -- in practice -- a physician doesn't want to fiddle with parentheses,
so a simple parser (16 lines in the proof-of-concept) is needed to go from
something close to the original DSL to the new, parenthesized DSL.

>From this new DSL there are many ways to get to the expanded script.
Because it keeps coming up (and it's a quick hack ;-) I've used eval. A
simple desugaring approach (as described in Shriram's PLAI book and course)
would also work well, IMO.

Here's my proof-of-concept in action...

Input:

(shorthand->script
"John Doe
CU4
HCTZ25 30P 1CPM
OMZ20 30P 1CPM INSTOMZ
SIMVA20 30P 1CPN")


Output:

John Doe

Continuous use - 4 months

Hydrochlorothiazide 25mg ---------------- 30 pills

    Take 1 pill in the morning.

Omeprazol 20mg ---------------- 30 pills

    Take 1 pill in the morning, 1/2 hour before breakfast.

Simvastatin 20mg ---------------- 30 pills

    Take 1 pill at night.


Code pasted here: http://pasterack.org/pastes/67082

To summarize:

   1. Design the Lispy version of the DSL
   2. Parse from the input DSL to the Lispy DSL
   3. Expand from the Lispy DSL to the full script
   4. Bells and whistles: graphics, file-handling, proper user-interface,
   error-handling, etc.

I hope that helps.

I think this would be a good open-source project, and well-suited to
Racket.

BTW: If you want to produce nicely type-set output, consider looking into
the Scribble language / tool.

Dan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20140731/30a5e287/attachment.html>

Posted on the users mailing list.