Welcome to the Code Aviary: Where Ducks Debug and Canaries Die
- 4 minutes read - 727 wordsYour survival guide to feathered philosophies in software development
Rubber Duck Debugging
Alright, we’re starting easy and light for this one.
It was popularised by the Pragmatic Programmer written by Andrew Hunt and David Thomas (an alumnus of Imperial College London). The idea is rather simple: instead of spending hours trying to debug something obscure, explain the code line-by-line to an inanimate object - a rubber duck named Chucky maybe? - to help you work out what the problem is.

This is a funny method to force a developer to articulate a problem without using somebody else’s time. Let’s be real, if you had asked the help of Richard, the office’s rockstar, you would’ve probably given the same explanation as Chucky’s.
In other words, it’s an amusing way of reminding devs that to identify a problem’s root cause, it is often better to break down the problem in smaller pieces and build a deep as well as accurate understanding of what the code is doing. You probably would have a harder time fixing this bug otherwise.
As a proud ICL alumni, I’m going to claim ICL indirectly gave birth to this essential, indispensable and pivotal concept!
Canary Deployment
Unlike rubber duck debugging, this one comes from a darker origin story.
Do you know what the “silent killer” is? It is the name we give to carbon monoxide - CO. CO is very toxic to humans; it is also famously odourless, colourless and tasteless. Consequently, its presence is extremely dangerous and very hard to detect. This is the main component of “White Damp”, a mixture found down in the mines.
To help with carbon monoxide detection, miners used to bring a caged canary down in the mine with them. Because of its size, the bird’s metabolism is faster than a human. Exposed to carbon monoxide, it would die before the miners, giving them an early warning sign to evacuate.

The singing canary metaphor has been carried over in software engineering as a release strategy. Gradual roll-out of an application’s new version is done on sub-sets of users before it is made available to all users. The initial subset of users acts as a metaphorical canary: problems occurring post-release can be easily contained.
This technique is quite useful when changes are high-risk or for testing new features.
For web applications, the standard practice is to host two versions of the software (often behind a load balancer) and control traffic routing with feature flags, percentage-based rollout tools for feature management e.g. LaunchDarkly, or segment-specific logic e.g. location, account type, user activity.
As a proud alumni of the engineering school of Mines, I can confidently say we continue our tradition of sending canaries into danger — though thankfully now it’s mostly bugs, not gas leaks.
Duck-typing
“If it looks like a duck and quacks like a duck, then it must be a duck.”
Java uses nominative typing: the compatibility of data types is explicitly declared. Polymorphism is achieved by interface implementation or class extension. In Python, an object is of a given type if it has the minimum necessary methods and attributes required by that type. It is usage-based equivalence rather than declared.
In the first operations of the iteration, both Swan and Cat classes can be used the same way we use the Duck class. They all have
the has_feathers attribute and implement the quack() method. A Swan and a Cat could be considered a Duck.
But duck-typing isn’t perfect — it only works until you make assumptions beyond what’s actually implemented.
An attribute error would be raised as the fly() method is not
implemented by other classes. A Swan or a Cat is definitely not a Duck.
class Duck:
has_feathers = True
is_flying = False
def quack(self):
print('QUACK')
def fly(self):
self.is_flying = True
class Swan:
has_feathers = True
def quack(self):
print('TUTUT')
class Cat:
has_feathers = False
def quack(self):
print('MEOW')
# Duck Typing
for animal in [Duck(), Swan(), Cat()]:
animal.quack()
print(f'The animal has feathers: {animal.has_feathers}')
# Duck Typing Error Handling
if hasattr(animal, 'fly'):
animal.fly()
else:
print(f"{animal.__class__.__name__} can't fly.")
QUACK
The animal has feathers: True
TUTUT
The animal has feathers: True
Swan can't fly.
MEOW
The animal has feathers: False
Cat can't fly.
As a proud alumni!
.. nah just kidding, I can’t pull that off three times.
Until next time, keep your ducks on your desks, and your canaries well-fed.