Vector plays a very special role in Clojure, its one of the most primitive data strucutre in Clojure. Its impossible to master Clojure without a very deep understanding about vector.

The concept of vector exist almost all main stream languages, its the simplest compound data structure. In dynamic language like PHP and Javascript, vector is represented with associate array, and its no different with a map. We should careful about the terminology here, in PHP and Javascript, the name array should be vector, even they call it array. Array should be fixed length, an vector is much like the vector in C++ STL or Java's ArrayList, its dynamically grow.

In Clojure vector and map are two different kind of thing. It more like Python and Java. Python calls its vector the list, which is insane in context of functional programming. Another difference is PHP and Javascript's vector are sparse, Clojure is not.

Vector as a syntax element

One of the biggest improvement for Clojure over old style LISP is using different kind of parenthesis to represent different syntax element. In Clojure the function parameter list is a vector, most binding forms also use vector. So instead in LISP

(defun add (x y) 
  (+ x y)

In Clojure

(defn add [x y] 
  (+ x y)

Doesn't it much clear and easier to read?

How to create vectors in Clojure

The simplest form of creating vector is literal

[1 2 3]

Lets see what the type is this

user=> (class [1 2 3])

This type shows us another feature of Clojure's vector: they are persistent. To achieve persistent, Clojure used a sophistic mechanism behind the scene. For more details Understanding Clojure's Persistent Vectors, pt. 1. Thank God, we the user don't have to deal with these complexities, just happily use the fine grained data structure.

There several functions in Clojure helps you create vector more flexibly: vec and vector.

user=> (vec [1 2 3])
[1 2 3]
user=> (vec '(1 2 3))
[1 2 3]
user=> (vec (range 1 4))
[1 2 3]
user=> (vector 1 2 3)
[1 2 3]

Access vector elements

Clojure vector supports accessing element by numeric index in constant time. You have three ways to do it.

(nth [1 2 3] 0)
(get [1 2 3] 0)
([1 2 3] 0)

They all do the same thing, but they are different, which one to use is depend on your intention.

The nth and get can accept nil vector, in this case, for any index, the nil is returned. If vector is not nil, and index is out of bound, nth throws exception and get returns nil.

(nth nil 2)
user=> nil
(get nil 2)
user=> nil
(nth [1 2 3] 100)
IndexOutOfBoundsException   clojure.lang.PersistentVector.arrayFor (
(get [1 2 3] 100)

Another important thing to note about nth and get is when the vector is sequence or list.

user=> (nth (seq [1 2 3]) 1)
user=> (get (seq [1 2 3]) 1)

The nth and get can also works with list,

user=> (nth (for [ x (range 1 10)] x) 2)
user=> (get (for [ x (range 1 10)] x) 2)

The reason is get only works on key value data structure, in case of vector , the key is numeric index. But list and sequence are not keyed data structures.

How to 'change' vector

You can not really change a vector because of the immutability. When you changes a vector you get a new one. Lets start with the simplest: append element to a vector.

(conj [1 2 3] 4)
[1 2 3 4]

Removes an element from right side of a vector

(pop [1 2 3] )
[1 2]

Change value of an index inside vector

(assoc [1 2 3] 0 "hello")
["hello" 2 3]