it's also worth noting that you can implement the pretty useless restrictions interfaces provide for you with duck typing

foo( a ) { a.doYouImplementIAddable() }

class Foo {

doYouImplementIAddable() { true }


a = new Foo()

foo(a) // true

a = 5

foo(a) // Fail, could even fail at compile time

So really duck typing is a superset of everything static languages offer. If you want a complicated taxonomy go right ahead with dynamic typing. But they also let you do so much more.