2014-01-05

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

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.

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.

1
2
3

view raw
executor.js
hosted with ❤ by GitHub

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.

1
2
3

view raw
Executor.vb
hosted with ❤ by GitHub

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.

1
2
3

view raw
ExecutorDynamic.cs
hosted with ❤ by GitHub

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.

1
2
3

view raw
executor.boo
hosted with ❤ by GitHub

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

1
2
3

view raw
ExecutorReflection.cs
hosted with ❤ by GitHub

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.

1
2
3
4
5
6
7

view raw
ExecutorInterface.cs
hosted with ❤ by GitHub

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 first appeared in Scala (which Eric mentions in his post), but similar behavior is also available in 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.

1
2
3

view raw
executor.scala
hosted with ❤ by GitHub

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.

1
2
3
4
5
6
7

view raw
executor.go
hosted with ❤ by GitHub

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?

Show more