= Sequences
Rich Hickey
2015-01-01
:type: reference
:toc: macro
:icons: font
:prevpagehref: datatypes
:prevpagetitle: Datatypes
:nextpagehref: transients
:nextpagetitle: Transients

ifdef::env-github,env-browser[:outfilesuffix: .adoc]

toc::[]

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. The https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/seq[seq] function yields an implementation of ISeq appropriate to the collection. Seqs differ from iterators in that they are persistent and immutable, not stateful cursors into a collection. As such, they are useful for much more than foreach - functions can consume and produce seqs, they are thread safe, they can share structure etc.

Most of the sequence library functions are _lazy_, i.e. functions that return seqs do so incrementally, as they are consumed, and thus consume any seq arguments incrementally as well. Functions returning lazy seqs can be implemented using the https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/lazy-seq[lazy-seq] macro. See also <<lazy#,lazy>>.

When https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/seq[seq] is used on objects that implement Iterable, the resulting sequence is still immutable and persistent, and will represent a single pass across the data. Because that pass might happen lazily, the pass might see changes that happen after https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/seq[seq] has been called. Also, if the backing iterator is subject to ConcurrentModificationException, then so too is the resulting seq. When seq is used on native Java arrays, changes to the underlying array will be reflected in the seq - you must copy the source array to get full immutability. That said, there is still a lot of utility to using seq on Iterables and arrays since seqs support multi-pass and lazy algorithms. Robust programs should not mutate arrays or Iterables that have seqs on them.

Many of the functions in the seq library take one or more collections, call https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/seq[seq] on them, and then operate on the resulting seq. In other words, many of these functions take collections but operate on their seqs.

== 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.

For a discussion of *rest* vs. *next* and *lazy-seq* see <<lazy#,lazy>>.

== The Seq library

This is a sampling of the primary sequence functions, grouped broadly by their capabilities. Some functions can be used in different ways and so appear in more than one group. There are many more listed in the https://clojure.github.io/clojure/[API] section.

Since Clojure 1.7, Clojure also provides <<transducers#,transducers>>, an alternate model for composable transformations on collections. Transducers decouple the input, processing, and output parts of transformation and allow reuse of transformations in more contexts, such as core.async channels. Many of the sequence functions in the list below will create transducers if the input collection is omitted. See the Transducers page for more details.

=== Seq in, Seq out

[%hardbreaks]
Shorter seq from a longer seq: https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/distinct[distinct] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/filter[filter] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/remove[remove] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/for[for] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/keep[keep] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/keep-indexed[keep-indexed]
Longer seq from a shorter seq: https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/cons[cons] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/concat[concat] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/lazy-cat[lazy-cat] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/mapcat[mapcat] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/cycle[cycle] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/interleave[interleave] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/interpose[interpose]
Seq with head-items missing: https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/rest[rest] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/next[next] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/fnext[fnext] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/nnext[nnext] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/drop[drop] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/drop-while[drop-while] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/nthnext[nthnext] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/for[for]
Seq with tail-items missing: https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/take[take] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/take-nth[take-nth] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/take-while[take-while] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/butlast[butlast] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/drop-last[drop-last] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/for[for]
Rearrangment of a seq: https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/flatten[flatten] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/reverse[reverse] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/sort[sort] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/sort-by[sort-by] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/shuffle[shuffle]
Create nested seqs: https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/split-at[split-at] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/splitv-at[splitv-at] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/split-with[split-with] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/partition[partition] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/partition-all[partition-all] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/partition-by[partition-by] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/partitionv[partitionv] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/partitionv-all[partitionv-all]
Process each item of a seq to create a new seq: https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/map[map] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/pmap[pmap] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/mapcat[mapcat] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/for[for] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/replace[replace] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/reductions[reductions] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/map-indexed[map-indexed] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/seque[seque]

=== Using a seq

[%hardbreaks]
Extract a specific-numbered item from a seq: https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/first[first] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/ffirst[ffirst] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/nfirst[nfirst] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/second[second] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/nth[nth] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/when-first[when-first] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/last[last] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/rand-nth[rand-nth]
Construct a collection from a seq: https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/zipmap[zipmap] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/into[into] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/reduce[reduce] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/set[set] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/vec[vec] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/into-array[into-array] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/to-array-2d[to-array-2d] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/frequencies[frequencies] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/group-by[group-by]
Pass items of a seq as arguments to a function: https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/apply[apply]
Compute a boolean from a seq: https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/not-empty[not-empty] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/some[some] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/reduce[reduce] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/seq?[seq?] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/every?[every?] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/not-every?[not-every?] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/not-any?[not-any?] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/empty?[empty?]
Search a seq using a predicate: https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/some[some] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/filter[filter]
Force evaluation of lazy seqs: https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/doseq[doseq] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/dorun[dorun] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/doall[doall]
Check if lazy seqs have been forcibly evaluated: https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/realized?[realized?]

=== Creating a seq

[%hardbreaks]
Lazy seq from collection: https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/seq[seq] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/vals[vals] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/keys[keys] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/rseq[rseq] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/subseq[subseq] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/rsubseq[rsubseq]
Lazy seq from producer function: https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/lazy-seq[lazy-seq] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/repeatedly[repeatedly] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/iterate[iterate]
Lazy seq from constant: https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/repeat[repeat] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/range[range]
Lazy seq from other objects: https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/line-seq[line-seq] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/resultset-seq[resultset-seq] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/re-seq[re-seq] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/tree-seq[tree-seq] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/file-seq[file-seq] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/xml-seq[xml-seq] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/iterator-seq[iterator-seq] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/enumeration-seq[enumeration-seq]
