Those following examples are producing same output.
(seq [1 2 3 4])
=> (1 2 3 4)
(sequence [1 2 3 4])
=> (1 2 3 4)
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. The seq function yields an implementation of ISeq appropriate to the collection.
A list is a sequence but a sequence is not necessarily a list. A sequence is any type that supports the sequence interface ("protocol"). Sequence types describe a functional superset.
"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.
Overview. Clojure is not a lazy language. However, Clojure supports lazily evaluated sequences. This means that sequence elements are not available ahead of time and produced as the result of a computation.
The difference is that sequence
always returns a seq even if the collection is empty (in that case an empty list), while seq
returns nil
for empty collections. Also, sequence
can be used with transducers.
A look into the source code:
user=> (source sequence)
(defn sequence
"Coerces coll to a (possibly empty) sequence, if it is not already
one. Will not force a lazy seq. (sequence nil) yields (), ..."
([coll]
(if (seq? coll) coll
(or (seq coll) ())))
...
So calling sequence
with only a collection calls seq
on the collection if it isn't already a seq and returns an empty list if the collection was nil
.
first of all, they treat empty sequence argument differently:
user> (seq nil)
nil
user> (seq ())
nil
user> (sequence ())
()
user> (sequence nil)
()
also sequence
has additional arities to operate on transducers
as of docs:
clojure.core/sequence
[coll]
[xform coll]
[xform coll & colls]
Added in 1.0 Coerces coll to a (possibly empty) sequence, if it is not already one. Will not force a lazy seq. (sequence nil) yields (), When a transducer is supplied, returns a lazy sequence of applications of the transform to the items in coll(s), i.e. to the set of first items of each coll, followed by the set of second items in each coll, until any one of the colls is exhausted. Any remaining items in other colls are ignored. The transform should accept number-of-colls arguments
clojure.core/seq
[coll]
Added in 1.0 Returns a seq on the collection. If the collection is empty, returns nil. (seq nil) returns nil. seq also works on Strings, native Java arrays (of reference types) and any objects that implement Iterable. Note that seqs cache values, thus seq should not be used on any Iterable whose iterator repeatedly returns the same mutable object.
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