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