A persistent vector is an indexed Clojure collection that appears immutable while older versions remain available wherever they are still referenced. It is useful when code needs a changed vector without losing the previous value, or when cached results must support access by position. section 12.1 section 12.5
Updates do not copy the whole vector. Elements sit in the leaves of a balanced tree; changing one element copies its leaf and the nodes along the path to the root, while other nodes are shared. With 32-way branching, the tree stays shallow. An indexed change is O(log n) in theory but behaves almost like constant time in practice. section 12.1
Change a position, keep the old value
(def original [:a :b :c]) (def changed (assoc original 2 :d)) changed ; => [:a :b :d] original ; => [:a :b :c] (nth original 2) ; => :c (original 3) ; => IndexOutOfBoundsException section 12.1
Vectors work with sequence operations, but are not themselves sequence types: seq? returns false. Use vec to turn a seqable collection into a persistent vector; ordered inputs retain their order. For results that should remain vectors, mapv transforms elements and filterv retains those satisfying a predicate. Unlike map and filter, both produce their results eagerly rather than returning lazy sequences. section 12.1 section 12.5 section 12.8 section 12.9
Build vector-valued results
(vec '(:a 1 nil {})) ; => [:a 1 nil {}] (mapv inc [0 1 2 3]) ; => [1 2 3 4] (filterv odd? (range 8)) ; => [1 3 5 7] Choose map or filter instead when a vector result is unnecessary or laziness matters. section 12.5 section 12.8 section 12.9
One interoperability caveat qualifies the apparent immutability: vec may alias a Java object array of 32 or fewer elements. Do not mutate that array afterward, because the vector's observed contents may change. section 12.5
