7

Is it possible to call a Scheme function using only the function name that is available say as a string in a list?

Example

(define (somefunc x y)
  (+ (* 2 (expt x 2)) (* 3 y) 1))

(define func-names (list "somefunc"))

And then call the somefunc with (car func-names).

Matthias Benkard
  • 15,497
  • 4
  • 39
  • 47
commsoftinc
  • 71
  • 1
  • 3

1 Answers1

14

In many Scheme implementations, you can use the eval function:

((eval (string->symbol (car func-names))) arg1 arg2 ...)

You generally don't really want to do that, however. If possible, put the functions themselves into the list and call them:

(define funcs (list somefunc ...))
;; Then:
((car funcs) arg1 arg2 ...)

Addendum

As the commenters have pointed out, if you actually want to map strings to functions, you need to do that manually. Since a function is an object like any other, you can simply build a dictionary for this purpose, such as an association list or a hash table. For example:

(define (f1 x y)
  (+ (* 2 (expt x 2)) (* 3 y) 1))
(define (f2 x y)
  (+ (* x y) 1))

(define named-functions
  (list (cons "one"   f1)
        (cons "two"   f2)
        (cons "three" (lambda (x y) (/ (f1 x y) (f2 x y))))
        (cons "plus"  +)))

(define (name->function name)
  (let ((p (assoc name named-functions)))
    (if p
        (cdr p)
        (error "Function not found"))))

;; Use it like this:
((name->function "three") 4 5)
Matthias Benkard
  • 15,497
  • 4
  • 39
  • 47
  • 4
    I think a lot of people come from Ruby and similar backgrounds and expect to be able to use name-based dispatch (e.g., Ruby's `Kernel#send` method). In Scheme, there is no direct mechanism for name-based dispatch, and people need to design programs with that in mind, e.g., building a hash table with the name-to-function associations. – C. K. Young Aug 06 '11 at 14:28
  • That's true, but a more complete answer would show how to write a macro that creates functions and the mapping table. – Eli Barzilay Aug 12 '11 at 21:30