1

curry目前,必须使用 Alexandria 的 curried 函数调用funcall. 但是,可以设置新函数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

4

2 回答 2

3

根据您的评论,并查看问题,是的curry,更改以绑定全局命名空间中的函数将是“愚蠢的” :

  • 这将是一个重大的变化curry,它会破坏现有的代码
  • 据我所知,具有此功能的宏与Alexandria的精神不符。这将更适合Serapeum,它恰好已经定义了这样一个函数,即defalias. 如您所见,定义比使用更复杂一些symbol-value。另请参阅文档
于 2017-08-25T14:25:00.150 回答
1

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

(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))
于 2017-09-01T15:06:44.323 回答