[programming-languages] What is duck typing?

I came across the term duck typing while reading random topics on software online and did not completely understand it.

What is “duck typing”?

This question is related to programming-languages duck-typing

The answer is


Duck Typing is not Type Hinting!

Basically in order to use "duck typing" you will not target a specific type but rather a wider range of subtypes (not talking about inheritance, when I mean subtypes I mean "things" that fit within the same profiles) by using a common interface.

You can imagine a system that stores information. In order to write/read information you need some sort of storage and information.

Types of storage may be: file, database, session etc.

The interface will let you know the available options (methods) regardless of the storage type, meaning that at this point nothing is implemented! In another words the Interface doesn't know nothing about how to store information.

Every storage system must know the existence of the interface by implementing it's very same methods.

interface StorageInterface
{
   public function write(string $key, array $value): bool;
   public function read(string $key): array;
}


class File implements StorageInterface
{
    public function read(string $key): array {
        //reading from a file
    }

    public function write(string $key, array $value): bool {
         //writing in a file implementation
    }
}


class Session implements StorageInterface
{
    public function read(string $key): array {
        //reading from a session
    }

    public function write(string $key, array $value): bool {
         //writing in a session implementation
    }
}


class Storage implements StorageInterface
{
    private $_storage = null;

    function __construct(StorageInterface $storage) {
        $this->_storage = $storage;
    }

    public function read(string $key): array {
        return $this->_storage->read($key);
    }

    public function write(string $key, array $value): bool {
        return ($this->_storage->write($key, $value)) ? true : false;
    }
}

So now, every time you need to write/read information:

$file = new Storage(new File());
$file->write('filename', ['information'] );
echo $file->read('filename');

$session = new Storage(new Session());
$session->write('filename', ['information'] );
echo $session->read('filename');

In this example you end up using Duck Typing in Storage constructor:

function __construct(StorageInterface $storage) ...

Hope it helped ;)


Duck typing:

If it talks and walks like a duck, then it is a duck

This is typically called abduction (abductive reasoning or also called retroduction, a clearer definition I think):

  • from C (conclusion, what we see) and R (rule, what we know), we accept/decide/assume P (Premise, property) in other words a given fact

    ... the very basis of medical diagnosis

    with ducks: C = walks, talks, R = like a duck, P = it's a duck

Back to programming:

  • object o has method/property mp1 and interface/type T requires/defines mp1

  • object o has method/property mp2 and interface/type T requires/defines mp2

  • ...

So, more than simply accepting mp1... on any object as long has it meets some definition of mp1..., compiler/runtime should also be okay with the assertion o is of type T

And well, is it the case with examples above? Is Duck typing is essentially no typing at all? Or should we call it implicit typing?


Simple Explanation (without code)

Discussion of the semantics of the question is fairly nuanced (and very academic), but here's the general idea:

Duck Typing

(“If it walks like a duck and quacks like a duck then it is a duck.”) - YES! but what does that mean??! This is best illustrated by example:

Examples of Duck Typing functionality:

Imagine I have a magic wand. It has special powers. If I wave the wand and say "Drive!" to a car, well then, it drives!

Does it work on other things? Not sure: so I try it on a truck. Wow - it drives too! I then try it on planes, trains and 1 Woods (they are a type of golf club which people use to 'drive' a golf ball). They all drive!

But would it work on say, a teacup? Error: KAAAA-BOOOOOOM! that didn't work out so good. ====> Teacups can't drive!! duh!?

This is basically the concept of duck typing. It's a try-before-you-buy system. If it works, all is well. But if it fails, like a grenade still in your hand, it's gonna blow up in your face.

In other words, we are interested in what the object can do, rather than with what the object is.

Example: statically typed languages

If we were concerned with what the object actually was, then our magic trick will work only on pre-set, authorised types - in this case cars, but will fail on other objects which can drive: trucks, mopeds, tuk-tuks etc. It won't work on trucks because our magic wand is expecting it to only work on cars.

In other words, in this scenario, the magic wand looks very closely at what the object is (is it a car?) rather than what the object can do (e.g. whether cars, trucks etc. can drive).

The only way you can get a truck to drive is if you can somehow get the magic wand to expect both trucks and cars (perhaps by "implementing a common interface"). If you don't know what that means then just ignore it for the moment.

Summary: Key take-out

What's important in duck typing is what the object can actually do, rather than what the object is.


The term Duck Typing is a lie.

You see the idiom “If it walks like a duck and quacks like a duck then it is a duck." that is being repeated here time after time.

But that is not what duck typing (or what we commonly refer to as duck typing) is about. All that the Duck Typing we are discussing is about, is trying to force a command on something. Seeing whether something quacks or not, regardless of what it says it is. But there is no deduction about whether the object then is a Duck or not.

For true duck typing, see type classes. Now that follows the idiom “If it walks like a duck and quacks like a duck then it is a duck.". With type classes, if a type implements all the methods that are defined by a type class, it can be considered a member of that type class (without having to inherit the type class). So, if there is a type class Duck which defines certain methods (quack and walk-like-duck), anything that implements those same methods can be considered a Duck (without needing to inherit Duck).


I know I am not giving generalized answer. In Ruby, we don’t declare the types of variables or methods— everything is just some kind of object. So Rule is "Classes Aren’t Types"

In Ruby, the class is never (OK, almost never) the type. Instead, the type of an object is defined more by what that object can do. In Ruby, we call this duck typing. If an object walks like a duck and talks like a duck, then the interpreter is happy to treat it as if it were a duck.

For example, you may be writing a routine to add song information to a string. If you come from a C# or Java background, you may be tempted to write this:

def append_song(result, song)
    # test we're given the right parameters 
    unless result.kind_of?(String)
        fail TypeError.new("String expected") end
    unless song.kind_of?(Song)
        fail TypeError.new("Song expected")
end

result << song.title << " (" << song.artist << ")" end
result = ""

append_song(result, song) # => "I Got Rhythm (Gene Kelly)"

Embrace Ruby’s duck typing, and you’d write something far simpler:

def append_song(result, song)
    result << song.title << " (" << song.artist << ")"
end

result = ""
append_song(result, song) # => "I Got Rhythm (Gene Kelly)"

You don’t need to check the type of the arguments. If they support << (in the case of result) or title and artist (in the case of song), everything will just work. If they don’t, your method will throw an exception anyway (just as it would have done if you’d checked the types). But without the check, your method is suddenly a lot more flexible. You could pass it an array, a string, a file, or any other object that appends using <<, and it would just work.


In duck typing, an object's suitability (to be used in a function, for example) is determined based on whether certain methods and/or properties are implemented rather than based on the type of that object.

For example, in Python, the len function can be used with any object implementing the __len__ method. It doesn't care if that object is of a certain type say string, list, dictionary or MyAwesomeClass, as far as these objects implement a __len__ method, len will work with them.

class MyAwesomeClass:
    def __init__(self, str):
        self.str = str
    
    def __len__(self):
        return len(self.str)

class MyNotSoAwesomeClass:
    def __init__(self, str):
        self.str = str

a = MyAwesomeClass("hey")
print(len(a))  # Prints 3

b = MyNotSoAwesomeClass("hey")
print(len(b))  # Raises a type error, object of type "MyNotSoAwesomeClass" has no len()

In other words, MyAwesomeClass looks like a duck and quacks like a duck and therefore is a duck, while MyNotSoAwesomeClass doesn't look like a duck and doesn't quack, therefore is not a duck!


Wikipedia has a fairly detailed explanation:

http://en.wikipedia.org/wiki/Duck_typing

duck typing is a style of dynamic typing in which an object's current set of methods and properties determines the valid semantics, rather than its inheritance from a particular class or implementation of a specific interface.

The important note is likely that with duck typing a developer is concerned more with the parts of the object that are consumed rather than what the actual underlying type is.


Looking at the language itself may help; it often helps me (I'm not a native English speaker).

In duck typing:

1) the word typing does not mean typing on a keyboard (as was the persistent image in my mind), it means determining "what type of a thing is that thing?"

2) the word duck expresses how is that determining done; it's kind of a 'loose' determining, as in: "if it walks like a duck ... then it's a duck". It's 'loose' because the thing may be a duck or may not, but whether it actually is a duck doesn't matter; what matters is that I can do with it what I can do with ducks and expect behaviors exhibited by ducks. I can feed it bread crumbs and the thing may go towards me or charge at me or back off ... but it will not devour me like a grizzly would.


Consider you are designing a simple function, which gets an object of type Bird and calls its walk() method. There are two approaches you can think of:

  1. This is my function, and I must be sure that it only accepts the Bird, or the code will not compile. If anyone wants to use my function, they must be aware that I only accept Birds
  2. My function gets any objects and I just call the object's walk() method. So, if the object can walk() it is correct, if it can't my function will fail. So here it is not important the object is a Bird or anything else, it is important that it can walk() (This is duck typing)

It must be considered that the duck typing may be useful in some cases, for example Python uses duck typing a lot.


Useful reading


Tree Traversal with duck typing technique

def traverse(t):
    try:
        t.label()
    except AttributeError:
        print(t, end=" ")
    else:
        # Now we know that t.node is defined
        print('(', t.label(), end=" ")
        for child in t:
            traverse(child)
        print(')', end=" ")

Duck typing means that an operation does not formally specify the requirements that its operands have to meet, but just tries it out with what is given.

Unlike what others have said, this does not necessarily relate to dynamic languages or inheritance issues.

Example task: Call some method Quack on an object.

Without using duck-typing, a function f doing this task has to specify in advance that its argument has to support some method Quack. A common way is the use of interfaces

interface IQuack { 
    void Quack();
}

void f(IQuack x) { 
    x.Quack(); 
}

Calling f(42) fails, but f(donald) works as long as donald is an instance of a IQuack-subtype.

Another approach is structural typing - but again, the method Quack() is formally specified any anything that cannot prove it quacks in advance will cause a compiler failure.

def f(x : { def Quack() : Unit }) = x.Quack() 

We could even write

f :: Quackable a => a -> IO ()
f = quack

in Haskell, where the Quackable typeclass ensures the existence of our method.


So how does duck typing change this?

Well, as I said, a duck typing system does not specify requirements but just tries if anything works.

Thus, a dynamic type system as Python's always uses duck typing:

def f(x):
    x.Quack()

If f gets an x supporting a Quack(), everything is fine, if not, it will crash at runtime.

But duck typing doesn't imply dynamic typing at all - in fact, there is a very popular but completely static duck typing approach that doesn't give any requirements too:

template <typename T>
void f(T x) { x.Quack(); } 

The function doesn't tell in any way that it wants some x that can Quack, so instead it just tries at compile time and if everything works, it's fine.


I try to understand the famous sentence in my way: "Python dose not care an object is a real duck or not. All it cares is whether the object, first 'quack', second 'like a duck'."

There is a good website. http://www.voidspace.org.uk/python/articles/duck_typing.shtml#id14

The author pointed that duck typing let you create your own classes that have their own internal data structure - but are accessed using normal Python syntax.


I think it's confused to mix up dynamic typing, static typing and duck typing. Duck typing is an independent concept and even static typed language like Go, could have a type checking system which implements duck typing. If a type system will check the methods of a (declared) object but not the type, it could be called a duck typing language.


I see a lot of answers that repeat the old idiom:

If it looks like a duck and quacks like a duck, it's a duck

and then dive into an explanation of what you can do with duck typing, or an example which seems to obfuscate the concept further.

I don't find that much help.

This is the best attempt at a plain english answer about duck typing that I have found:

Duck Typing means that an object is defined by what it can do, not by what it is.

This means that we are less concerned with the class/type of an object and more concerned with what methods can be called on it and what operations can be performed on it. We don't care about it's type, we care about what it can do.