What is "duck typing"?

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, but let's recap.

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 as1

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 name2 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".3 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 type4 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:5

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!

  1. I am not a Scala programmer; I might have made some syntax errors here.
  2. or operator
  3. 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.
  4. 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.
  5. and ungrammatically

105 thoughts on “What is "duck typing"?

  1. Interesting. I'd never really thought of the distinction that you clearly illustrate until I started using Typescript, which allows you to do pretty much "static duck typing" - as long as the type of the object supplied to a method can quack and walk then the compiler will allow it. This, to me, is what duck typing is, rather than late binding - I think some C# devs tend to confuse the two is because there is little support for static duck typing in the language, so when people want to do it, they use dynamic.

  2. I saw this show up in the feed for c# chat at Stack Overflow. When it asked "What is duck typing?" I originally thought it was when you took something typed as an object, and then used dynamic as an intermediate step to cast it to a specific type. Sorry if this seems naive or ignorant, but that was what I thought it meant. I usually avoid jargon like this when trying to explain myself. I also generally try to avoid using dynamic, but here is a simple example of what I am talking about.

    public double Average(ICollection list)
    {
    return list.Cast().Average(n => (double) n);
    }

    I thought the approach of casting there was "duck typing" from object to double. I guess that is "late binding" so at least now I know. Thanks for the write up Eric :)

      • It is true that the (double) cast is downcasting. But that wasn't the point I was trying to make.

        The formatting stripped out the generic arguments here. I commented a note on the method signature, but there is one more. The call to .Cast should also have a generic argument of dynamic. Casting to dynamic is an upcast which will cause the binding to occur at runtime. This will then use the runtime binding rules for the downcast.

        My point was: I thought a version of duck typing was when a cast to dynamic was used which caused runtime binding, and then that result was used based on the assumption it would have certain properties.

  3. I think you're right in that it's just a meaningless, confusing term if you try to use it to categotize a specific language. I do however think that Wikipedia explains it quite well though.

    I think the best way to explain duck typing is by stating it's the antonym of static typing...

  4. What you're describing with Scala, where the compiler determines that a type meets certain constraints, is Structural Typing, as also seen in Go, TypeScript and other languages. Structural Typing may be thought of as a kind of compiler-enforced subset of Duck Typing, but I've always associated Duck Typing with dynamic languages, where it doesn't matter what class or prototype an object was instantiated from, only that it has the methods and/or properties that a consumer of the object requires, which is determined at runtime when it tries to access them.

  5. > Or do I have to treat "duck typing" the same way I treat "strong typing"?
    Yes. Why should it be any other way? Something magical about ducks?

  6. Duck typing is a way for code in loosely typed languages to determine whether the object they are processing has a behavior compatible with the operation the code wants to perform.

    A simple case would be an array copying function in JavaScript. Most of the time it may get real honest-to-goodness `Array` objects, but it also wants to allow `Arguments` objects which appear as `Object`s that have a `length` property. So the `length` property satisfies the "quacks like a duck". To narrow the chance of false detection you might check that `typeof obj.length === "number"` since arrayish things shouldn't have non-numeric lengths.

    Like Isaac, I hadn't seen anything similar to duck typing used in a static way until Typescript, but I think they call it something like "structural equivalence". To me, duck typing is where the actual code (vs compiler) has to suss out whether the argument is the right kind.

  7. Duck typing is structural typing. It's mostly associated with some dynamic languages, chiefly Python, which signal an error if the object in question doesn't possess the required method; but nothing prevents a language implementation from enforcing it at compile-time.
    As to why its proponents call it "duck typing", I think it's a combination of ignorance of computer science and a penchant for catchy names for the sake of advertisement.

  8. My understanding of "duck typing" is the same as yours, Eric, and I concur that there is no sense in having a term which is effectively synonymous with "late binding". However, I have seen this term used and abused in so many different ways that I suspect that there is little consensus on what it actually means in the programmer community. In particular, people frequently make little or no distinction between late binding and implicit typing, leading to this sort of confusion.

  9. Someone smarter at Scala can correct me - but I think the reason example "works" is because 'def' isn't a variable declaration like var/val - it holds a function pointer rather than a reference to a value. The structural type-checking is validating the return type of that anonymous function, which is void.

    If you change one of Person's methods to return string instead of void:
    class Person {
    def quack = "The person imitates a duck." // returns this string now instead of printing it & returning void.
    def feathers = println("The person takes a feather from the ground and shows it.")
    }

    The code will not compile.

    In Ruby, if you do the same thing, the code runs fine - the string gets assigned nowhere and won't be printed, that's all.

    So I duck-typing *is* kind of poorly defined. Logically, it is taken to mean 'late-binding w/ no compile-time checks', but the way that it's implemented in non-dynamic-typed languages *simulates* duck-typing, but breaks in some interesting ways.

    I think the difference is because of the difference between what a function-signature means in dynamic vs static languages. In dynamic languages (at the bytecode level anyway), we just carry the name of the method/function & number of parameters. In static languages, I need to worry about the return type & types of parameters.

    So in a static language I can give you something that *looks* like duck-typing, but I have to do compile-time hacks to make it happen. In a dynamic language, it's ducks all the way down, so duck typing just works.

  10. Just because Wikipedia disagrees with you doesn't mean you're wrong... Since Wikipedia articles are community authored, anyone could have written or edited this article, and that doesn't make them right.

    My understanding of duck typing is roughly the same as yours. I think the Wikipedia article confuses duck typing with late binding; and it is indeed confusing, because it contradicts itself... But anyway, I don't think there is an "official" definition of duck typing, any more than there is an official definition of strong typing.

  11. Duck Typing says absolutely nothing about when the type check takes place. C++ templates, for instance, are duck typed:

    template
    void do_things(X const& x) { x.Go(); }

    works for any type X which has a member function Go(). This occurs at compile time (in C++).

    Usually duck typing refers to compile time checks, as you mentioned in your "conception" part of this article; except for those language where run time and compile time are one and the same; e.g. Python.

    • I still don't see where you distinguish between late binding and duck typing here and why c++ templates would somehow not qualify as "late binding".

      • From the definition of late binding in Wikipedia it is done in "runtime". But C++ templates are subject to static binding. Unlike C#/Java generics C++ templates do not pose a type or a function they are just templates and are instantiated upon usage at compile time.

        • Conceptually, the C++ template system is a Turing-complete programming language that generates template-free C++ code. Instantiating a template means invoking a function of that language. Template instantiation *is* the run-time of the template language, and so type-checking is performed at "run-time", i.e. the resulting code is checked against the constraints of template-free C++ code, and an error is raised if the check fails (including a full program stack dump, which is the reason for the huge error messages).

          The difference between that an a typical dynamic language is that it is the output of the program that is checked, not the program itself. But it comes down to pretty much the same thing.

          C++ concepts, then, are an attempt to add static typing to the template system. The previous, failed proposal had both automatic concepts which were fulfilled automatically by any matching type (and thus were structural typing like in the Scala example), and explicit concepts which required an explicit declaration that a type supports them (and thus were more like the nominal type systems that we're used to from C++ and C#, except the binding between an interface (concept) and a type could be established independently of the type definition).

          C++ Concepts Lite, the proposal currently being worked on, dropped explicit concepts entirely and radically changed the way the structural constraints are defined from a pseudo-type syntax (the concept from the original proposal) to a set of more or less arbitrary boolean requirements like "this property holds on the type" and "this piece of code compiles".

  12. > But this is not even typing in the first place! We already have a name for this; this is late binding.

    Then, what would be the difference between "dynamic typing" and "late binding" ?

    > 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.

    "Duck typing" is an expression that is useful when trying to explain how to think in languages like Ruby[1]. It's not the kind of vocabulary that is precisely defined in whitepapers by computer scientists or academists (who usually (dis)regard dynamically-typed languages as being uni-typed, since types are only a static concept to them).

    Still I find the meaning of "duck typing" to be better defined than "strong typing" (but it doesn't hurt to treat it with the same precautions in a discussion).

    How about the following definition: "A language is duck-typed if your sample code that calls Quack() works fine on both objects (independently of whether the method is early or late-bound, with structural or dynamic typing or templates or whatever)".

    [1] : However, the Ruby way is actually not "if it quacks like a duck, then it's a duck". It is really "if it quacks, then I don't care what it is 'cause it's good enough".

  13. I first encountered "duck typing" in Python, a strongly typed language roughly equivalent to all variables being declared with C#'s dynamic. I agree that duck typing's implementation is identical to late binding. However Python only has late binding, and can be written with or without duck typing.

    The guidance in Python towards duck typing is one that eschews testing whether you've been passed a duck (or int or list), and instead prefers just telling it what to do. If it can't do it, it'll raise an exception. Duck typing teaches that it is better to trust the programmer who is calling your function than to build in artificial barriers to using your function in unexpected new ways. If the function takes a file-like-object, tell that object to read() or seek(); don't try to figure out whether it's reading a local, remote, or memory-cached "file," and definitely don't try to do things differently.

    Similar guidance shows up even in static languages like C++ (especially around templated functions such as those taking iterators - a compile-time dynamism, if you will), or almost any language that supports interfaces. And the opposite of duck typing would be a code smell even in C#; making control flow choices by querying if a dynamic variable is a specific type isn't the purpose of dynamic.

  14. Structural typing is the belief that popping a balloon and popping a stack are fundamentally the same operation and should be treated as such by the compiler.

    Duck typing is the additional belief that, when you later replace the stack with a double-ended queue that uses different method names, the balloon-popping code you'd mistakenly used will now crash the program instead of just silently corrupting data.

  15. I somehow agree with Eldc. Duck typing is not about some kind of property of language or it's type system, but about how you think when you design the code. With duck typing, you don't explicitly define interface your code requires, but you write code that calls methods and access properties or attribute on any arbitrary object. And you know that when you pass object that does have those methods and properties, then the code will work. Duck typing is mentality that allows this kind of code.

    Also, I think in case of Python or Ruby, you cannot "statically" analyze this kind of code thanks to magic methods like __getattr__ or method_missing. They completely break any kind of static analysis of the code, yet they allow most of the crazy magic in both of the language.

  16. As I understood it, and especially given the F# and Scala examples, duck typing is structural typing regardless of when the call is bound. Instead of considering the type hierarchy when determining type validity for a given use case, only the required contracts are considered. That said, however, I think it's safe to say that the term is poorly defined and analogous in that way to "strong typing".

  17. When I think "duck typing", especially in relation to C#, I think of how `foreach` is handled. As long as the thingy on the right side of the `in` keyword has a method called `GetEnumerator()` which only has to return a type which has a property called `Current` and a method called `MoveNext()`. No interfaces need to be implemented (though idiomatically, you would), but the compiler automatically figures out if it can be `foreach`ed or not.

    • This is a very good example.

      If you create your enumerable type so that you do not implement all the required methods, you get a *compile-time* error (foreach statement cannot operate on variables of type 'FakeEnumerable' because 'FakeEnumerable' does not contain a public definition for 'GetEnumerator').

      This seems to comply with Eric's definition of duck-typing. Definitely not a late-binding style definition implied by Wiki article.

  18. I always thought that duck typing means "runtime-types are defined by collections of method names and their properties - an object is in a runtime-type only if it has these methods with their properties".

    Well I've also thought that strong typing means "non-well-typed operations immediately cause well-defined errors".

    And static typing is a proof system for well-typedness - which is also used to [automatically] insert conversions and resolve names [so that the programmer won't need to].

  19. I think most people would agree that "duck-typing" refers to this kind of structural typing that you refer to. Whether it occurs at compile time or runtime really doesn't matter at all. In Ruby, you can add methods on to an object at runtime, thus performing dynamic ducktyping. In TypeScript, the duck-typing, and in fact most of the type system, is purely compile time. Why don't you edit the Wikipedia article and make it more precise, Eric?

    I'm interested to see if the C# team explores bringing more structural typing to the language. It is really useful in TypeScript, and is the thing I miss the most when I have been writing some TypeScript and then go back to C#.

  20. I don't really know... But I think most people got the "duck type" system upside down, as far as I know "duck typing" is an expression. created to describe javascript type system (or lack of one, by your definition), not a "feature" languages are designed around or to support.

      • Unfortunately, I didn't get very far at all due to difficulties modifying the Mono C# compiler in a rational way. Now that the Roslyn/.NET Compiler Platform has been made open-source, it might be time for someone to take up the mantle again! I'm unlikely to have the time myself.

  21. You explain something like Duck typing on Wikipedia from its first, and continued use in the dynamic scripting language community; and then everyone tries to muscle in!

    It is a wikipedia page that is beset by by people that can't bear to have their favourite language possibly excluded from a wp page. (Hence the F# quote for example).

    I would suggest you learn Python or Ruby, (or, ...?) and when you graduate to some proficiency ask around their communities about Duck typing.

  22. F# does in fact have a form of compile-time static duck typing. Its called "Statically Resolved Type Parameters".

    Using your example with an additional Wolf class ...

    type Duck() =
    member x.Quack() = "My name is daffy"
    member x.Walk() = 3

    type OtherDuck() =
    member x.Quack() = "Quack, quack, quack"
    member x.Walk() = 7

    type Wolf() =
    member x.Think() = "I see some yummy ducks!"
    member x.Walk() = 10

    // A function to call the Quack and Walk methods
    let inline M(bird: ^a) =
    let sound = (^a : (member Quack: unit -> string) (bird))
    printfn "The bird said \"%s\"" sound

    let steps = (^a : (member Walk: unit -> int) (bird))
    printfn " It took %d steps" steps

    let duck, otherDuck = Duck(), OtherDuck()
    let wolf = Wolf()

    M(duck) // Legal
    M(otherDuck) // Legal
    M(wolf) // Compile time error: "The type 'Wolf' does not support any operators named 'Quack'"

  23. As an aside, I find the homophony between "duck type" and "duct tape" interesting. I don't know whether or not it's accidental.

  24. Throwing in with the "it's just Wikipedia" crowd: your apprehension of the term's general meaning is correct, though it's also not actually any kind of typing system. It's about the semantics available to the programmer, regardless of implementation. (One might induce widespread groaning by suggesting that duck typing is duck typed.) Late binding allows duck typing, and so does compile-time type inference. So the answer is "all of the above," and Wikipedia is just suffering from its usual committee issues.

    Gonna hijack the topic now, for a minute. :) I'm a hobbyist coder with zero formal education in the field, and while I've been at it for decades and picked up plenty, I lack many of the fundamentals expected of an educated programmer; for instance, I've never written a compiler. My awareness of modern practices tends to be five or ten years out of date, and I usually pick up languages right after they stop being cool.

    With all that said, I really enjoy C#. It's not perfect by any means, and I miss stuff from other languages, but more often than not I can find a way to work with it that matches up to my own (thoroughly unorthodox and largely just wrong) idioms and preferred paradigms. I tried Java (back in the 1.x days), learned what objects are, but absolutely hated the language. Later I discovered Smalltalk and discovered how objects can be beautiful, but couldn't get much done because it plays in a cramped little sandbox. I started learning C# a few years back because of XNA, expecting very little of it, and I've been blown away: Smalltalk spoiled me against compile-time typing, but C# has actually swung me back around.

    There are hiccups, though. In a fit of frustration I recently wrote the following (ooh boy, let's see if I tagged this up right):

    public abstract class BlackBox>T> {
    public abstract T Value {get;}
    public static implicit operator T(BlackBox>T> box) {
    return box.Value;
    }
    }
    public sealed class ImplicitBlackBox>T> : BlackBox>T> {
    T value;
    public override T Value {
    get { return value; }
    }
    public ImplicitBlackBox(T value) {
    this.value = value;
    }
    public static implicit operator ImplicitBlackBox>T>(T value) {
    return new ImplicitBlackBox>T>(value);
    }
    }

    I almost named this Duck>T> but opted against the snarky moniker. The point here was to have a type which could be used interchangeably with numeric values, whose value depends on factors which are outside of (and otherwise irrelevant to) the scope in which it will be used. This is for an RPG-style game system, and brings all sorts of convenience to both conditional modifiers and randomization.

    I would have liked it to be an interface, allowing struct implementations (which the Implicit version should be), but then I couldn't define the operator. And this is only necessary because there are no extendable pre-boxed versions of the numeric types, nor anything like INumeric>T> (in fact there's not even a way to limit T to numeric types).

    So, this seems to be a place where C# offers nothing that anyone might call duck typing: I can't make something that quacks like an integer, the closest I can come is making integers quack like something else and using the latter thing for all my arguments and variables (though at least returns can still be plain values). That is unless I've missed something, which is very possible.

  25. Well, reading your blog has probably influenced my understanding of duck typing over the last few years, so my comments may not be of any help :) But I'll try anyway.

    I agree with you that wikipedia is referring to late binding, but I do think duck typing is something different. I've always just taken its meaning literally, sort of like "typing by convention".

    If it walks like a duck:

    class Duck { public void Walk(); }
    class It { public void Walk(); }

    And it quacks like a duck:

    class Duck { public void Walk(); public void Quack(); }
    class It { public void Walk(); public void Quack(); }

    The it's a duck:

    class Foo
    {
    void Run(Duck duck) { ... }
    void Bar()
    {
    Run(new It()); // Legal
    }
    }

    I would expect that the compile-time type AND the corresponding runtime type that is passed to Run would be Duck. Obviously this code doesn't compile in C#, but to truly support "duck typing" as I understand it, perhaps the compiler would have to create an anonymous type to act as an adapter between Duck and the It object that was passed in as a Duck.

    class ItDuck : Duck
    {
    private readonly It it;
    public ItDuck(It it) { this.it = it; }
    public void Walk() { it.Walk(); }
    public void Quack() { it.Quack(); }
    }
    ...
    Run(new ItDuck(new It())); // Actual compiler output

    Essentially, when Run asks this Duck to Walk or Quack, It Walks or Quacks.

    I'm not sure what the compiler would do here if Duck was sealed though :)

    Of course, this example is statically typed, but that's not entirely necessary.

    void Run(dynamic duck)
    {
    var d = (Duck)duck; // Succeeds
    }
    ...
    Run(new It()); // Legal

    Perhaps this "typing by convention" would require an additional keyword or a special FCL type? (Assuming it's even a good idea in the first place, which I'm not entirely sure.)

    void Run(loose Duck duck)
    -or-
    void Run(LooseType duck)

    • Oops, the very last example was actually supposed include generics like this:

      void Run(LooseType{Duck} duck)

      (The curly braces {} indicate a type parameter. I don't think the blog supports )

  26. Hi,

    First off, a happy new year to you too.

    Secondly, take a bow for your modesty - not many people openly accept they don't understand certain concepts.

    Thirdly, could you pls do a follow-up post on this topic that settles the confusion?

    Thx!

  27. Eric, what you are demonstrating as duck typing in Scala is static typing + type inference + some form of the C++ "concepts" that are basically interfaces for generic programming.

    The name "duck typing" is a joke for no typing and is already reserved for late binding in the common CS literature. I would not confuse my readers with comparing late binding to a quite free-form early binding in Scala.

    C# duck typing is the dynamic type. C# generics are a failed attempt of adding concepts into generic programming. It is a pity you cannot add a concept to a type without recompiling it.

  28. Wow, so many comments, so many opinions, but nobody stating the obvious, namely that your last paragraph hits the nail on the head. Duck typing means different things to different people. This is probably due to the fact that neither a lawyer, nor mathematician, or any other kind of academic properly defined the term. The Wikipedia article lacks coherence, so maybe it's better to steer away from the term and rather use statements like "structural typing", "late binding", etc.

  29. I wasn't familiar with the term before now (I think I may have heard it but not really cared about it). I am however now convinced that if anybody uses the phrase to me that I will ask them to clarify exactly what they mean by it (if I feel it is important and that context of the conversation won't actually make it clear what they mean).

  30. Duck Typing is a catchy term, since it neatly brings in "If it walks like a Duck..."

    As such It should cover all the myriad ways such functionality can occur. The key part is to recognise that it is talking about particular examples of something: If *it* walks like a duck. This it only makes sense in situations where you have say: an actual instance of the object, a variable which may contain them etc.

    Formalising it somewhat:

    If a value, in a specific context, is able to perform the named individual operations requested (regardless of the correctness of attempting to do so), using only the signature of the operation then then it is deemed to to be legal to use that operation. There may be several such operations required for the value to be deemed appropriate for all usages within that context, though detection of this need not be eager.

    If the duck typing occurs at compiler time then the specific value in question will be a variable or constant whose compile time known operations form the subset of operations which will be considered for determining if the value is appropriate.
    If it is instead done at runtime then it is possible (and probable) that the operations available to the actual value passed in will be considered. In languages with a type hierarchy of some form you might be able to pass multiple different instances who share a common sub type, thus some attempts may succeed, and some fail.

    The provision of these operations need not just come from the instance itself, if operations may be defined on values of a specific type by some other code (extension methods/monkey patching/mix ins to name but a few) then these may also be considered. In a language with truly dynamic dispatch (for example in an OO language where an operation may be created as the result of seeing a particular message) it is feasible that the instance itself might be allowed to determine if the operation is deemed to be present, by the act of attempting it.

    some clarification for two terms used:
    "signature of the operation" this is inherently dependent on the expressiveness of whatever compilation environment/runtime environment provides. In C++ the signature is quite literally "does it compile if you stick the text in". In the c# examples it may look at the return type/arguments, or it may not. In many dynamic languages you get nothing but the name and the runtime values. regardless, you get a name and perhaps some other type information to make the decision.

    I say "specific context" because Duck Typing is not constrained to just the classic parameters to a method. Again the macros of C++ might apply to the constrains to almost any aspect of a legal C++ source file. the key thing is that the context may well alter the decision of the subset of operations available (especially in regard to operations being defined externally to the type).

    Late binding then, is simply language support which allows one to do Duck typing, based on the runtime type, rather than the compile time type. It should not be considered to be the only way it can occur, but it is an easy to provide example, which is why it tends to be conflated with the concept.

  31. To me this is similar to the difference between calling a method of an object and passing a message to an object. In languages like Java or C they are the same thing since the compiler/linker makes sure that the required method exists and it was only years later when I tried some scripting languages that I could see the difference.
    Duck typing means that the check will not be made until runtime and it may be possible that the message does not exist. This may or not be an error, I believe that Objective C allows unhandled messages to be quietly ignored.
    The point of Duck-Typing is that some languages don't care too much about the type of the object that you are calling, only whether it can respond to the message that you want to send to it.

  32. Object oriented programming as advocated by the original inventor of the phrase (As far is know Alan Kay). Favors the duck typing side of the argument, I am not sure that either argument is true, whenever I try to program in haskel the trendiest language invented for typing, but if u go down that road u might read up on agda and coq and those are also interesting, I am not saying I don't like C# at all but every time i write something in javascript which is a mediocre example of the original reason of duck typing, I find it easier, quicker and simpler, that may be because u are smarter than me. Its a shame that smalltalk did not take on for longer, and an even bigger shame for self, but the same could be said for every other choice

  33. I'd have to agree with your definition of Duck Typing, and not Wikipedia's. It does come in handy when working with anonymous objects.

    To throw another language into the mix:

    Dim customerNames = From c in Customers Select New With {c.FirstName, c.LastName}
    Dim employeeNames = From e in Employees Select New With {e.FirstName, e.LastName}
    Dim carNames = From c in Cars Select New With {.FirstName = c.Make, .LastName = c.Model}

    Dim allNames = customerNames.Union(employeeNames).Union(carNames).Distinct()

    The union can't happen if the fingerprints of the anonymous objects weren't identical. I would consider this to be an example of Duck Typing as I understand it.

  34. I think what you thought of as duck typing is what Go calls structural typing, which,I pretty like.

    Besides, many people also confuse type inference and duck typing...

  35. Lot of comments already and I don't want to rehash it all, but I will say that I don't think that C#'s interfaces really exhibit the spirit of duck typing. Some of the confusion might be because of the direction of the implication.

    Considering the usual example "If it walks like a duck and quacks like a duck then it's a duck":

    C# interfaces: An IDuck is a duck, therefore it has Walk() and Quack().

    Colloquial "duck typing": An arbitrary object Foo has methods Walk() and Quack(), therefore it is a duck.

    I believe, but could be wrong, that to most people "duck typing" is more the second (late binding, as you said). The reason I'd guess this is that the idea lives most strongly in dynamic languages such as Python and Ruby where static contracts like a C# interface are uncommon (if present at all).

    • The detail which prevents interfaces from really embodying duck typing is that while one can define a composite interface IFooAndBar which inherits IFoo and IBar, only types which *expressly* implement that interface can be cast to an IFooAndBar--types which implement IFoo and IBar but do not implement that interface cannot. If interfaces which inherit other interfaces but contain no members of their own could be tagged with an attribute such that the runtime would allow any type implementing a combination of interfaces to be cast to the composite interface (using magic similar to that which allows a Cat[] to be cast to IEnumerable[Animal]) that would be much more like duck-typing.

  36. I think that the difference is really a difference of point of view:

    "Late Binding" refers to the fact that the runtime will look up methods according to its name and possibly additional information, at the time when the method is effectively invoked;
    "Duck Typing" refers to the fact that some part of a program will take any "object" that looks like it fulfills a given contract, that may exist as some piece of static information (Scala, F#'s structural typing), or that may not exist outside of the documentation (Python's handling of file objects, of iterator objects).

    Example of Late Binding without Duck Typing: In Python, if you receive e.g. a parameter, and you check that it is a String before proceeding, then you have late binding (because every method in Python is late-bound), but you do not have duck typing, because objects that look like strings without being strings would be rejected.

    Example of Duck Typing without Late Binding: In C#, foreach/await usage requires that the target object expose a GetEnumerator()/GetAwaiter() method that returns an object with the appropriate members (MoveNext()+Current/INotifyCompletion+OnCompleted+IsCompleted+GetResult()). You will note that only part of that contract is expressed as a static interface - which is why that is considered Duck Typing. But the compiler generates code to statically bind to the methods of these objects.

    Now, in C#, it is pretty rare that duck typing is used - the thought being that, in general, if it is worth having a contract, then it is worth having a type for it. I suspect that duck typing was used in these cases because it had no negative performance impact, and it allowed the BCL to return structs for these methods while avoiding boxing.

  37. I think the original newsgroup post is enlightening on this topic: https://groups.google.com/forum/?hl=en#!msg/comp.lang.python/CCs2oJdyuzc/NYjla5HKMOIJ

    To summarize the question that was asked, how do you handle method overloading with a single parameter in a dynamic language?

    The proposed answer is to look at the various cases your code requires from the arguments and see what case your argument meets. Say there are three cases. Case Duck, Case Cat, Case Fish. If the object has methods needed to fulfill the requirement to be a Duck, you fall into that case.

    Not much else you can do with dynamic languages here. It's not exactly the same as late binding because your branching based on the set of methods and properties. You're not just blindly invoking these methods.

    As I'm learning F#, I find the concept of structural typing to be more interesting. Someone linked to my blog post about duck typing and it turns out I didn't have the vocabulary at that time to say what I really find interesting (for static languages at least) is structural typing. :)

  38. I've always thought of duck-typing as being able to substitute an instance of one type for an instance of another (usually unrelated and perhaps implicitly defined) type in any expression, where the substituted instance has, at minimum, a set of properties/methods that match those used during the evaluation of the expression.

  39. A type system could support run-time duck-typing without late binding if the type system supported types which combined interfaces. For example, if the same sort of magic which allows a Cat[] to be regarded as implementing IEnumerable(Of Animal) would allow a special CompositeInterface(Of T,U) to be regarded as an implementation of T and U, and also allow any type which implemented T and U to be cast to CompositeInterface(Of T,U) then that would represent a form of run-time duck typing since one could have a List(Of CompositeInterface(Of IWalk, IQuack) to encapsulate the identities of things that walk and quack, and anything which implemented both IWalk and IQuack could inherently be cast at run-time to allow storage in the list. Note that this would be duck typing (if it walks like a duck and quacks like a duck, it can be used like a "thing that walks and quacks") but would not require late binding.

  40. I thing the key difference between duck typing and structural typing is in how and where the checking takes place, regardless of runtime vs. compile time differences.
    When you do structural typing, checking will always occur at the call site - when calling a function and passing it an object, the compiler/runtime system will check if the object's (compile time/runtime) type matches the type declared/inferred for the function's parameter.
    With duck typing however, the check should occur at the place of usage: when calling one of the object's members inside a function, the compiler or runtime system will check if the type of the object has a way to perform the required operation.
    This has important consequences if all of the checks are done at runtime: if you only check code that is actually run, a function can do different things on different branches, and so accept different "types" of objects for these branches.
    There are also some important consequences of this distinction even if all checking is done at compile-time: a system with structural typing will have better error messages than one with duck typing. This is exactly the problem C++ templates are facing, and why the standard committee tried to push Concepts to allow structural typing in templates. Since compatibility checks are only done at the call site, errors in recursive/nested templates can only be shown at the bottom-most(implementation) level, instead of the top-most (interface) level.

    • I don't think duck-typing would preclude call-site validation, if the definition of a parameter listed all the things it had to be able to do, and methods were only allowed to use parameters in ways that were declared. If a method could be declared as accepting a parameter of type `{IWalksLikeDuck,IQuacksLikeDuck}` and could accept a `RoboDuck` which implements those members but has no relationship to `Duck` other than inheriting a common base type (perhaps `Object`) which does not implement the interfaces in question, I would regard such a feature as "parameter duck-typing" even though parameter-type compatibility could be validated at call sites.

      • My point was that what you are describing already has a perfectly good name - "structural typing" - and it doesn't make sense to extend "duck typing" to include this as well.

        I think that most people would be surprised to hear you call a language "duck-typed" if it couldn't do this:

        function f(cartoonCharacter)
        {
        if (cartoonCharacter.Name == "Donald")
        {
        cartoonCharacter.Quack()
        }
        else if (cartoonCharacter.Name == "Goofy")
        {
        caroonCharacter.Bark()
        }
        }

        In a language with structural typing, this function couldn't be called for any object, since no animals can both Quack() and Bark() ( :) ).
        However, in a language with (runtime, in this case) duck typing, as long as anyone named Donald can Quack() and anyone named Goofy can Bark(), everything would just work.
        Of course, in a language with compile-time duck typing (e.g. if this were a C++ template), you would have the same problems as you had with structural typing.

        • Under what I was describing, the method signature would be [imaginary syntax] "function f(cartoonCharacter as {IQuack, IBark})", and the method would accept anything which could do those things. At first glance that might not seem different from (using brackets for greater/less) "void f[T](T cartoonCharacter) where T:IQuack,IBark", except that if one had a "List[{IQuack,IBark}]" one could pass items from that list to such a function without a typecast, and given a "List[Object]", one could pass items to the function by using a narrowing [i.e. not-guaranteed-to-succeed-at-runtime] typecast to "{IQuack,IBark}". Using the typed list would have the advantage that if things in the list will have to quack and bark, and code tries to add something to the list which can't do both, the mistake would be detected before the invalid item is added to the list.

          In a sense, one can run-time duck-type anything in C# by simply casting to an interface anytime one wants to do something. If one wants to make myThing quack, simply say "((IQuack)myThing).Quack()" and it will either quack or throw an exception. The need to name an interface doesn't semantically change what can be done. Rather, it merely provides a chance to distinguish between e.g. IArithmeticSummable[Int32].Add(23) and ICollection[Int32].Add(23); if as a matter of course every time one created a method "Add[Int32]" one created an interface "IAdd[Int32]", and when calling such a method cast to that interface, the interfaces would be semantically redundant with the method names, but allowing the interface names to be distinct allows different functions which would be described using the same words (e.g. "add") to be recognized as different.

          • If you were to infer the type of "cartoonCharacter" in my example in a duck typed system, you wouldn't end up with {IQuack, IBark}, you would end up with {Name=="Donald"?IQuack; Name=="Goofy"?IBark; Anything}. There are many objects that can be said to be of this type. For example "null" implements this type :) (assuming "null.Field" returns null, instead of throwing NullReferenceException).

            Of course, trying to deduce this type (or using it in any way even when you succeeded) is probably impossible. However, if you are able to achieve this, instead of deducing {IQuack, IBark}, you're program can now do something that it couldn't otherwise - it can call this function with this object: new Duck(name: "Donald"), and with this object: new Dog(name: "Goofy"), and even with this object: new Car (name: "Honda") (doing nothing).

            Now, what I'm saying is that any language which allows you to call this function with an object that implements my deduced type is "duck-typed". Any language which only allows you to call this function with an object that implements your deduced type is called "structurally typed".

            Note that you could still have a compile-time duck-typed language by this definition. However, it would require that Name be a compile-time constant for any object that should be used with this function, so that the compiler can check it's value.

            I also really like your second observation. I'd never thought of using the unified type system for that - it's a really fun idea.

          • Here's an example of doing what I was describing in C++, showing why templates for a duck typed language:

            #define Donald 0
            #define Goofy 1
            #define Honda 10

            template
            class F
            {
            void operator()(T cartoonCharacter)
            {/*do nothing, like in my example.*/}
            };

            template
            class F
            {
            void operator()(T cartoonCharacter)
            { cartoonCharacter.Quack(); }
            };

            template
            class F
            {
            void operator()(T cartoonCharacter)
            {cartoonCharacter.Bark();}
            };

            template
            class Duck
            {
            void Quack()
            {
            }
            };

            template
            class Dog
            {
            void Bark()
            {
            }
            };

            template
            class Motorcycle
            {//can't bark, can't quack
            };

            void main()
            {
            Duck duck;
            Dog dog;
            Motorcycle motor;
            (F())(duck); //will Quack()
            (F())(dog); //will Bark()
            (F())(motor); //will do nothing
            (F())(motor); //will give an error at compile-time, since objects named Donald must know how to quack,
            }

          • #define Donald 0
            #define Goofy 1
            #define Honda 10

            template<typename T, int NameCode>
            class F
            {
            void operator()(T cartoonCharacter)
            {/*do nothing, like in my example.*/}
            };

            template<typenameT>
            class F<T, Donald>
            {
            void operator()(T cartoonCharacter)
            { cartoonCharacter.Quack(); }
            };

            template<typenameT>
            class F<T, Goofy>
            {
            void operator()(T cartoonCharacter)
            {cartoonCharacter.Bark();}
            };

            template<int NameCode>
            class Duck
            {
            void Quack()
            {
            }
            };

            template<int NameCode>
            class Dog
            {
            void Bark()
            {
            }
            };

            template<int NameCode>
            class Motorcycle
            {//can't bark, can't quack
            };

            void main()
            {
            Duck<Donald> duck;
            Dog<Goofy> dog;
            Motorcycle motor;
            (F<Donald>())(duck); //will Quack()
            (F<Goofy>())(dog); //will Bark()
            (F<Honda>())(motor); //will do nothing
            (F<Donald>())(motor); //will give an error at compile-time, since objects named Donald must know how to quack,
            }

          • My reason for favoring interfaces is that an object may have multiple abilities or traits which share a name; for example, a PolyLine which encapsulates a list of vectors might be viewed as as list whose "Length" is the number of vectors, or as a linear shape whose "Length" is the combined magnitude of the vectors therein. Code which receives a PolyLine as a {IReadableByIndex(of IReadableCoordinate), ICountable} and calls `Length` would get the number of vectors; code that receives it as an `{ILinearShape, IDrawable}` and calls `Length` would get the combined magnitude of the vectors.

            As for the ability to have an object's properties affect what abilities are used, one could simply have the signature include things that are known to be required, and perform a cast at run-time if other things are needed; if the necessary abilities don't exist, the cast would fail. It might be nicer to be able to specify "maybe" abilities in a parameter list, with the semantics that if `maybe(IQuack)` was included in a parameter list, any class which implemented IQuack would implement the members of `maybe(IQuack)` just like those of `IQuack`, while a class which didn't would implement the members of `maybe(IQuack)` to throw `NotSupportedException`, but that would probably add considerable bloat to the type system.

  41. Pingback: Les liens de la semaine – Édition #62 | French Coding

  42. Hey Eric,

    Your Scala code is almost perfect. You just need an = sign after the method signature and before the first open bracket for it to be syntactically correct:

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

  43. What is present in most dynamic languages that are characterized as duck-typed cannot be called "typing" in any nontrivial sense.

    In C#, once you have a "string" object (verified by the runtime type system), you know what kind of operations you can perform on it (guaranteed to be meaningful by the static type system); nothing in Ruby or Python makes such checks on your behalf or gives you any guarantee - the only checks performed are on the level of a single invocation and it makes no more sense to call that "typing" than to call the empty string a separate type of string because it raises an exception on .Substring(1).

    To reason about the supported operations on an object you have to query it explicitly or examine it's type - but that's not a "type system" any more than checking string.Length against zero.

    • > What is present in most dynamic languages that are characterized as duck-typed cannot be called "typing" in any nontrivial sense.

      I really have to disagree with your choice of words here.

      What you call "typing" is actually called "static typing". Javascript, Ruby and Python use "dynamic typing". They represent a totally different idea and purpose, and should not be confused.

      As static typing has been extensively studied in academia, it is totally ok that people that study Computer Science and write papers just say "typing" to refer to static typing -- because Computer Science do not interests itself in dynamic types that cannot lead to proof about programs.

      However, there is also the side of practice. One should not forget that programs written in dynamically-typed languages exist, and that they do make use of dynamic types to store metadata about the runtime instances, and that all of this is used and useful.

      So, when both world meet, as in discussions about "duck typing" (which is not a clearly defined Computer Science term), I think that a big part of the confusion would be avoided by simply disambiguating between static types and dynamic types.

      For example, as a (sometimes) user of dynamically-typed languages, I feel kinda offended when you say that duck typing is not typing. But were I to read a modified version of your comment where every occurrence of "type" is replaced by "static type", suddenly your comment would become perfectly correct to my eyes.

      Let's read again a modified version of your first sentence :

      > What is present in most dynamic languages that are characterized as duck-typed cannot be called "*static* typing" in any nontrivial sense.

      Now it's good!

      • @Eldc, I meant and still mean exactly what I wrote - there is no typing framework, static or runtime, that does any nontrivial work on your behalf. And no, tagging objects with their constructed type isn't enough. Consider the following Python fragment:

        if foo.bar():
        foo.asfd()
        else:
        foo.moo()
        end

        Semantically, the above is valid if either 1) foo's runtime type defines "bar", which returns a bool, and 2) foo's runtime type defines "asdf" or "moo", depending on the output of bar. Not only will bar() be executed regardless of the validity of 2), the validity of the entire code fragment may change at runtime for the same object instance. Any and all checks for such conditions are up to you, hence no "typing system".

        • Your example of how dynamic typing does not statically enforce anything sits well with the differences I see between static typing and dynamic typing. Obviously types in Python are not part of a static type system, but they are certainly part of a dynamic system, whose goals do not even include static proof.
          I would like to understand how to explain my point better, but it seems this will remain fruitless. Oh well. I continue to blame the choice of words.

          • I'm sorry but I believe you're missing my point by concentrating on "static"-ness, whereas I'm arguing about what is required for a typing "system" to be said to exist in the first place.

            A meaningful example of a *dynamic* type system would take the fragment above and validate it at runtime, before any of the code is executed - for example, when the containing method is entered (of course since objects are fluid, this could still be broken, but it does provide some nontrivial safety net). We don't even get that, so what's the point of talking about a typing system in the first place? What is your definition of a typing system?

  44. Pingback: Interesting stuff about Duck Typing | Code Mischiefs

  45. I think it can be summed up like this: Duck Typing is an "After the Fact" assessment whereas Static Typing is a "Before the Fact" assessment. In static typing, we can achieve in two ways - via an interface or a class. A class will state what an instance or its children will have. With an interface, it states what something *can* be at least in part. Both of these determinations can be made before they exist. With Duck Typing, we only know what something is until after it has been created.

    In a duck type world, if I have all of your members, we are of the same type. I may have additional members, which makes me a more specialized type of you - but we are still of the same type. In the OO world, to be of the same type, we have to share some common lineage, either via a class or interface inheritance.

    A good analogy is this. In the old days of the British Aristocracy, to be *of* them, you had to be born into it (inherited). Even if you had as much money, property, an estate, etc (AKA you looked like them) - you would never be of them. But if it was a duck type world, then you would be of them since you had all the same semantics.

  46. This discussion missed a key element of Duck Typing, which is that you can add a new method to the type at runtime:

    var x = 7;
    x.Triple() = function() { return this * 3; }
    var y = x.Triple(); // y is 21

    // This function turns any object into a Duck
    function MakeDuck(something)
    {
    something.Quack = function() { alert("Quack"); }
    something.Walk = function() { alert("Walk"); }
    }

    var x = "dog";
    MakeDuck(x);
    x.Quack();
    x.Walk();
    // This instance of "dog" is now also a duck

    TypeMock and Castle Dynamic Proxy add Duck Typing to C#. I found TypeMock to be phenomenal for creating mock objects.

  47. Pingback: Programming 이슈. 1월 1주 | devgrapher

  48. The way I see it is this:

    Duck typing is a form of typing in which type correctness is verified by the actual use of the object at the use spot (rather than contracts present in its declaration). This may take the form of:
    1. Constraints expressed on-the-spot (and by that I mean constraints that are not expressed in a formal interface acting as a contract in the object's declaration), which can be verified using compile-time analysis (but this is an implementation detail) or
    2. Direct (unconstrained) usage, the legality of which is verified completely at runtime, using some form of late binding, as you've said (again, this being an implementation detail).

    Now, I recognize that the quotations you picked from the Wikipedia page are contradictory, as you've pointed out, and I definitely can't speak for the author(s) of the page, but the above is what I think they meant and how I think of duck typing. (...And I might be dead wrong or contradicting myself without realizing it, as well!)

  49. > it seems perfectly reasonable to have a duck-typed functional language or procedural language.

    I suspect any functional or procedural language that you think it seems reasonable to have duck-typing in is also an object-oriented language by a sufficiently expansive definition of "object-oriented".

  50. You're conflating two different issues in binding of a call.

    1. Is binding done using the static type of the expression or the dynamic type of the object?
    2. Is binding done by the method's name or signature?

    In C#, you have (static, signature), (dynamic, signature), and (dynamic, name).

    (static, signature) - A call to a non-virtual method
    (dynamic, signature) - A call to a virtual method
    (dynamic, name) - Use of the "dynamic" keyword

    Duck typing corresponds to (*, name)

    There's a form of duck typing which is not dynamic binding or late binding. C# does not have it, other languages do. It's the fourth tuple:

    (static, name)

    It applies only to generic code, and it means that method resolution is done based on looking for the named method in the actual compile-time parameter type. In constrast to .NET generics where, as we know, overload resolution uses the constraints, and then the method matching that signature is used from the actual compile-time argument (where signature is equivalent to vtable slot -- it includes "what function I overrode" as well as argument types).

    MethodBase.IsHideBySig seems like a related concept.

  51. I like that compile-time view of duck typing. Just being able to call everything on every object and risk runtime failures is not a solution for a language like C#.

    What I like is the definition of interfaces on the call side instead of the classes themselves like in the Go language (I've just had a short look at the language but that caught my eye). At least that's a good thing in some situations where we want to have an abstracted view on the behaviour of sealed classes or just want to avoid subclassing from 3rd party classes to make them fit to a certain interface.

    Might there be a chance to get language support for automatic proxy generation or something like this in a future version of the C# compiler? Or are there remarkable drawbacks or problems implementing such explicit duck typing support in a .NET language?

  52. Thank you for this interesting post. My understanding is that duck typing is largely akin to structural typing and is defined by when binding occurs. The Wikipedia definition seems to conflate duck typing with late binding as you say. This is probably because the term is often used in the context of dynamically typed, late-bound languages such as Python.

  53. Pingback: Programming 이슈. 1월 1주 | TDD

  54. Pingback: Patos y código C# | Mouseless Me

  55. In all the discussion nobody seems to be bringing up semantics. I thought everyone kind of knew that duck typing refers to the idea that any object that conforms to an implicit contract (e.g. that has a certain set of methods) is accepted as a duck and all the comparisons with static typing or any typing at all are beside the point.

    My impression was that duck typing talks more about something like "behavioral subtyping", e.g. it's important what happens once quack() is actually called, not whether quack exists. That's what I got out of the "don't check whether the object has quack()" lingo in the old quote.

  56. Long-time Python programmer here.

    tl;dr Duck typing is based around conventions, written in the docs instead of code. This allows the language to defer the type system.

    You're not actually too far off. Like the distinction between static and dynamic languages, there's also a "static" and "dynamic" concept of duck typing, which isn't often discussed.

    You nailed "static" duck typing with "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." The obvious advantage is that you catch some problems at compile-time.

    With "dynamic" duck typing, the concept is the same, but you don't get the compile-time check. Late-binding is the mechanism here. (And so, as you pointed out, they are equivalent on a technical level.) The difference is subtle. With duck typing you start giving explicit names to these "types" and describe them in the docs, function docstrings, and with argument name conventions. And you can verify them at "test-time" with some good tests. There's no assumption about what you mean when you say a variable is "late-bound" though. Other than "try to use these members when the time comes." Usually you do have one or more language-defined types in mind with late-binding.

    For example, in Python you have "Iterator types" [1]. The only expectation, as per the docs [2], is to provide an __iter__ method. Any function that takes a an "iterator" object, as indicated in its name, docstring, etc, then you'd better pass it an object you can iterate over. File objects are a little more complicated, but notice the docs still only require a handful of methods for a type to be considered "file-like" [3]. The Python community does understand the importance of type inspection though, so they added Abstract Base Types [4] in 2.6 to help in a more consistent way.

    Now the question is "why would I ever do this?" I'll try to give a practical answer. It's simply because we haven't discovered a better type system. It's deferred until we do. With duck typing, you say an object is an X, but you don't encode what that means into the language directly. Rather, you describe it in your docs and verify it with your tests. This is easy to do in Python because of its late-binding. If Python did implement "inferred interfaces," that would restrict the language from adopting a better approach later, such as pysonar [5]. (Also, I don't think some of these techniques were around / popular at the time Python introduced duck typing. Or it was too much work. One difficulty is that Python is interpreted, so when would these type checks happen? And how would you do this across all modules, since imports are resolved at runtime?)

    Hope this helps.

    [1]: http://docs.python.org/2/library/stdtypes.html#iterator-types
    [2]: "One method needs to be defined for container objects to provide iteration support"
    [3]: http://docs.python.org/2/library/stdtypes.html#file-objects
    [4]: http://docs.python.org/2/library/abc.html The Rationale section is a good read on the philosophy
    [5]: http://yinwang0.wordpress.com/2010/09/12/pysonar/ is an interesting approach. It's big though. Not something Guido would have wanted to do because it involves a lot of research and would have delayed Python. Worse, if he didn't get it right, the language surely would have failed. I'm sure there will be even better techniques in the future. Verifying Turing-complete code is, well, hard.

  57. Pingback: What is “duck typing”? | Fabulous Adventures In Coding | josephdung

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>