Вызов функции Scheme с использованием ее имени из списка - PullRequest
6 голосов
/ 05 августа 2011

Можно ли вызвать функцию Scheme, используя только доступное имя функции, скажем, в виде строки в списке?

Пример

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

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

А затем вызвать somefunc с помощью (car func-names).

1 Ответ

13 голосов
/ 06 августа 2011

Во многих реализациях Схемы вы можете использовать функцию eval:

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

Однако, как правило, вы действительно не хотите этого делать. Если возможно, поместите сами функции в список и вызовите их:

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

Добавление

Как указали комментаторы, если вы действительно хотите отобразить строки в функции, вам нужно сделать это вручную. Поскольку функция является объектом, как и любой другой, для этой цели вы можете просто создать словарь, например, список ассоциаций или хеш-таблицу. Например:

(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)
...