As inadvertently blogged below, I'm back in Oxford this week, pretending to be a computer scientist (or at least a software engineer) once more. I already established that one of the other guys had to be an instance of a specialization of me, since he could finish a milkshake in less time than me. (The post-condition of a subclass operation, like a class invariant, can be stronger than the superclass version, or equally strong but never weaker. The principle is called covariance. Any practicing programmer knows about polymorphism and the like, but übergeeks take things to another level.)

Speaking of other realities (in a city that houses David Deutsch, Philip Pullman, and dozens of homeless drug addicts... er, that is, people from two distinct subsets of humanity), I wrote a rather gruesome story set in an alternate world, for Lou Anders' anthology, as pictured.
Writing in SFX, Jonathan Wright praises the Jon Courtenay Grimwood story in the same anthology, before adding: "Also holding up the British end, John Meaney’s “Via Vortex” is built around a gory idea of how near-instant teleportation might be achieved. If we didn’t know him better, we’d be worried… "
Ah, well. You all know me by now.

(Despite what it says below, this post has comments...)


Anonymous Anonymous said...

I know this is a joke, but I wanted to pull the substance out of it:
When referring to a subclass, strengthening is actually the removal of conditionality isn't it? Just as maybe includes yes and no, the superclass sets the upper limit on conditionalities, the number of maybes that may be there!

Covariance sounds familiar, something to do with statistical distributions? That sets of lights in my head along the following lines: Dimensionality of possibility, category theory's morphisms and requisite variety from cybernetics, with the information as distinction concept, so more "this or that" moments would count as more information.
But if you can't make any sense of that, I'd like to hear if I'm on the right track with the first bit!

November 20, 2008 at 9:46 PM  
Blogger John Meaney said...

Hi, Josh... "Strengthening" (in the context of polymorphism) is used in the sense of making more restrictive: the new condition is a subset of the old.

The superclass sets the maximum range of possible results it might produce, and defines the minimum range of operating conditions under which you can expect good results. (If subtypes operate under extra circumstances as well, that's fine -- just an added bonus.)

Here's how it works in software.

The discussion is in terms of the preconditions and postconditions of individual methods (member functions) in classes related by inheritance, so their behaviour is polymorphic (a favourite buzzword in object-oriented programming).

The key point here is that clients (client programs/objects) of these classes may know only the top superclass (the top of the hierarchy of types) and call methods without realizing that they're actually dealing with instances of subtypes. For example, the clients may expect to work with vehicles, but at runtime be dealing with car objects, van objects, bicycle objects, etc.

So here's an explanation of covariance/contravariance, starting with post-conditions of methods.

Let's say that you have a Vehicle superclass and various subclasses (e.g. Car, Van, Truck) and they all provide a getPerformanceRating method. The method returns an integer in the range of zero to one hundred inclusive (i.e. it's meant to be a percentage). The method's signature (its definition) merely declares the return type.

Now all clients of Vehicles (for example, a RacingGameController that controls vehicle objects) are ignorant of which type of actual object they're talking to (via polymorphism). The controller knows it's talking to vehicles, but not whether it's talking (at runtime) to cars, trucks etc. However, the controller has come to expect numbers in the given range.

The thing is, the only restriction enforced by the compiler is that the return type of the method is an integer. No restrictions on value (beyond the maximum length of an integer in the language).

Now let's add a new subclass called HotRod. If it returns values in a more restrictive range (say 30 to 90 percent) then the clients are still happy -- the values are in a range they can deal with. But if it can return a value of 110% (because of the way it has a second engine bolted to the first) then the clients may receive numbers that they fail to expect, and fail to execute valid logic.

If you're used to programming languages that throw Exception objects, consider what happens when you override a method and try to make it throw named Exception types. If they're the same type as the superclass method's declared exceptions, all is well. If the new exceptions are subclasses (subtypes) of the parent's exceptions, again all is well. If the new subclass is trying to throw exceptions of types unknown to the parent, then the subclass fails to compile, and so it should, because the client cannot be expected to have code already in place to catch the thrown exception.

The reverse is true of pre-conditions.

Let's say that all the Vehicle class can operate some method on weekdays (the pre-condition is that the day is in the range Monday-Friday inclusive). Clients expect that if they call the method on a weekday, it will work.

Now when we add the HotRod, if its version of the method fails to work on Thursdays, the clients will be surprised. But if it works on all seven days of the week, the clients are fine. (They won't actually try to call it on a weekend if they're used to working with all vehicles, but that's all right.)

All OO programmers know that inheritance means you should be able to substitute an instance of a subclass for an instance of a parent type, and clients won't know the difference. Very few extend this principle to method pre- and post-conditions (or class invariants, a related concept).

Post-conditions are covariant with inheritance, while pre-conditions are contravariant.


And thanks for asking!!!

November 22, 2008 at 9:32 PM  

Post a Comment

Subscribe to Post Comments [Atom]

<< Home