A value is immutable when it can’t be changed after it’s created. Instead of modifying it, you build a new value from it and leave the original alone. (The opposite — changing a value in place — is called mutation.)
This pairs naturally with last lesson’s idea of a pure function: a function whose output depends only on its inputs and which changes nothing outside itself. A function can’t very well “change nothing” if it mutates the list you handed it.
Here’s the setup. Some caller has a list and will use it again:
scores = [10, 20, 30]
result = with_four(scores)
# The caller now expects `scores` to STILL be [10, 20, 30],
# and `result` to be [10, 20, 30, 4].
In Python, xs + [4] builds a brand-new list (a new value). But xs.append(4), xs += [4], and
slice-assignment like xs[len(xs):] = [4] all mutate the existing list in place — so the caller’s
scores would silently change too.
Which body for with_four returns the new list without disturbing the caller’s original?
def with_four(xs):
???