A functional data structure is essentially an immutable data

structure: its values never change. However, unlike for instance C#’s

ReadOnlyCollection , which has no operations to e.g. insert into it,

functional data structures do support operations like insertion or

deletion, they are just not in-place. Instead these operations are

handled by creating an entirely new updated structure.

For example, a typical list might look something like the value

[3,2,1] . If this list is mutable and we perform the operation of

inserting the value 4 at the front (head) of this list it now looks

like [4,3,2,1] . It has been modified in place and has become the new

value. The old value [3,2,1] is lost to us. Someone else who was

looking at this list now sees the value [4,3,2,1] instead. If that

someone was in the process of iterating through that list, they now

get a nice exception.

In the functional model this does not happen. Instead, when we insert

4 into the list, it creates a new value [4,3,2,1] , without modifying

the original list. Both the values [4,3,2,1] and [3,2,1] now exist,

and anyone else who was looking at the list [3,2,1] still sees that

value.

You might be thinking this seem very inefficient. If we have access to

both the lists [4,3,2,1] and [3,2,1] we’d always have to store all

those seven elements in memory right? Even though we might no longer

be interested in the value [3,2,1] ? In fact, the efficiency of

functional data structures depend heavily on what operations are

performed on them, and what internal representation is used (just like

normal data structures do, of course, but with some different

advantages, costs and trade-offs).

For (singly linked) lists, if all we’d like to do is do insertions at

the front, we can handle this case efficiently, by storing the

elements as below.

+---+ +---+ +---+ +---+ | 4 +--->+ 3 +--->+ 2 +--->+ 1 | +---+ +---+ +---+ +---+ | | new list original

We put the new value 4 in a new node, with a reference back to the

rest of the list. The original value is represented with the existing

reference, starting at the node for 3 . If someone else had a

reference to that node, they would never notice an update had taken

place (if the list has been doubly linked this wouldn’t be true). We

can honestly say we have access to both the lists [4,3,2,1] and

[3,2,1] independently even though they share elements in memory, as

without operations for in-place modification, there is no perceivable difference.

In fact we could go further: If someone else would like to insert the

element 9 at the head of [3,2,1] , they could do this independent of

us, reusing the same elements.

+---+ +---+ +---+ +---+ new list 1 -> | 4 +---+->+ 3 +--->+ 2 +--->+ 1 | +---+ / +---+ +---+ +---+ / | +---+/ original new list 2 -> | 9 + +---+

We could of course store elements like this for a non-immutable list

as well, but this is frought with danger: For instance, if we’d upate

the element 3 in the list [4,3,2,1] , we’d also update it for someone

seeing the list [9,3,2,1] , who might not like that one bit.

But… what if I really do need to update the element 3 , setting it

to, say, 5 . What then? We’ll, since we’re not allowed to perform any

in-place updates, we’ll have to copy some nodes into the updated

list. The result of all three operations might look like this:

+---+ +---+ updated list -> | 4 +--->+ 5 +----+ +---+ +---+ +---+ +---+ +-+-+ +---+ new list 1 -> | 4 +--->+ 3 +--->+ 2 +--->+ 1 | +---+ / +---+ +---+ +---+ / | +---+/ original new list 2 -> | 9 + +---+

If we start at each pointer, going backwards, we see that this

simultaneously represents all the four values [4,5,2,1] , [4,3,2,1] ,

[9,3,2,1] and [3,2,1] . If we’re indeed interested in storing all these

values simultaneously, this representation is in fact much more

compact than using mutable lists.

Purely functional data structures can be quite useful in

multi-threaded programming, as changes from different threads will not

interfere with each other.