Reputation: 1490
In JavaScript, one can do the following:
function foo(arg1, arg2, arg3) {
...
}
var others = [ 'two', 'three' ];
foo('one', ...others); // same as foo('one', 'two', 'three')
In Clojure, "variable args" can be accepted like so:
(defn foo [arg1 & others]
...)
But to pass them in combination with other args, you have to do this:
(apply foo (concat '("one") others))
Which is frankly really ugly. It's also impossible when what you need to do is recur:
(apply recur (concat '("one") others)) ;; doesn't work
Is there a better way to do this? And if not, is there any way at all to accomplish it in the recur
case?
Upvotes: 1
Views: 428
Reputation: 16194
But to pass them in combination with other args, you have to do this:
(apply foo (concat '("one") others))
You don't have to do that: apply
is also a variadic function that can take arguments before the final sequence argument e.g.
(apply foo "one" others)
You can pass any number of individual arguments before the final sequence argument to apply
.
user=> (defn foo [arg1 & args] (apply println arg1 args))
#'user/foo
user=> (apply foo "one" 2 "three" [4 "five" 6.0])
one 2 three 4 five 6.0
To further demonstrate, these calls to +
are functionally equivalent:
(apply + 1 2 [3])
(apply + 1 [2 3])
(apply + [1 2 3])
It's also impossible when what you need to do is recur
recur
is a special form, and apply
doesn't work with it like it would a typical Clojure function.
is there any way at all to accomplish it in the
recur
case?
Not with apply
. You can recur
with variadic args, but you can't (apply recur ...)
.
Upvotes: 5