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

453 Views Asked by At

Currently a function curried with Alexandria's curry must be called with funcall. However it is possible to set the new function's symbol-function so that we can do without it and treat it like a real function. Illustrated on 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)

Is there a good reason not to allow both styles ? This looks quite interesting to me in this context of currying.

ps: I did ask on Alexandria's issue tracker some 3 weeks ago

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

2

There are 2 best solutions below

2
On BEST ANSWER

Based on your comment, and looking at the issue, yes it would be "foolish" to change curry so that it binds functions in the global namespace:

  • This would be a major change for curry, which would break existing code
  • A macro with this functionality would not mesh well with the spirit of 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.
0
On

For reference, this simple macro does the job:

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

Example:

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

edit: but… this is much simpler:

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