Fwd: [plt-scheme] treating a string a procedure name
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
> >
>