Reputation:
The following code
(setq func 'concat)
(apply func "a" "b")
throws the following error
***Eval error*** Wrong type argument: listp, "b"
Why does apply
take all arguments from the third position as arguments meant for 'func'?
Upvotes: 2
Views: 3105
Reputation: 11372
apply
takes a list as its last argument, so these calls are correct:
(apply func "a" '("b"))
(apply func '("a" "b"))
To pass plain arguments, you can use funcall
instead:
(funcall func "a" "b")
Eventually, you can also use apply
as follows
(apply func "a" "b" nil)
or
(apply func "a" "b" ())
This is because nil
and ()
are considered empty lists in Emacs Lisp.
Upvotes: 4
Reputation: 21288
The typical use of apply
is to apply one function to a list of arguments and then "spread" that list over the arguments. On the other hand, funcall
is only needed because elisp separates function and variable bindings.
(defun wrapped-fun (fun a b)
"Wrapped-fun takes a function and two arguments. It first does something,
then calls fun with the two arguments, then finishes off doing
something else."
(do-something)
(funcall fun a b) ;; Had function and variable namespaces been the same
;; this could've been just (fun a b)
(do-something-else))
Upvotes: 2
Reputation: 44063
apply
takes a function and a list, so use
(apply func '("a" "b"))
Or just
(func "a" "b")
Upvotes: 1