On Duck Typing

Update: Phil Haack just posted his own reflections on Duck Typing which by the way has a much cooler title than mine!

Another Update: A coworker on my team just passed me an awesome video from Daniel Spiewak describing the fundamentals of type inference. As part of the the talk he describes how structural typing works in Scala. I didn’t realize how much type inference ties in here, but it appears to relate very strongly. Near the end he also talks about Duck Typing as well. If you are a language geek or want to just understand the nuts and bolts, watch it: http://screencasts.chariotsolutions.com/uncovering-the-unknown-principles-of-type-inference-

Happy New Year everyone!

Recently Eric Lippert (One of the fathers of C#) had a nice post entitled “What is Duck Typing?”. In the post Eric looks at Duck Typing and tries to clarify what it is or isn’t in particular critiquing the Wikipedia article on the topic. His conclusion is that Duck Typing is not a special type system and it is either another name for late-binding or completely meaningless. You should read it!

I’ve been working with Duck Typing for a while, more recently the past few years as I’ve been working mostly with dynamic languages. I agree completely with Eric that it’s not a special type system.  It’s not meaningless though, it is something!

And that leads to this post. I’m going to share my own thoughts on Duck Typing, what it is and what it isn’t, the different types and give examples across several different stacks/languages to back up my points. I’ll also talk about how Duck Tying is evolving in newer stacks like Scala and Go.

What is it?

Duck Typing is a programming technique where a contract is established between a function and its caller, requiring the parameters passed in by the caller to have specific members present.

Update: I found this definition which seems much more accurate than the Wikipedia version: “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.”

There are two types of contracts, Implicit Contracts and Explicit contracts which will both be explored further in this post.

Note: In traditional object-oriented statically typed languages Duck Typing is commonly substituted with using interfaces and inheritance though you can do Duck Typing in many modern static languages.

Is Duck Typing the same as Late Binding?

Duck Typing differs from late binding which is a general term for delaying looking up an object’s members at compile time and doing the lookup at runtime.

Implicit Contracts

In an implicit contract, the contract is implicitly defined solely based on which members of the arguments passed in by the caller, that the code in the function actually accesses.

Dynamic languages

In dynamic languages, Duck Typing is very common. For example the JavaScript snippet below uses Duck Typing. The executeRule function defines a rule as any thing that has an execute function on it.

The contract here is only in the code. The fact that an execute function is invoked in executeRule() means it will fail unless execute() is present.

This kind of code is very easy and common to write in JS due to the very fact that it is dynamic. Similarly you can easily do the same in other dynamic languages like Ruby and Python.

In some stacks these implicit contracts are even formalized as part of the core libraries. For example in nodejs, streams are implicit contracts from a stream implementer perspective. All functions that accept streams are technically using Duck Typing.

What about Method Missing type?

Reading through Phil’s post reminded me that I missed mentioning something. Both Ruby and Javascript have a generic way for dynamically handling invocations on members that are not actually present. Ruby has the method_missing method. Harmony proxies are a bit more complicated but within a proxy you can implement similar semantics. In either case the object (or the proxy) has an explicit implementation to handle missing members. I am kind of back and forth on this one. It obviously not identical in that the presence of the members to satisfy the contract is actually virtualized.  From the standpoint of the function receiving the params it is still Duck Typing though, as it just invokes the members it expects to be present.

Please feel free to disagree with me on this ;-)

Ok, now let’s see Duck Typing in statically typed languages in particular .NET.

VB.NET

VB.NET has had support for using Duck Typing for a long time. As long as your objects are declared as type Object you can party on them in a similar fashion.

C# with dynamic

In C# thanks to the dynamic keyword we can do Duck Typing. What’s nice about this from a C# perspective is you can pass either a dynamic object or a statically typed object and get the same result as long as the required members are present.

Important to note that similar to Ruby and JavaScript you can implement Method Missing type semantics by rolling your own Dynamic Object.

Boo

Boo is a really cool statically typed .NET language. Years before dynamic ever existed, Boo introduced the duck type specifically for supporting Duck Typing. Its behavior and dynamic’s are very similar as you can see below.

.NET/JAVA with Reflection

You can even use reflection to achieve the same, but it is far less natural. Basically you use the reflection APIs and invoke members. As Krzysztof Cwalina mentioned in one of this earlier posts, the .NET framework uses this approach for enumerables. Using the previous example, here it is done with reflection in C# (yes this code can be refactored to be more performant).

The same approach can work in Java / any static typed language that has it’s own reflection type APIs.

The downside of this approach is it requires you to do the reflection heavy lifting. Above I am calling a single method, but imagine if I am accessing multiple members, the code starts to get ugly quick. Is it still Duck Typing though? Technically probably yes, but it is definitely not leveraging language features, rather it is utilizing runtime hacks introspection to get the Duck Typing behavior.

Interfaces in traditional static languages

Now the question then becomes is using an interface in C#/Java achieving Duck Typing? Below you can see I introduced an IRule interface, and ExecuteRule now expects an IRule instance.

I would say the answer is no, it is not Duck Typing. The reason it because the object getting passed to the Execute method must explicitly implement an interface in order to be compatible. It is not enough for it to have the Execute method on it’s surface, as in the previous cases.

Explicit Contracts via Structural Typing

In all of the previous examples that were mentioned, we saw two common traits:

  • The contract is established implicitly (in the code)
  • There is no compile time safety.

In recent years, a new player has appeared on the block called Structural Typing which provides a way to do Duck Typing in a compiler safe manner that works with static types.  It is exciting to see these advancements!

Structural Typing has been around for a while in languages like C++ (kudos to Stephen Cleary) and O’Caml (kudos to @PickedUsername for that ref). More recently it has been making an appearance in newer languages like Scala (which Eric mentions in his post), and Go. Similar to Duck Typing, the presence / absence of members on the parameters passed in by the caller determines if the contract is satisfied. The difference however is that the the contract is specified explicitly in a manner that can be used at compile time to ensure compatibility.

In the case of Scala this is done by inlining metadata in the function definition which describes the expected contract.

In Go you can do the same using interfaces. What’s special (and beautiful) about the Go interface which differs from other languages, is it retroactively applies to any object that has the members present in the interface.

In either case the behavior is the same. If E(e)xecuteRule is called passing an object that does not have an E(e)xecute() function it will fail at compile time. The object itself has no knowledge however of the contract though the contract itself is explicitly declared externally.

Summing up

Both Duck Typing and it’s newer cousin Structural Typing are techniques which provide a contract to the caller that is based on the structure of the parameters getting passed in. The contract itself can be implicitly established in code, sacrificing compile time checking, or explicitly by using advancements in newer statically typed languages to get compile time safety.

Parting thought – Now that newer languages are treading the path for achieving duck typing in static typed languages with compiler safety, I hope we see other languages follow suit. I for one would love for C#’s interfaces to work the way they do in Go. The first time I saw the language supported this I was literally drooling. Can you hear me Anders? :-)

This entry was posted in Languages, misc. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Yan Cui

    Hi Glenn, nice post!

    The structural typing example you cited in Scala is also available in F# as ‘statically resolved type parameters’ http://msdn.microsoft.com/en-us/library/dd548046.aspx which comes handy when working with types that share some common members but you don’t control and therefore can’t extract as interface.

    Also I find what’s great about Go’s interfaces is how it addresses the expression problem, and from what I can remember, Julia has the same approach (completely by accident since the author of Julia wasn’t even aware of Go interfaces!).

  • andres bracho fernandez

    O’Caml had structural typing (for objects) before Scala was even created for sure!

    _____________
    http://www.digitalfactory.mx

  • Li Chen

    I tried to come out with an implementation of duck-typing in c# using a dynamically generated proxy. Blog at: http://weblogs.asp.net/lichen/archive/2014/01/12/a-c-implementation-of-duck-typing.aspx and code at: http://skylinq.codeplex.com/. See if it makes sense.

  • Zdeslav Vojkovic

    As C++ templates exhibit all properties of structural typing, I doubt that OCaml was the first language to feature ST. I am not even sure if C++ was first :)

  • http://blogs.msdn.com/gblock Glenn Block

    Glad you like it Konstantin, thanks!

  • http://blogs.msdn.com/gblock Glenn Block

    C++ is always overlooked :-)

    Templates are extremely powerful (from what I remember) so that makes sense.

  • http://tarkus.me/ Konstantin Tarkus

    It was great to see a comparison in different languages. Subscribing to your blog…

  • http://blogs.msdn.com/gblock Glenn Block

    ha ha :-).

    Yes you are right on the DLR it was initially created for supporting interop with dynamic languages, but the way it was implemented also opened a ton of interesting other scenarios. I don’t think that was accidental either :-)

    As for other cases, there are plenty of frameworks out there that leverage dynamic for it’s simplicity or who just prefer that style. You lose some compile time benefits but you gain flexibility / reduce the need to recompile a “contract” library.

    And…your mileage may vary….

  • http://Typecastexception.com John Atten

    Indeed. I am new to the concept (and in fact did my own little write up), and I am still absorbing. I totally agree on how it can be done using things like dynamic in C#. My understanding is that the DLR came about specifically to interface with dynamic languages, so that makes sense. I guess my point would be, other than special cases such as meshing with a dynamic language, why would one *want* to? Seems you would be tossing away the strengths of the statically-typed environment for little gain.

    I think we agree altogether, you are just better at expressing your points! :-)

  • http://blogs.msdn.com/gblock Glenn Block

    @John Atten:disqus totally agree with you first point. As to the second I mentioned above that it is common to use interfaces for static languages. The two are not mutually exclusive though as there are plenty of examples of how you can do Duck Typing in static languages. dynamic in C#, interfaces in Go, Structural Types in Scala and Sub Types in O’Caml.

  • http://blogs.msdn.com/gblock Glenn Block

    Hi Nicolas

    Thanks for weighing in.

    Hmm, I agree it’s not a Type system as you said. But the other point he made was Duck Typing is equivalent to late binding which I don’t think is true. My point for doing the post was to show that it is a real thing and how it can be done across various languages both static and dynamic.

  • http://Typecastexception.com John Atten

    I thnk of Duck Typing as more of “approach” than a “type system.” I also agree that interfaces are not a form of duck typing. They do however, acheive a similar result. In fact, I would go so far as to say that a “duck-typed” approach (in a dynamically-typed language) is how one might achieve a result comparable to using an interface in a statically typed language, no?

  • http://stephencleary.com/ Stephen Cleary

    Another language that’s often overlooked is C++, which offers a purely static-time duck typing via templates (nearly twenty years ago, no less!).

    Also, the Boost Concept Check Library allows you to explicitly define “concepts” that a template argument must satisfy. This includes methods/properties, but also can include pretty much anything else, e.g., “I can construct an instance, passing two integer arguments” or “instances can be sorted with the < operator" or even "this type refers to a related type that satisfies these other concepts".

    Difficult to learn and obtuse syntax, yes. But also unbelievably powerful and efficient.

  • Nicolas Garfinkiel

    Glenn, I think you and Phil are missing the point of Eric’s post.

    IMHO, what he is trying to state is that what you commonly refer as “Duck Typing” is not a real type system (and I think we all agree on that). Additionally, he is implying that Duck Typing’s principle of “if it walks like a duck and quacks like a duck then it is a duck” is just describing a feature inherent to any late-binding-capable type system, be it static or dynamic.

    If you ask me and as far as I know, the only language that makes a proper use of the “if it walks like…” saying is Go.

    You declare interfaces, but you are not required to make your types implement them. If a type satisfies the interface, then the compiler assumes that that type can be used wherever the interface is used. If you think about it, it’s sort of what Eric thought on how Duck Typing works.

    Why the confusion then?

    On one hand, dynamic languages you can use (and sometimes abuse) this “language feature” (treating an object as of any type, because if is late-bound) and you don’t have to write any special contract (interfaces) or keyword (dynamic, duck) to use it.

    On the other hand, how do you explain a Java or C# developer how python’s or ruby’s polymorphism works? We have clases and inheritance, but what about polymorphism?

    Hence, duck typing.

    Anyways, great posts, good reading!

  • http://blogs.msdn.com/gblock Glenn Block

    Thanks! I went and updated the post with a reference.

  • http://blogs.msdn.com/gblock Glenn Block

    In this case I agree you are right, but it’s a very simplistic example where I have a single method that could be an action. However imagine accessing properties and then calling a method.

    The delegate example will fall down there while in Scala I can clearly specify each required member on the incoming object. Yes I could do “Action” or accept a Tuple but that’s working around the lack of ability to do this in the language and the code will be uglier.

  • Konstantin Savelyev

    It seems that there is no much difference between Scala’s version

    def executeRule(rule: {def execute(): Unit}) = {
    rule.execute()
    }

    executeRule(rule)

    and C# code below:

    void executeRule(Action execute)
    {
    execute();
    }

    executeRule(rule.execute)

    Does this then mean that all OO languages which support first-class functions support structural typing like Scala?

  • PickedUsername

    A little historical note: I believe O’Caml had structural typing (for objects) before Scala was even created.

  • http://blogs.msdn.com/gblock Glenn Block

    Good point!

  • http://codeofmatt.com/ Matt Johnson

    I’m pretty sure that the VB example will only work with Option Strict Off