2
votes

In clojure, I frequently use the following code:

(into [] (range 3))

But then I've seen this code being used:

(apply vector (range 3))

What is the difference between those two code samples ? Is one more idiomatic than the other ? When to use into to init collections, and when to use apply + factory function ?

1
The latter I would write as (vec (range 3)). No need to use apply there.Michiel Borkent

1 Answers

8
votes

The way you are calling them, the results of both functions are the same. However, the semantics of apply and into are quite different.

  • apply is used to eval a function received as an argument with a set of arguments, also received as arguments. (apply vector (range 3)) results in a call to (vector 0 1 2)
  • into reduces a collection into another by repeatedly applying conj. (into [] (range 3)) results in (conj (conj (conj [] 0) 1) 2).

Regarding which is more idiomatic, this enters into the realm of opinions. I would suggest to use whichever shows intent in your particular situation. I might use into for the specific use case you raise in the comment (building a concrete type from a lazy seq). I think it would be easier to read:

(into [] (get-the-lazy-seq))
;; vs
(apply vector (get-the-lazy-seq))

Last but not least, there might be differences on the memory footprint and performance of both invocations but they depend so much on your environment that I would recommend to use a profiler if you are concerned about this.