Scheme中使用语法规则进行隐式currying?

时间:2010-09-19 11:48:17

标签: macros functional-programming scheme currying syntax-rules

Jeffrey Meunier有一个隐含的Curry宏here,它使用了defmacro。我想知道是否有人用语法规则写过这个?

1 个答案:

答案 0 :(得分:3)

Scheme中有许多curry实现 - 没有一个可以像Haskell一样优雅,因为函数总是一元函数,所以一切都可以通过curry。 (但这当然可以在一个足够强大的方案中实施,如Racket。)

至于你挖出的宏 - 它是一个非常糟糕的宏:它不仅使用不卫生的宏,它还明确地调用eval,并依赖于环境的实现等。但使用简单的syntax-rules宏很容易做到这一点。 AFAICT,这是它实现的:

(define-syntax-rule (clambda (x ... . r) b ...)
  (let ([len  (length '(x ...))] [real (lambda (x ... . r) b ...)])
    (let loop ([argss '()] [n 0])
      (lambda args
        (let ([n (+ n (length args))] [argss (cons args argss)])
          (if (>= n len)
            (apply real (apply append (reverse argss)))
            (loop argss n)))))))

但这里有一个重要的注意事项。您引用的页面表示函数版本的问题在于它是显式的 - 但它也有一个重要的优点:使用宏实现您必须使用clambda定义函数,而函数版本可以使用具有任何内置功能。在许多Scheme实现中,有一些工具可以检查函数的arity,使用它可以实现一个知道何时调用原始函数的currying函数版本。