So let's analyze how much time would it take to retrieve

an element at some index in that vector.

You've seen for lists, it very much depend on what the index is.

Fast for zero, slow, linearly slow, for indices towards the end of the list.

Vectors are much better behaved here because to get

an index of a vector of length 32, it's a single index access.

If the vector has size up to about a 1,000, then it's just two accesses,

so generally the number of accesses are the depth of the vector.

And we'll see that that debt grows very slowly.

A depth of six gives you a billion elements.

So generally the formula would be that the depth of the vector is log

to the basis of 32 of N, where N is the size of the vector.

So we've seen that log to the basis of 32 is a function that grows very,

very slowly.

That's why vectors have a pretty decent random access

performance profile much, much better than list.

Another advantage of vectors is that they are fairly good for

bulk operations that traverse a sequence.

So such bulk operations could be for instance a map that applies a function to

every element, or a fold that reduces addition elements with an operator.

For a vector then you can do that in chunks of 32 and that happens to

be coincide fairly closely to the size of a cash line in modern processes.

So it means that all the 32 addition elements

will be in a single cache line and that accesses will be fairly fast.

For list on the other hand, you have this recursive structure where

essentially every list element is in a con cell, with just one element and

the pointer to the rest.

And you have no guarantee that these con cells are anywhere near to each other.

They might be in different cache lines and different pages so the locality for

list accesses could be much worse than the locality for vector accesses.

So you could ask if vectors are so much better why keep list at all?

But it turns out that if your operations fit nicely into the model that you take

the head of the recursive data structure, that's the constant time operation for

list, whereas for vectors who have to go down potentially several layers.

And then to take the tail to process the rest, again a constant type operation for

lists, whereas for vectors it would be much more complicated.

In that case, definitely,

if your access patterns have this recursive structures, lists are better.

If your access patterns are typically bulk operations, such as map or

fold, or filter, then a vector would be preferable.

Fortunately, it's easy to change between vectors and

lists in your program because the two are quiet analogous.

So we create vectors just like we create list,

only we write vector where we had written list.

And we can apply all the same operations of list, also to vectors,

map, fold, head, tail, and so on.

Except for the cons because cons in a list, that's the primitive thing

that builds a list and that let's us pattern match against the list.

Instead of a con, vectors have operations +; which adds a new element

to the left of the list, and :+ which adds an element to the right of the list.

So you see theses here, x +: xs creates a new vector with

leading element x followed by all elements of xs.

And xs :+ x creates a new vector with trailing element x,

preceded by all elements of xs.

So note that the colon always points to where the collection is,

where the sequence is.

So let's see what it would take to append an element to a vector.

Again, vectors like lists are immutable, I can't touch the existing vector.

I have to create a new data structure.