I am a Java programmer and am new to Clojure. From different places, I saw sequence and collection are used in different cases. However, I have no idea what the exact difference is between them.
For some examples:
1) In Clojure's documentation for Sequence:
The Seq interface
(first coll)
Returns the first item in the collection.
Calls seq on its argument. If coll is nil, returns nil.
(rest coll)
Returns a sequence of the items after the first. Calls seq on its argument.
If there are no more items, returns a logical sequence for which seq returns nil.
(cons item seq)
Returns a new seq where item is the first element and seq is the rest.
As you can see, when describing the Seq interface, the first two functions (first/rest) use coll
which seems to indicate this is a collection while the cons
function use seq
which seems to indicate this is a sequence.
2) There are functions called coll?
and seq?
that can be used to test if a value is a collection or a sequence. It is clearly collection and sequence are different.
3) In Clojure's documentation about 'Collections', it is said:
Because collections support the seq function, all of the sequence functions can be used with any collection
Does this mean all collections are sequences?
(coll? [1 2 3]) ; => true
(seq? [1 2 3]) ; => false
The code above tells me it is not such case because [1 2 3]
is a collection but is not a sequence.
I think this is a pretty basic question for Clojure but I am not able to find a place explaining this clearly what their difference is and which one should I use in different cases. Any comment is appreciated.
Any object supporting the core
first
andrest
functions is asequence
.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:
And you can create a sequence object from a
map
tooThat's why you can use
filter
,map
,for
, etc. onmaps
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
callseq
on the input:If you call
(filter pred 5)
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.
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.For
seq?
:For
coll?
:And I found ISeq interface extends from IPersistentCollection in Clojure source code, so as Rörd said, every sequences is a collection.
In Clojure for the brave and true the author sums it up in a really understandable way:
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.