Fwd: [plt-scheme] treating a string a procedure name

From: Dor Kleiman (ifconfig at ntr.co.il)
Date: Mon Feb 16 01:53:48 EST 2004

eval can evaluate anything:

(define (f x y) (+ x (* 5 y)))
(define x 2)
(define y 3)
(eval 'f) ; => procedure
(eval 'x) ; => 2
(eval 'y) ; => 3
(eval `(f x y)) ; => 17

-----Original Message-----
From: David J. Neu [mailto:djneu at att.net] 
Sent: Sunday, February 15, 2004 6:58 PM
To: Matthias Felleisen
Subject: Re: Fwd: [plt-scheme] treating a string a procedure name

Matthias and Jens, thanks for the help!

I had two followup questions:

1. In reference to Jens comment ... is it the right thing to do for
"security" reasons?
> Although The Right Thing(tm) is to keep a an association list of
> symbols and functions to call:

2. Jens mentioned that you could use eval, but suppose that rather
   than a procedure name coming in as a string, I had a variable
   name. I could mimic Matthias's code as shown below, but I don't see
   a parallel to the eval solution.  I guess I'm wondering if there is
   a solution that doesn't require me to "register" the variables in a
   legal-vars list.  For example, in Python it's possible to do the
   following:
   > x = 2
   > s = "x + 1"
   > eval(s)

Again many thanks for the help,

--David


(define-struct point (x y))
(define one-two (make-point 1 2))
(define two-one (make-point 2 1))

(define legal-vars `(("one-two" ,one-two)
                     ("two-one" ,two-one)))

(define (magic-var x)
   (cond
     [(assoc x legal-vars) => cadr]
     [else (error 'magic "someone tried to reference an illegal
variable")]))

(point-x (magic-var "one-two"))


On Sun, Feb 15, 2004 at 11:18:40AM -0500, Matthias Felleisen wrote:
>  For list-related administrative tasks:
>  http://list.cs.brown.edu/mailman/listinfo/plt-scheme
> 
> 
> 
> Begin forwarded message:
> 
> >From: Matthias Felleisen <matthias at ccs.neu.edu>
> >Date: Sun Feb 15, 2004  10:52:00 AM US/Eastern
> >To: "David J. Neu" <djneu at att.net>
> >Subject: Re: [plt-scheme] treating a string a procedure name
> >
> >
> >On Sunday, February 15, 2004, at 10:27 AM, David J. Neu wrote:
> >
> >>  For list-related administrative tasks:
> >>  http://list.cs.brown.edu/mailman/listinfo/plt-scheme
> >>
> >>Hi,
> >>
> >>I have an application in which I'd like to be able to grab a string,
> >>(e.g. from a file, web-form, etc) and then to treat that string as a
> >>procedure name to invoke.
> >>
> >>For example, in the code below, I'm hoping there is some procedure
> >>(I'm calling it magic) that would allow me to do this.
> >>
> >>(define square
> >>  (lambda (x)
> >>    (* x x)))
> >>
> >>; in real app the string procedure-name is would obtained
> >>; from some  external source
> >>(define procedure-name "square")
> >>
> >>((magic procedure-name) 2)
> >
> >;; String -> Procedure
> >(define (magic x)
> >  (cond
> >    [(assoc x legal-magics) => cadr]
> >    [else (error 'magic "someone tried to invoke an illegal 
> >procedure")]))
> >
> >;; Number -> Number
> >(define (square x) (* x x))
> >
> >;; (Listof (List String Procedure))
> >(define legal-magics
> >  `(("square" ,square)
> >    ("sqrt"   ,sqrt)))
> >
> >;; --- Tests
> >
> >(= ((magic "square") 2) 4)
> >(= ((magic "sqrt") 4) 2)
> >(with-handlers ([exn:user? (lambda _ #t)]
> >                [void (lambda _ #f)])
> >  ((magic "duh") 3)
> >  #f)
> >
> >-- Matthias
> >
> 


Posted on the users mailing list.