'Is-a' versus 'is-a-descendant-of'

November 16, 2009

One of the things that my issue with the Python re module not exposing its types has firmly mashed my nose into is the difference between 'is-a-descendant-of' and 'is-a' in object-oriented languages. It's conventional to think of them as more or less the same thing, even in a loose duck typed language like Python; it just seems to make sense for all compiled regular expressions to descend from a single base class, just as it theoretically makes sense for both plain bytestrings and Unicode strings to descend from an abstract generic string class.

(Technically, some of the things that I am calling classes here are actually types. In Python this is a distinction that can usually be ignored.)

Of course, when I write it out like this it's evident that it doesn't necessarily make sense. For example, the actual implementation of Python's base string class has no code and no behavior; it exists only for the convenience of programmers who want to isinstance() a single class. Similarly, a hypothetical version of the the C based regular expression module that used different classes for different sorts of regular expressions (in order to have different matching engines) could perfectly well have no common abstract class (especially since the re module does not expose such a class today).

On the flipside, it would be nice to be able to write alternate regular expression engines and have their objects accepted as 'compiled regular expressions'. Right now, anything that does duck typing will accept them, but things that look at types won't, purely because they don't descend from the current implementation of the regexp class (and you can't fix that, partly for reasons that I covered yesterday).

What this gets down to is that 'is-a' is effectively a question of interface, not of inheritance. In fact, duck typing in a nutshell is that your object 'is-a' compiled regular expression if it satisfies the expected interface behavior for such objects. Even in Python, we almost always use 'is-a-descendant-of' tests only as a convenient proxy for answering this 'is-a' question, but they are not quite the same thing and the difference can trip you (or other people) up.

(I'm sure I've read about this before, but there is a certain vividness to things this time around because I've had my nose rubbed in this.)

Written on 16 November 2009.
« A limitation of Python types from C extension modules
Finally understanding the appeal of 'Interfaces' »

Page tools: View Source, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Mon Nov 16 00:50:50 2009
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.