Duck Typing

In terms of StaticTyping/DynamicTyping, ManifestTyping/ImplicitTyping, one kind is what DavidThomas calls "DuckTyping".

The name derives from the colloquial saying, "If it WalksLikeaDuck and talks like a duck, it must be a duck".

In a language that supports DuckTyping an object of a particular type is compatible with a method or function, if it supplies all the methods/method signatures asked of it by the method/function at run time.

Example1: If a method1 calls object.draw() then any object with a draw method is compatable with it.

Example2: If a method2 calls object.draw() but object.move() only if object.stationary is false, then an object whose stationary parameter is true and that does NOT have a move method would be compatible with method2 under DuckTyping as no object.move() would be called in this case. The test is carried out at run time.

Here are some references from the ruby-talk mailing list: See also StructuralSubtyping

A number of languages use some form of DuckTyping: Do C++ templates really implement duck typing? It seems to me that most templating systems simply provide a more DRY implementation of manifest typing."

Yes, albeit statically. E.g. if you use 'template<typename X> void foo(X x) { x.y(); }', it will work if and only if the element x has a 'y' method that requires no explicit arguments. It is primarily the structure of the elements that determine whether they can be successfully used in this manner. This becomes clearer once you start using template functions/structures as arguments.

Does HaskellLanguage use DuckTyping? I think it can. Type classes, and all that. Look at this code:
    apply :: a -> b -> (a -> b -> c) -> c
    apply a b f = f a b
    uncurry :: ((a, b) -> c) -> a -> b -> c
    uncurry f a b = f (a, b)
Don't know if that's exactly duck typing, but it does prove that Haskel has a template equivalent. Now, templates I know can do duct typing.
     template <typename T> T[] sort(T[] ts) {
             if (t > pivot) { ... }
You don't have to declare that T inherits from IComparable, the compiler just works out that you need a bool operator > (T a, T b).

{The Haskell example is not DuckTyping. It is GenericProgramming. The critical distinction is that apply and uncurry must both explicitly provide structural signatures for their input types - e.g. (a,b) and (a->b->c) - instead of just applying them much deeper in the function.}

Actually DuckTyping can be said not to be prevalent in Python, because there's no typing Python, ItsAllInYourHead?. That is a python programmer has to have it all DuckTyping in its head for his code to be correct, but Python as a language has no concept called type that matches DuckTyping. It simply leaves it to programmer's heads to worry about DuckTyping. Is the same thing about SmalltalkLanguage. However, Python and other similar "dynamically typed" languages can be said that it enforces some DuckTyping invariants at run-time. But you can't put your hand over any object or language construct in Python and call it: "this is my duck type". Python has no ducks.

I disagree--if you had to declare your duck, then it's no longer DuckTyping, but a more typical Interface/Implementation metaphor. The same thing is true in C++'s template DuckTyping.

I disagree too - I think the author has misunderstood the whole concept. Duck Typing allows you to pass an object of any type to a function provided that the object supports a given set of functions and variables. This can also be implemented in Python by using multiple inheritance and in a sense Duck Typing is the lazy man's version of constructing a 'proper' type hierarchy using mix-in classes for these situations.

Actually, I think that interfaces are a great way to make those ducks--rather than declaring an input variable to a method/function as
	def meth(s as sometype):
	// do something with S
You would declare (using a hypothetical extension of BooLanguage):
	def meth(s impliments someinterface):
Or even better, with custom duck typing:
	def meth(s hasmethods(Iterate, Invoke)):
	// do something with methods that can be Iterated over *and* called.
...and this could all be STATICALLY CHECKED AT COMPILE-TIME!!! (Leading to less compiling, only to find it doesn't work, a major annoyance).

'' I agree with the initial comment - there is no typing in Python, and it's not because of the lack of declarations, but the lack of any checks on your behalf other than presence of a method at invocation time. Calling,, on an object that only has foo and boo methods would only barf on the .bar() call. To be able to claim there is something in Python called a 'type system' you have to show that it actually does anything.

I consider it an incidental obfuscation technique by which one probes the interface of an object by looking for characteristic method-names, instead of just looking at the declared protocols. This happens usually because language designers forget to add provisions for classes that subtype built-in classes without actually subclassing them. For example there is no standard way of saying "anything array-like" in RubyLanguage.

Here's a snippet of how you can make a protocol-representing object in Ruby:

(module ArrayP; end; class Array; include ArrayP; end) if not defined? ArrayP

From that point, you can use ArrayP and Array as two different levels of array-ness, where the array-like objects that don't subclass Array would still inherit from ArrayP.

Now if we can get more people to use that convention... But it's not like anyone really uses Array-like classes that respect (or even attempt to respect) the full 41-method protocol of Array. (There is the MetaRuby? library but I don't know anyone using it.)

So right now, all that DuckTyping really does is calling things like "the thing that can do X" instead of calling things by their name. I actually prefer the above alternative to DuckTyping (ArrayP and such...), just like what I had originally proposed in the MetaRuby? implementation a few years ago.

Note: Duck Typing in general is more than I've written above, it's also about not checking types at all assuming they are right, which is a good way to get meaningless error messages. I use that technique because it's the natural way of doing in many languages, and I'd rather use that than JavaLanguage's type system anyway. (If type-checking is to be enforced, it better be using a good type system) -- MathieuBouchard

I don't consider this interface checking behavior to be an integral part of what we call Duck Typing. My usage and understanding of these concepts is more closely aligned with your last negative paragraph ("meaningless error messages"), though I can count the number of times I've run into meaningless error messages on zero fingers. It just doesn't happen.

In what ways is Duck Typing "An incidental obfuscation technique". Incidental? Obfuscation? Technique? None of those words make sense in this context.

-- ChadFowler

I think that was sarcasm. Mathieu believes that DuckTyping obfuscates a design because there is not explicit contract for an object to guarantee that it supports a given type, and it's an incidental technique because obfuscation is not its desired goal.

But that's not the point. You're not really trying to find out whether it supports a given type, are you? You're really trying to find out if it behaves ("walks...") like you want it to (" a duck"). Hence the availablity of the "responds_to?" method in Ruby.

The problem is that in effect, Duck Typing puts all your method names in the same namespace, so you get nasty conflicts. Your drawing function takes what you think is a SprayCan? and calls spray()... and your data gets peed on because you were really calling Cat.spray().

How is this different from mere "substitutability"? Why give it a special name?

For an A to be a substitute for a B, a B must also do anything an A can do, and it must do something reasonably similar. Under DuckTyping, you only care that something can do what you asked it to do.

Substitutability: Imagine a method that takes a Polygon, and asks the Polygon to draw itself at some coordinates -- under substitutability, you can send the method anything substitutable for a Polygon, such as a Square, but not a Circle, even though it's reasonable to ask a Circle to draw itself.

DuckTyping: You have a method that takes an object (you intended it to be a Polygon), and it asks the object to draw itself. Under DuckTyping, any object that can respond to the "draw yourself" method name with the parameters you gave it without raising an error is allowed. I could send a GIF object to your method (as long as my GIF object knew how to draw itself) and itynamicTyping wouldn't complain. If I sent a GunFighter? object to your method, it might draw its gun out of its holster and fire at the coordinates given (because that's what "draw" means to a GunFighter?).

Actually under DuckTyping you cannot say a method that takes a Polygon, because you can't name the type Polygon, but you can say a method that takes any object that has a method called "draw" with one parameter.In a StaticTyping with ducks that condition may need further elaboration by saying what kind of parameter that should be compatible with.

Fredrik might have also said it at other times and in other venues, but his "if you don't understand duck typing, you don't really understand Python" was a direct response to a post of mine on python-list. My response was to the effect that being true, Python is really a pretty difficult language to understand - contrary to its reputation. I guess I would use the discussion here as evidence to support my response - since what duck typing in fact is, and whether Python actually implements it, is open to discussion. Fredrik was being Fredrik. He understands what duck typing is as to Python, as he understands it. But I would contend that Python is a lot easier to understand than "duck typing". So Fredrik must be wrong. "ItsAllInYourHead?" sounds more right.

-- ArtSiegel?

That's because python is very hard to understand. It is a massive ball of hacks put together so that pseudocode will run. That's the whole point of Python - runnable pseudocode. Pseudocode is hard to parse, because humans have vague ideas about it. So the language itself is monstrously complex. It just looks simple. That's why many Python fans are moving to the more "ideologically pure" RubyLanguage. Personally, I just stick to Python because it's what I know.

Pythons typing isn't pure duck, though, because you can check the actual type of an object. I've seen methods that made sure the a parameter was an honest to goodness file and not just a file like object, for example. I can't remember if this was in the standard library or a third party one, though.

Why would you ever want to do this? Insisting that an object have a certain type is the inverse of polymorphism and OO.

An excellent question. I presume it was a misguided attempt at validation. Or maybe it did some sort of voodoo magic with the objects internals that would break if it wasn't a real file. I don't know.

Python has isinstance(obj, classinfo) which checks if object is an instance of classinfo or a subclass of classinfo. So it is just fine to type check manually at runtime in this case.

This page has taken some sharp turns over an extended period of time. It would be nice if it became somewhat more solidly authoritative. A long time ago there were explicit guesses, which were pointed out to be such and eventually removed. Now there seem to be guesses that aren't labelled as such.

One might want to compare with the brief not-quite-stub article or at least the resources it points to.

Oh great, we've dumbed down programming to "walking like ducks", can people damage ComputerScience any more than we already have?

It's a questionable name, but the underlying concepts are sound and rigorous.
Talking about questionable, let's not forget ChickenTyping.
I'm currently fighting an ancient RubyOnRails application (ancient relative to the Rails scale, at least) with model object inheritance several layers deep represented by "polymorphic tables" (ugh) in the database. The joy here is that each subclass and the parent class are all used in many places, and because there is never a clear declaration of what's needed in a given spot, it is often impossible to tell what is expected except by looking at each method call within the various helpers and controllers to find out what methods are really being called. Over time, the subclasses have gained their own methods, which of course makes it even easier to break something by accident.

Meanwhile, working in ScalaLanguage on a personal project, the ease with which I can describe a function that accepts a subclass that implements a particular interface spoils me:

 trait Barable { ... }
 class Foo extends Barable { ... }
 def f[A <: Foo with Barable](x: A) = { ... }

Every time I run the (painfully slow) RSpec suite to find out if I've broken one of the innumerable subclasses with my change, I think about how easy this would be with static typing.
CategoryLanguageTyping, CategoryTypingDebate

View edit of January 7, 2014 or FindPage with title or text search