Crowley Code! 
 (Take 12)

The case against duck typing 2009/09/12

It’s a common enough argument to bear documenting once and for all.  Rubytards and cheese shoppers (that is, Python programmers) always gang up on me because they love ducks.  I’d rather the ducks stay out of my type checking, that’s all.

Take this (contrived, as Mike Malone loves to point out) example of what can go wrong with duck typing.  Your revenue-generating web app deals in kittens and dollars so you have classes called Kitten and CreditCard, both of which have a method used to stringify them:

class Kitten(object):
    # ...
    def __unicode__(self):
        return """<img src="%s" />""" % self.src
class CreditCard(object):
    # ...
    def __unicode__(self):
        return "XXXX-XXXX-XXXX-%s" % self.cc[-4:]

If some HTML template requires merely something stringifiable, a CreditCard will do just as well as a Kitten.  To prevent mishaps, the caller must first check the type of the potential kitten or the Kitten and CreditCard classes must be made different species of duck.  While the latter is certainly cleaner from the caller’s perspective, it (pathologically) results in every method of the Kitten class being prefixed "kitten_" to avoid calling a goose a duck.

Of course, this example was invented for the express purpose of making duck typing look awkward and dangerous.  Long before it gets to that point, I think it crosses into confusion.  Looking at a method signature written in any popular dynamic language gives the caller no instruction beyond (maybe) the number of parameters expected.  If you’re lucky, the names of the parameters shed some light.  Perhaps someone’s gone all Javadoc and written out comments that explain what the hell’s going on.

I am not an advocate of regressing back to statically typed languages for all programming (though it’s well-known I’m a big C++ fan).  I want declared typing.  Methods should state what they accept in such a way that the compiler can enforce this on our behalf.  PHP 5 introduced type hinting [1] as a half-assed way to accomplish this.  For objects and arrays (but not integers, floats and strings), PHP can automatically raise “catchable” [2] fatal errors when types don't match up as you intended.

While PHP’s solution is half useless for not working on primitives and half again because you can’t deal with the error and move on, the heart is in the right place.  Declared typing is for the programmer using the API your code creates.  A compiler saying unambiguously that you passed a Sailboat when you should have passed a Bulldozer is delightfully useful when compared to curious “method not found” errors.  Worse still is the subtly incorrect behavior introduced when somebody quacks.

In a nutshell, I wish for the clarity I get from reading statically typed code with the power of dynamically typed languages.

  1. http://us2.php.net/manual/en/language.oop5.typehinting.php
  2. http://bugs.php.net/bug.php?id=41948

Richard Crowley?  Kentuckian engineer who cooks and eats in between bicycling and beering.

I blog mostly about programming and databases.  Browse by month or tag.

To blame for...


© 2009 Richard Crowley.  Managed by Bashpress.