# Immutability and Python

Introducing Pyrsistent

Tobias Gustafsson

tobias.l.gustafsson@gmail.com

tobias.gustafsson@trioptima.com

## What is immutability?

Something is immutable if it cannot be changed once created.

Lets keep it simple:

### What's it good for?

• Cognitive offload for the developer
• Safe and simple invariance checking
• Safe and fast sharing, within and between threads
• Safe and fast reuse
• Hashable

### Why not?

• Runtime efficiency
• Programmer habits
• Lacking language support

## Base types

``````>>> x = 17
>>> y = 17
>>> x is y
True
>>> y = 1700
>>> x = 1700
>>> x is y
False``````

Numbers and strings are immutable

## Collections

tuple, frozenset and namedtuple, that's about it...

``````>>> tuple() is tuple()
True
>>> list() is list()
False``````

Gets messy and inefficient when you want to evolve the content

``````>>> t1 = (1, 2, 3, 4, 5)
>>> t2 = t1[:2] + (17,) + t1[3:]
# or
>>> l1 = list(t1)
>>> l1[2] = 17
>>> t2 = tuple(l1)``````

## Enter Pyrsistent

Immutable collections that are easy to evolve

a.k.a. persistent data structures

a.k.a. functional data structures

# Examples

``````>>> v1 = pvector([1, 2, 3, 4])
>>> v1 == v(1, 2, 3, 4)
True
>>> v1[1]
2
>>> v1[1:3]
pvector([2, 3])
>>> v2 = v1.set(1, 5)
>>> v2
pvector([1, 5, 3, 4])
>>> v1
pvector([1, 2, 3, 4])
>>> pvector(x + 1 for x in v1)
pvector([2, 3, 4, 5])
``````
``````>>> m1 = pmap({'a':1, 'b':2})
>>> m1 == m(a=1, b=2)
True
>>> m1['a']
1
>>> m1.b
2
>>> m1.items()
[('a', 1), ('b', 2)]
>>> m1.set('a', 3)
pmap({'a': 3, 'b': 2})
>>> m1
pmap({'a': 1, 'b': 2})
``````

# Pyrthon

``````>>> [1, 2, 3]
pvector([])
>>> {'a': 1, 'b': 2}
pmap({})
>>> {1, 2, 3}
pset([1, 2, 3])
``````
• Like living on the edge
• Don't mind (initial) confusion
• Want literal support for persistent data structures

If you:

Get them:

`pip install pyrsistent`
`pip install pyrthon`