Reputation: 175
The core.clj code for Clojure itself (available at https://github.com/clojure/clojure/blob/clojure-1.7.0/src/clj/clojure/core.clj) gives the following definition for comp
:
(defn comp
"Takes a set of functions and returns a fn that is the composition
of those fns. The returned fn takes a variable number of args,
applies the rightmost of fns to the args, the next
fn (right-to-left) to the result, etc."
{:added "1.0"
:static true}
([] identity)
([f] f)
([f g]
(fn
([] (f (g)))
([x] (f (g x)))
([x y] (f (g x y)))
([x y z] (f (g x y z)))
([x y z & args] (f (apply g x y z args)))))
([f g & fs]
(reduce1 comp (list* f g fs))))
I'm new to Clojure and trying to understand both the technical side and idiomatic style sides of it and I'm wondering what the reason is for including so many cases when two functions are passed into comp
. Why bother with the [x y] and [x y z] cases at all?
Upvotes: 3
Views: 199
Reputation: 14559
As Mars said, this is done for efficiency. Dispatching directly is faster than using apply
. Unrolling functions like this is quite common to speed up the performance, juxt
is unrolled in a similar fashion.
Upvotes: 6