【问题标题】:Calling a Scheme function using its name from a list使用列表中的名称调用 Scheme 函数
【发布时间】:2011-08-05 19:51:08
【问题描述】:

是否可以仅使用可用的函数名称(例如列表中的字符串)来调用 Scheme 函数?

示例

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

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

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

【问题讨论】:

    标签: function scheme evaluation invocation


    【解决方案1】:

    在许多 Scheme 实现中,您可以使用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)
    

    【讨论】:

    • 我认为很多人来自 Ruby 和类似的背景,并希望能够使用基于名称的调度(例如,Ruby 的 Kernel#send 方法)。在 Scheme 中,没有直接的基于名称的调度机制,人们需要在设计程序时考虑到这一点,例如,构建一个具有名称到函数关联的哈希表。
    • 确实如此,但更完整的答案将显示如何编写创建函数和映射表的宏。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-03
    • 2012-04-05
    • 1970-01-01
    • 1970-01-01
    • 2013-11-01
    • 2015-01-16
    • 1970-01-01
    相关资源
    最近更新 更多