使用列表中的名称调用Scheme函数

com*_*inc 7 evaluation scheme function invocation

是否可以仅使用可用的函数名称作为列表中的字符串来调用Scheme函数?

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

(define func-names (list "somefunc"))
Run Code Online (Sandbox Code Playgroud)

然后调用somefunc (car func-names).

Mat*_*ard 14

在许多Scheme实现中,您可以使用以下eval函数:

((eval (string->symbol (car func-names))) arg1 arg2 ...)
Run Code Online (Sandbox Code Playgroud)

但是,你通常不想那样做.如果可能,将函数本身放入列表并调用它们:

(define funcs (list somefunc ...))
;; Then:
((car funcs) arg1 arg2 ...)
Run Code Online (Sandbox Code Playgroud)

附录

正如评论者指出的那样,如果您确实想要将字符串映射到函数,则需要手动执行此操作.由于函数是与任何其他函数一样的对象,因此您可以简单地为此目的构建字典,例如关联列表或哈希表.例如:

(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)
Run Code Online (Sandbox Code Playgroud)

  • 我认为很多人都来自Ruby和类似的背景,并希望能够使用基于名称的调度(例如,Ruby的`Kernel#send`方法).在Scheme中,没有基于名称的调度的直接机制,人们需要设计具有这一点的程序,例如,构建具有名称到功能关联的哈希表. (4认同)