使用语法规则在Scheme中隐式柯里化?

发布于 2024-09-24 12:17:21 字数 162 浏览 4 评论 0原文

Jeffrey Meunier 在此处有一个隐式 Curry 宏,它使用 defmacro。我想知道是否有人用语法规则写过这个?

Jeffrey Meunier has an implicit Curry macro here, which uses defmacro. I was wondering if someone has ever written this with syntax-rules?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

阿楠 2024-10-01 12:17:21

Scheme 有许多柯里化实现——没有一个能像 Haskell 那样优雅,因为函数总是一元函数,所以所有东西都可以柯里化。 (但这当然可以在一个足够强大的方案中实现,例如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 定义函数,而函数版本可以与任何内置函数一起使用。在许多方案实现中,都有检查函数数量的工具,并且使用它可以实现知道何时调用原始函数的柯里化函数版本。

There are a number of curry implementations for Scheme -- none can be as elegant as Haskell, since there functions are always unary functions, so everything can be curried. (But this can of course be implemented in a sufficiently powerful Scheme like Racket.)

As for the macro that you've dug up -- it's a pretty bad one: not only does it use an unhygienic macro, it's also calling eval explicitly, and relies on an implementation of environments etc. But it's easy to do that with a simple syntax-rules macro. AFAICT, this is what it implements:

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

But there's an important note here. The page that you reference says that an problem of the function version is that it's explicit -- but it also has an important advantage: with the macro implementation you must define a function using clambda, whereas the functional version can be used with any built in function. In many Scheme implementations there are facilities to inspect a function's arity, and using this it's possible to implement a currying function version that knows when to call the original function.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文