Clojure functions can take a collection of arguments by using the "&"
symbol. So for instance:

    (defn print-all [& args]
      (doseq [arg args]
        (println arg)))

If we run this function with:

    (print-all "Hello" "World")

Then it will print:

    Hello
    World

But dealing with sequences has a cost to it. If print-all has only one
argument, then we can avoid the doseq. So we can optimise the function to
be more performant when we pass in only one argument:

    (defn print-all
      ([x]
        (println x))
      ([x & args]
        (println x)
        (doseq [arg args]
          (println arg))))

Notice that if we pass it one argument, we just print it directly. Two or
more arguments goes into the doseq loop.

Of course we could also add an optimisation for two arguments as well:

    (defn print-all
      ([x]
        (println x))
      ([x y]
        (println x)
        (println y))
      ([x y & args]
        (println x)
        (println y)
        (doseq [arg args]
          (println arg))))

Hopefully you can see why "apply" has five arities now. The first four are
just optimisations, so "apply" will be slightly faster if it has five or
fewer arguments.

In most cases you don't need to use this technique because the performance
gain will be minimal. My print-all function above is probably going to
spend most of its time on I/O, making the optimisation all but useless in
my example. But clojure.core is used everywhere, so wringing an extra drop
of performance is often worth it.

- James

On 14 December 2016 at 13:14, Rafo Ufoun <[email protected]> wrote:

> Hi everyone,
>
> I'm new to clojure and I try to understand the apply function.
>
> From the clojure sources, I can see that there are several signatures for
> this method: with or without additional arguments before the sequence.
>
> According to these signatures, we can have 4 arguments MAX before getting
> the sequence of arguments (([^clojure.lang.IFn f a b c d & args])
>
> However, (apply + 1 1 1 1 1 1 1 1 1 1 1 [2 3]) is a valid function call
> and I can get a result.
> At this point I'm not sure how this signature can accept so many argument
> before the [2 3] sequence. I think I miss a point but don't know what !
>
> Thanks you, Rafi.
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to [email protected]
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> [email protected]
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to