Tuples and immutability

Ian Kelly ian.g.kelly at gmail.com
Tue Mar 11 11:39:39 CET 2014

On Mon, Mar 10, 2014 at 11:03 PM, Gregory Ewing
<greg.ewing at canterbury.ac.nz> wrote:
> As far as observable effects are concerned, it's
> quite clear: mutable objects can *always* be updated
> in-place, and immutable objects can *never* be.

Hm. Consider the circle-ellipse problem.  Briefly, a circle is-an
ellipse, so in an inheritance hierarchy it is natural to make Circle a
subclass of Ellipse.  Now suppose the Ellipse has a stretch method
that mutates the ellipse by changing the length of one of its axes
while preserving the other.  To avoid violating LSP, the Circle class
must support all the methods of its ancestor.  However it cannot,
because the stretch method would invalidate the invariant of the
Circle class that both of its axes must always be equal.

There are a number of possible solutions.  One possibility would be to
copy the Circle as an Ellipse and return the new object instead of
mutating it.  Then you have the situation where, given a mutable
object x that satisfies isinstance(x, Ellipse), the stretch method
*may* be able to update the object in-place, or it *may* not.

I can't think of a reasonable example that would replace the stretch
method here with an augmented assignment, but then it is rather late.

> It might be the obvious way for that particular operation on
> that particular type. But what about all the others?
> What's the obvious way to spell in-place set intersection,
> for example? (Quickly -- no peeking at the docs!)

You mean set.intersection_update?  The in-place set methods are not
hard to remember, because they all end in _update.

More information about the Python-list mailing list