07 July 2006

Duck-typing and Scheme

Duck-typing advocates occasionally say that querying the type of an object is unnecessary. Certain Pythonistas are fond of this idea. I just don't see it.

Maybe querying the concrete type is unnecessary. (Aside: Python has a builtin, isinstance(), that does just that—but I found out a week or two ago that an object can lie to isinstance() about its type. It's just the most absurd design ever.) But once in a while, I need to know whether a given object can swim, at runtime, preferably without having to put it in the water. Surely in a well-designed language, these questions can be answered without unduly revealing how an object is implemented.

For example, in Scheme, you can't ask if a number is a floating point number, as opposed to a native int (fixnum in Scheme jargon), big-integer, rational, or big-decimal. But you can ask if the number is exact, meaning basically that it hasn't been subjected to rounding. You can ask if a number is an integer or not: (integer? x); but you are actually asking about the number, not its type. So (integer? 1.79e123) is true, as is (real? 1).

For numbers, the difference between querying an object's characteristics and querying its concrete type might seem unimportant. Also, numbers are a special case where the concrete type matters a whole lot, for performance. (The next Scheme standard will add a bunch of procedures like (fx+) that only work on fixnums.) But when you start talking about objects, the difference is whether or not you support duck typing, which I think is a big deal. Languages should make it easy to query an object's interface and inconvenient to query its implementation.

No comments: