user2879704
user2879704

Reputation:

Eval error - Wrong type argument: listp

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

Answers (3)

Tarmil
Tarmil

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

Vatine
Vatine

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

Wintermute
Wintermute

Reputation: 44063

apply takes a function and a list, so use

(apply func '("a" "b"))

Or just

(func "a" "b")

Upvotes: 1

Related Questions