What's the difference between a sequence and a collection in Clojure
Any object supporting the core first
and rest
functions is a sequence
.
Many objects satisfy this interface and every Clojure collection provides at least one kind of seq object for walking through its contents using the seq
function.
So:
user> (seq [1 2 3])
(1 2 3)
And you can create a sequence object from a map
too
user> (seq {:a 1 :b 2})
([:a 1] [:b 2])
That's why you can use filter
, map
, for
, etc. on maps
sets
and so on.
So you can treat many collection-like objects as sequences.
That's also why many sequence handling functions such as filter
call seq
on the input:
(defn filter
"Returns a lazy sequence of the items in coll for which
(pred item) returns true. pred must be free of side-effects."
{:added "1.0"
:static true}
([pred coll]
(lazy-seq
(when-let [s (seq coll)]
If you call (filter pred 5)
Don't know how to create ISeq from: java.lang.Long
RT.java:505 clojure.lang.RT.seqFrom
RT.java:486 clojure.lang.RT.seq
core.clj:133 clojure.core/seq
core.clj:2523 clojure.core/filter[fn]
You see that seq
call is the is this object a sequence validation.
Most of this stuff is in Joy of Clojure chapter 5 if you want to go deeper.
Here are few points that will help understand the difference between collection and sequence.
"Collection" and "Sequence" are abstractions, not a property that can be determined from a given value.
Collections are bags of values.
Sequence is a data structure (subset of collection) that is expected to be accessed in a sequential (linear) manner.
The figure below best describes the relation between them:
You can read more about it here.
Every sequence is a collection, but not every collection is a sequence.
The seq
function makes it possible to convert a collection into a sequence. E.g. for a map you get a list of its entries. That list of entries is different from the map itself, though.