Seriously, what is it? It’s not a rhetorical question. I realized this morning that I am totally confused about this.

First off, let me say what I thought “duck typing” was. I thought it was a form of typing.

So what is “typing”? We’ve discussed this before on this blog. (And you might want to check out this post on late binding and this post on strong typing.) To sum up:

A compile-time type system provides three things: first, rules for defining types, like “array of pointers to integer”. Second, rules for logically deducing what type is associated with every expression, variable, method, property, and so on, in a program. And third, rules for determining what programs are legal or illegal based on the type of each entity. These types are used by the compiler to determine the legality of the program.

A run-time type system provides three similar things: first, again, rules for defining types. Second, every object and storage location in the system is associated with a type. And third, rules for what sorts of objects can be stored in what sorts of storage locations. These types are used by the runtime to determine how the program executes, including perhaps halting it in the event of a violation of the rules.

Typically you want the compile time and runtime type systems to be highly similar and complement each other, which is certainly the case in C#. In a C# program the runtime type of an object is almost always identical to or compatible with the compile-time type of the associated expression, and if somehow it is not compatible (due to, say, an incorrect cast operator) then an exception is produced at runtime.

So I had assumed that “duck typing” was first and foremost a form of typing. That is, duck typing is a system for deducing facts about entities in a program and then deciding whether the collection of facts in the program showed that all parts of it were consistent. What then is the “duck” part? Duck typing is so-called because of the principle “if it walks like a duck and quacks like a duck then it is a duck”. Let’s look at an example in C#:

class Duck { public void Quack() { ... } public void Walk() { ... } } class OtherDuck { public void Quack() { ... } public void Walk() { ... } } ... void M(Duck bird) { bird.Quack(); bird.Walk(); } ... M(new Duck()); // Legal M(new OtherDuck()); // Illegal

C#’s static type system says that the relevant fact about new OtherDuck() is that it is of type OtherDuck , but the formal parameter bird is of incompatible type Duck , and therefore this is a violation of the type system. A duck-typed system — again, remember we are talking about what my conception of duck typing here — would allow a program like this:

void N(ducktyped bird) { bird.Quack(); bird.Walk(); } ... N(new Duck()); // Legal N(new OtherDuck()); // Legal! N(123); // Illegal!

That is, the compiler deduces that the relevant fact about bird is “has methods Quack and Walk “. This is then the type that is deduced for bird . Since the types deduced for new Duck() and new OtherDuck() are compatible with this type, these lines are legal. But since the type associated with 123 is not compatible with the type associated with bird , that line is illegal.

In C# of course one would typically do this with interfaces; you’d define an interface IDuck , have the method take one of those, and have both classes implement the interface. The point of duck typing — again, in my conception — is that the compiler essentially deduces the interface for you, saving you from the inconvenience of having to create and name an interface and then ensure that every class or struct in the universe that you would like to make quack implements that interface.

Somewhat surprisingly, C# does implement this feature in some limited ways. For example, when you say from c in customers where c.City == "London" select c , the type system requires that the type of expression customers be associated with a unique best method or an extension method Where that takes a lambda. This was, again to my mind, duck typing. The type of customers is not required to implement IQueryable or anything like that; rather, the only relevant fact in the type system is “can we find a unique best Where method?”

But C# does not implement this kind of typing in general. Scala does, though Scala requires what I might have characterized as manifest or explicit duck typing. In Scala we could define our method N as follows: (Note that I am not a Scala programmer; I might have made some syntax errors here.)

def N(bird : {def quack() : Unit; def walk() : Unit}) { bird.quack(); bird.walk(); }

Scala requires that you state the needed methods up front, but does not require that you define an interface. If the argument passed for bird did not have the requisite methods then the program would not compile.

So that was my understanding of duck typing. So imagine my surprise when I looked it up in Wikipedia this morning and discovered:

In computer programming with object-oriented programming languages, duck typing is a style of typing in which an object’s methods and properties determine the valid semantics, rather than its inheritance from a particular class or implementation of a specific interface.

This is off to a bad start. I don’t see what in the slightest object-orientedness has to do with it; it seems perfectly reasonable to have a duck-typed functional language or procedural language. Nor do I see why methods and properties are so important; surely there are other relevant facts that can be deduced from usage. But so far this agrees with my concept more or less. Then we come to:

In duck typing, one is concerned with just those aspects of an object that are used, rather than with the type of the object itself.

Again, this is inelegantly expressed. “Aspects” are not clearly defined; are these the “methods and properties” mentioned before? Worse, there seems to be a fundamental incoherency here: that the object has a “real type” of itself. Is this trying to draw a distinction between the runtime and compile time types? What exactly is meant by “object” here? I think of objects as being a runtime concept. Though this is perhaps badly stated, it still agrees more or less with my conceptualization of duck typing. But then we come to:

For example, in a non-duck-typed language, one can create a function that takes an object of type Duck and calls that object’s walk and quack methods. In a duck-typed language, the equivalent function would take an object of any type and call that object’s walk and quack methods. If the object does not have the methods that are called then the function signals a run-time error.

My emphasis.

But this is not even typing in the first place! We already have a name for this; this is late binding. “Binding” is the association of a particular method, property, variable, and so on, with a particular name (or operator) in a particular context; if done by the compiler then it is “early binding”, and if it is done at runtime then it is “late binding”. (As I noted in the article linked above, certain forms of binding such as virtual method calls have both early and late aspects; the “virtual method slot” is bound early but the contents of that slot are determined late.) Why would we even need to invent this misleadingly-named idea of “duck typing” in the first place??? If you mean “late binding” then just say “late binding”!

So OK, perhaps my whole concept of duck typing all these years has simply been wrong. All those people who said “duck typing” actually meant “late binding”, and I just didn’t realize they were synonyms. But the Wikipedia page goes on to say:

Certain usually statically typed languages such as … C# have extra type annotations that instruct the compiler to arrange for type checking of classes to occur at run-time rather than compile time

The page is of course referring to dynamic which it then goes on to say is how you do duck typing in C#. But I don’t think of dynamic typing in C# as duck typing at all; rather, it means “defer what would normally be the compile-time analysis of this expression until runtime, and use the runtime type of the object as the compile-time type. (As an aside I note that the actual meaning is rather more subtle; the runtime type might not have been accessible at the call site. The type actually used is the most derived type that would have been accessible.) of the object as the compile-time type.” Again, this is late binding, not (again, to my mind) duck typing.

And the page then goes on to say, bizarrely and ungrammatically:

Other statically typed languages like F# supports static duck typing which verifies on compile time that the type have the specific method available

Wikipedia started this article by saying that duck typing happens at runtime in object oriented languages, and now apparently we are saying that it also happens at compile time in a functional language?! And it then goes on to give an example in Scala that is again, checked at compile time rather than at runtime, despite stating several times in the article that duck typing only means runtime checking, except when it doesn’t.

I am utterly confused, and I am coming to believe that either this Wikipedia page is incoherent, or worse, the whole idea of duck typing is fundamentally incoherent.

Can anyone out there resolve this for me? Or do I have to treat “duck typing” the same way I treat “strong typing”? “Strong typing” without a careful definition is essentially meaningless; any two people talking to each other can reasonably have completely opposite definitions of “strong typing” in their head. Apparently for a long time that has been true of me and “duck typing”; anyone else I talked to using that term likely thought I meant something completely different, and I might have been the one in the wrong.

Oh and happy new year all!