1

I'm playing around with apply-partially and I'm confused about what gets returned when calling this function. The documentation states that apply-partially returns a function, but then I'd expect to be able to do the following:

(defun add-numbers (a b)
  (+ a b))
(defun add2 (apply-partially 'add-numbers 2))

and then call the function:

(add2 3)

OR:

(funcall add2 3)

Unfortunately this throws an error. When I do everything inside of a let, however, it does work and I get "5" back:

(let ((add2 (apply-partially 'add-numbers 2)))
  (funcall add2 3))

I thought maybe the difference was that let doesn't use defun, as I do above, but then I would expect the following to work:

(defvar add2 (apply-partially 'add-numbers 2))
(funcall
 add2 3)

but that doesn't work either. So what am I missing? Is it not possible to assign the return value of apply-partially outside of a let?

3
  • Wait, I see now, that my (defun add2 (....)) can't work because defun sees (apply-partially 'add-numbers 2) as an argument list. apply-partially never actually gets called here. So that means the (defun add (...)) call CAN'T work, leaving only the (defvar add2 (...)) towards the bottom.
    – flooose
    Commented May 18, 2018 at 12:16
  • You could also use defalias
    – npostavs
    Commented May 18, 2018 at 12:36
  • You're right, using defalias allows me to call the return value of apply-partially in the following way: (add2 3), i.e. as a normal function. (funcall add2 3) doesn't work, but that's also not a problem. Thanks :)
    – flooose
    Commented May 18, 2018 at 12:41

1 Answer 1

1

I figured it out. As noted in my comment above, my code:

(defun add2 (apply-partially 'add-numbers 2))

can't work because defun is a special form and (apply-partially 'add-numbers 2) is seen as the argument list to the special form, i.e. apply-partially never gets evaluated.

This leaves us with the challenge of saving the call (apply-partially 'add-numbers 2) to something else that can either be called directly, i.e. (add2 3) or with (funcall add2 33). As mentioned, my attempt with defvar above doesn't work:

(defvar add2 (apply-partially 'add-numbers 2))

I found the answer here, and has to do with the fact "... that in Emacs Lisp, symbols have a value cell and a function cell, which are distinct. When you evaluate a symbol, you get its value. When you evaluate a list beginning with that symbol, you call its function. This is why you can have a variable and a function with the same name."

So can replace defvar with setq and (funcall add2 3) will work as expected. Otherwise, we can also use fset to set the returned value of apply-partially directly to add2's function cell:

(fset 'add2 (apply-partially 'add-numbers 2))

and then we can simply call the function: (add2 3)

3
  • The defvar + funcall example works for me.
    – npostavs
    Commented May 18, 2018 at 12:39
  • Am I using defvar wrong? I keep getting "Symbol's function definition is void: nil" when I use defvar + funcall
    – flooose
    Commented May 18, 2018 at 12:47
  • 1
    Maybe you have set the add2 variable earlier in the session? See the docstring of defvar: ...set SYMBOL, only if SYMBOL's value is void.
    – npostavs
    Commented May 18, 2018 at 14:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.