使 alexandria:curry 不一定使用 funcall 是愚蠢的吗?

Is it foolish to make alexandria:curry not necessarily use funcall?

目前必须用 funcall 调用与 Alexandria 的 curry 柯里化的函数。然而,可以设置新函数的 symbol-function ,这样我们就可以不用它,把它当作一个真正的函数来对待。图解 https://lispcookbook.github.io/cl-cookbook/functions.html#with-the-alexandria-library:

(defun adder (foo bar)
  "Add the two arguments."
  (+ foo bar))

(defvar add-one (alexandria:curry #'adder 1) "Add 1 to the argument.")

(funcall add-one 10)  ;; => 11

(setf (symbol-function 'add-one) add-one)
(add-one 10)  ;; => 11
;; and still ok with (funcall add-one 10)

有充分的理由不允许这两种样式吗?在柯里化的背景下,这对我来说看起来很有趣。

ps:大约 3 周前我确实在 Alexandria 的问题跟踪器上询问过

pps: https://gitlab.common-lisp.net/alexandria/alexandria/blob/master/functions.lisp#L116

根据您的评论,并查看 the issue,是的 "foolish" 更改 curry 以便它绑定全局命名空间中的函数:

  • 这将是对 curry 的重大更改,这将破坏现有代码
  • 具有此功能的宏不符合 Alexandria, as far as I know. This would be better suited for Serapeum, which happens to already define such a function, namely defalias. As you can see, the definition is a little more involved than using symbol-value. See also the documentation 的精神。

作为参考,这个简单的宏可以完成工作:

(defmacro defcurry (name function &rest arguments)
  "Returns a regular function, created by currying FUNCTION with ARGUMENTS."
  `(let ((closure (alexandria:curry ,function ,@arguments)))
     (setf (symbol-function ,name) closure)))

示例:

(defun adder (x y) (+ x y))
(defcurry 'add2 #'adder 2)
(add2 3)  ;; no "funcall" here
;; => 5"

编辑:但是……这要简单得多:

(defun add2 (a)
  (adder 2 a))