[Tutor] What does Python gain by having immutable types?

Danny Yoo dyoo at hkn.eecs.berkeley.edu
Tue Nov 15 03:38:55 CET 2005


> > Quite often the only answer is "just because". Some features are the
> > way they are because that's Guido's pesonal preference. Others may
> > disagree with him but it's his language and he gets to pick what he
> > thinks is best - the benign dictator syndrome.


Hi Hugo,

There are a few languages that have immutable values.  For example, C and
Java both define string literals to be immutable: trying to mutate them
causes an error.  (Well, C is supposed to raise a segmentation fault.)


There are strong advantages to immutability: one of the main ones is that
side-effect-less programming is less prone to certain kinds of bugs.

For example, let's say we wanted a function to squish values together:

######
>>> def squish(A, B):
...     """Creates a new list containing the elements of A and B"""
...     result = []
...     result.extend(A)
...     result.extend(B)
...     return result
...
>>> squish(range(5), range(7, 9))
[0, 1, 2, 3, 4, 7, 8]
######


An alternative way to write this might be:

######
>>> def smash(A, B):
...     """Creates a new list containing the elements of A and B.
...        Smashes the existing list A."""
...     A.extend(B)
...     return A
...
>>> smash(range(5), range(7, 9))
[0, 1, 2, 3, 4, 7, 8]
######


These both appear to have the same behavior but of course we know that
something must be different between the two.  *grin*


If we have two lists, like:

######
>>> firstNames = ['hugo', 'keanu']
>>> lastNames = ['weaving', 'reeves']
######

we can squish() them together:

######
>>> squish(firstNames, lastNames)
['hugo', 'keanu', 'weaving', 'reeves']
>>>
>>> firstNames
['hugo', 'keanu']
>>> lastNames
['weaving', 'reeves']
######


... or we can smash() them:

######
>>> smash(firstNames, lastNames)
['hugo', 'keanu', 'weaving', 'reeves']
>>>
>>> firstNames
['hugo', 'keanu', 'weaving', 'reeves']
>>> lastNames
['weaving', 'reeves']
######

Oh!

Notice that smash() messes with the list named by firstNames; when we
finish calling it, we see a side effect: firstNames is smashed.  The issue
here is that we've let ourselves mutate our input values.  Of course this
is an exaggerated example, but it tries to make a point: having mutable
values means we have to think about mutation.  Mutation introduces a kind
of "leakage" between functions.

To make the situation more extreme: if we are working with someone else's
code, and if we pass a mutable value to that external code, then if we see
a bug later on in our own program, we may have to wonder if the external
code mutated our values.  That can be a big pain.

(C programmers have to worry about this ALL THE TIME because they have
pointers that let anyone smash up everything.  *grin*)

If we guarantee, though, that we are working with immutable values, we can
toss them with abandon at anyone and know that they won't get munged.
That's why immutability is an important concept in a programming language,
and an especially useful one in a collaborative language like Python.


Does this make sense?  If you have more questions, please feel free to
ask.



More information about the Tutor mailing list