The best tool for the job: Duck typing vs Interfaces
Posted by Jason Baker on December 11, 2008
A question on StackOverflow got me thinking today: what are the advantages of duck typing in comparison to interface-based languages (like C# or Java) and vice versa? Notice that I’m not talking about the differences between dynamic and static typing. These two comparisons go hand-in-hand to be sure, but they are two different things in my opinion.
The basic idea behind duck typing is that “if it walks and talks like a duck, then it’s a duck.” Thus, if you want to do an operation on a certain type of object, then you should do that operation on a certain type of object. If the interpreter has a problem, then the interpreter/runtime will let you know (and hopefully you’ve got some error handling in place).
On the other hand, interface-based languages solve this problem by having a pre-established contract between objects and code. Thus, an object will guarantee that it will implement certain methods if the client code will guarantee not to call anything else. If that contract is broken, then the complier will likely let you know at compile time (though that isn’t always the case).
So what are the pros/cons of these two methods?
On first glance, it would seem that the benefits of type safety would make interface-based designs more worthwhile in almost all cases. Indeed, interfaces have helped me prevent a lot of needless errors that I frequently encounter in using dynamic languages. It does this by forcing you to think your class hierarchy a long way in advance.
This is where C# and Java get their enterprise-y reputations. If you need to develop a complex hierarchy of classes, interface-based typing is the only way to go.
This is simultaneously interface-based typing’s greatest strength and greatest weakness. Indeed, it’s also duck typing’s greatest strength and weakness. As wrong as it feels, not every class hierarchy needs to be so well-planned. Heck, sometimes you don’t need class hierarchies at all (there seem to be a lot of python programmers who are totally against inheritance altogether). Of course this does require a lot more unit testing, but you’ve already signed onto the TDD bandwagon anyway, right?
This is where Python gets its famed extreme levels of productivity. By having a good set of unit tests, a Python programmer can churn out good code at breakneck pace.
At any rate, both ways of programming have their strengths and weaknesses, and there’s not any good answer as to what way of thinking about it is the best way to go. So go with your gut. If your first reaction at tackling a task is to say “gee, it really would be nice to be able to write a lot of code fast without having to go through a lot of tedium” then go with Python or Ruby or most other dynamic languages. If you find yourself saying “I need a very complex class hierarchy to do this” then chances are you should be using C# or Java.