I have a list that contains the "names" of some functions (for example '(+ - *)
)
I want to use that list to call the functions
(define list_of_names_of_functions '(+ - *))
(define sum (car list_of_names_of_functions))
(sum 2 3)
However, sum is a list, so can't be used as a procedure.
How should i do it?
As I mentioned in a comment, using eval
is not the right answer to this: it 'works' but it opens the way to horrors.
If you have a symbol like +
and you want to get its dynamic value then the Racket approach to doing this is to use namespaces. A namespace is really a machine which turns symbols into values in the same way that eval
does, but that's all it does, unlike eval
. Unfortunately I don't understand namespaces very well, but this will work:
(define-namespace-anchor nsa)
(define ns (namespace-anchor->namespace nsa))
(define (module-symbol-value s (in ns))
(namespace-variable-value s #t #f in))
Then
(define function-names '(+ - / *))
(define sum (module-symbol-value (first function-names)))
And now
> (sum 1 2 3)
6
> (eq? sum +)
#t
>
The problem with this approach is that it's leaky: if you have something like this:
(module msv racket
(provide module-symbol-value)
(define-namespace-anchor nsa)
(define ns (namespace-anchor->namespace nsa))
(define secret "secret")
(define (module-symbol-value s (in ns))
(namespace-variable-value s #t #f in)))
(require 'msv)
(define oops (module-symbol-value 'secret))
Now oops
is secret
. A way around this is to use make-base-namespace
to get a namespace which is equivalent to racket/base
.