Excuse the slightly unusual blog post, but we are living in quite unusual times as I write this. I thought this post might be a mood lightener for a few of my regular readers! With that, let’s explore whether we have an obsession with ducks in software development.
There are two phrases which came to my mind when this weird idea popped into my head. “Duck Typing” and “Rubber Ducking”. That’s two more duck based terms than many industries have, excluding perhaps zoos and veterinary practices.
Let’s dive into these two potentially foul terms!… Get it… Foul sounds like fowl, as in ducks… Okay, never mind, that was a terrible attempt at a pun. I’ve been in lockdown for too long!
I’ve seen and heard the term duck typing defined in a few ways over the years. I don’t intend to try to provide a single definitive description here (surely you got the casual tone of this post from the pun, right?), just a general summary of the concept.
In C# and .NET, we have a static type system which allows us to define and work with objects. Because objects are strongly typed, we get a great degree of safety in the code which we write. The type system supports us at both runtime and compile time. The C# compiler can determine when we’ve passed the wrong type into a method and cause an error to be surfaced. This allows errors to be dealt with during development. Tooling can even help us find and fix the problem.
The type system also has the notion of inheritance and interfaces, which allow us to define an abstraction and have our implementation derive from it. You can pass a concrete type into a method if it inherits from the required type of a method parameter.
Duck Typing is the premise that in some circumstances, we can concern ourselves less with the actual type of an object, but instead focus on what it does. With duck typing, if a class includes specific method signatures, it can be used within a particular context that only requires those methods to be present.
This can be boiled down to the following statement:
“If it looks like a duck, swims like a duck, and quacks like a duck, then it probably is a duck.”
In .NET, our reliance on duck typing is rare, but not wholly absent. A commonly cited example is the foreach loop which acts on an IEnumerable. Except, that strictly speaking it doesn’t. While we can derive a type from that interface to indicate its capability and conformance with the interface, this isn’t required. A foreach loop only requires that a type which includes a public, parameterless GetEnumerator method. That method must also return a type which contains a public MoveNext method and a public Current property.
We see the duck typing principle in other places within .NET too. If you’ve used ASP.NET Core, you’ve relied on duck typing as well.
The Startup class, for example, is included in the ASP.NET Core templates and can be used to register services with the dependency injection container and to configure the application middleware pipeline. This class does not require the use of an interface. In fact, the minimum requirement for this class is that it includes a Configure method accepting an IApplicationBuilder. It doesn’t even have to be called Startup, it can have any name you want.
The preceding code is a perfectly valid class which provides a single endpoint for an ASP.NET Core application.
Another example in ASP.NET Core is middleware. When creating a custom middleware component, again there is no interface. There are a set of rules you must follow when creating a middleware class:
- A public constructor with a parameter of type RequestDelegate.
- A public method named Invoke or InvokeAsync. This method must:
- Return a Task.
- Accept a first parameter of type HttpContext.
Any type which meets these requirements may be registered into the middleware pipeline and be correctly invoked.
Duck typing has drawbacks since reasoning about types becomes more difficult and errors may creep in. For example, I can tweak my valid startup class from above by renaming the method.
The compiler is more than happy with this, so there are no compile-time errors. If we try to run the application, we hit a runtime exception.
The signature of this class no longer satisfies the rules for a suitable startup class.
Rubbing ducking, in generalised terms, is the process whereby we can often debug issues or solve a programming problem by explaining them to someone else.
I’ve experienced this many times in my career. I’ll hit a wall with something I am working on, sure that I’m unable to figure out the solution. I may stare at the code for a very long time without figuring out the correct fix.
At a certain point, I will ask a colleague for advice and explain what I’m trying to achieve, the steps I’ve taken and the current problem. More often than not, part of the way through my explanation, a lightbulb flicks on, and I know what I’m doing wrong. I expect this has happened to many of you too.
As many developers on the receiving end of this will know, it can break your flow to stop what you’re doing to act as a sounding board for such problems. And so, we introduce the rubber duck concept. Rather than interrupt a colleague to ask their opinion, try explaining your problem to a rubber duck, or any suitable stand-in.
The mere act of restating the problem will often be enough to kick your brain into gear and to get you out of your coding rut. You can do this in your head, but I find speaking out loud helps. For sure, you may want to find somewhere not too public before you begin talking to yourself, or your rubber duck.
If you don’t have a duck to hand, but honestly, who doesn’t, you can replace it with any inanimate object willing to be subjected to your ramblings. At home, I keep a trusty rubber duck under my primary monitor. I picked it up at Techorama NL last year, and it’s proven to be a font of problem-solving abilities. In fact, it may be more deserving of MVP status than me!
That’s duck typing and rubber ducking in a nutshell. I leave it to your dear reader, do we have an obsession with ducks? Perhaps you found this interesting, or perhaps you didn’t give a duck!
Note: My normal deeply technical blog post service will hopefully resume shortly! 🙂