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.
"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.
Clojure defines many algorithms in terms of sequences (seqs). A seq is a logical list, and unlike most Lisps where the list is represented by a concrete, 2-slot structure, Clojure uses the ISeq interface to allow many data structures to provide access to their elements as sequences.
Lazy sequences in Clojure have two parts, the head is the first unrealized element of the sequence, and the thunk is an uninvoked, argument-less function that, when called, will realize the rest of the elements in the sequence starting from the head.
Advertisements. A Vector is a collection of values indexed by contiguous integers. A vector is created by using the vector method 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With