What's the difference between a sequence and a

2019-02-04 01:47发布

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.

5条回答
放荡不羁爱自由
2楼-- · 2019-02-04 02:15

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.

查看更多
放荡不羁爱自由
3楼-- · 2019-02-04 02:22

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.

查看更多
Animai°情兽
4楼-- · 2019-02-04 02:28

For seq?:

Return true if x implements ISeq

For coll?:

Returns true if x implements IPersistentCollection

And I found ISeq interface extends from IPersistentCollection in Clojure source code, so as Rörd said, every sequences is a collection.

查看更多
Deceive 欺骗
5楼-- · 2019-02-04 02:41

In Clojure for the brave and true the author sums it up in a really understandable way:

The collection abstraction is closely related to the sequence abstraction. All of Clojure's core data structures — vectors, maps, lists and sets — take part in both abstractions.

The abstractions differ in that the sequence abstraction is "about" operating on members individually while the collection abstraction is "about" the data structure as a whole. For example, the collection functions count, empty?, and every? aren't about any individual element; they're about the whole.

查看更多
爷、活的狠高调
6楼-- · 2019-02-04 02:41

Here are few points that will help understand the difference between collection and sequence.

  1. "Collection" and "Sequence" are abstractions, not a property that can be determined from a given value.

  2. Collections are bags of values.

  3. 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:

enter image description here

You can read more about it here.

查看更多
登录 后发表回答