518
votes

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

What is “duck typing”?

16
@Mitch i tried and got something as its some form of inheritance. But could not follow much. Sorry if i asked the wrong question.sushil bharwani
@sushil bharwani: no, not angry. But people expect that as the first port of call (i.e. the first thing you do) is to try searching before posting here.Mitch Wheat
Given the arguments above it doesn't seem that stackoverflow is actually necessary since I am sure almost every question one could possibly think of is answered somewhere on the internet, and if not the answer could probably be obtained more easily and without criticism by emailing a knowledgeable friend. I think many of you have missed the point of stackoverflow.rhody
I'm sure I've read somewhere that SO was intended to be "a repository of canonical questions", and I'm pretty sure you cannot get more canonical than this one.heltonbiker

16 Answers

348
votes

It is a term used in dynamic languages that do not have strong typing.

The idea is that you don't need a type in order to invoke an existing method on an object - if a method is defined on it, you can invoke it.

The name comes from the phrase "If it looks like a duck and quacks like a duck, it's a duck".

Wikipedia has much more information.

234
votes

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 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.


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.

157
votes

Simple Explanation (without code)

What is duck typing?

“If it walks like a duck and quacks like a duck then it is a duck.” - YES! but what does that mean??!

Consider this example:

Explanation of Duck Typing

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: if using C# or Java etc.

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.

38
votes

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 type 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() then 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 duck typing may be useful in some cases. For example, Python uses duck typing a lot.


Useful reading

25
votes

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.

20
votes

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.

15
votes

"Duck typing" := "try the methods, don't check the type"

Note: := can be read as "is defined as".

"Duck typing" means: just try the method (function call) on whatever object comes in rather than checking the object's type first to see if that method is even a valid call on such a type.

Let's call this "try the methods, don't check the type" typing, "method-call type-checking", or just "method-call typing" for short.

In the longer explanation below, I'll explain this more in detail and help you make sense of the ridiculous, esoteric, and obfuscated term "duck typing."


Longer explanation:

DIE 🦆 DIE! 🍗

Python does this concept above. Consider this example function:

def func(a):
    a.method1()
    a.method2()

When the object (input parameter a) comes into the function func(), the function shall try (at run time) to call any methods specified on this object (namely: method1() and method2() in the example above), rather than first checking to see if a is some "valid type" which has these methods.

So, it's an action-based attempt at run-time, NOT a type-based check at compile-time or run-time.

Now look at this silly example:

def func(duck_or_duck_like_object):
    duck_or_duck_like_object.quack()
    duck_or_duck_like_object.walk()
    duck_or_duck_like_object.fly()

Hence is born the ridiculous phrase:

If it walks like a duck and quacks like a duck then it is a duck.

The program that uses "duck typing" shall simply try whatever methods are called on the object (in this example above: quack(), walk(), and fly()) withOUT even knowing the type of the object! It just tries the methods! If they work, great, for all the "duck typing" language knows or cares, IT (the object passed in to the function) IS A DUCK!--because all the (duck-like) methods worked on it.

(Summarizing my own words):

A "duck typed" language shall not check its type (neither at compile time nor run-time)--it doesn't care to. It will just try the methods at run-time. If they work, great. If they don't, then it shall throw a run-time error.

That is duck-typing.

I'm so tired of this ridiculous "duck" explanation (because without this full explanation it doesn't make any sense at all!), and so are others too it sounds like. Example: from BKSpurgeon's answer here (my emphasis in bold):

(“If it walks like a duck and quacks like a duck then it is a duck.”) - YES! but what does that mean??!"

Now I get it: just try the method on whatever object comes in rather than checking the object's type first.

I shall call this "run-time checking where the program just tries the methods called without even knowing if the object has these methods, rather than checking the type of the object first as the means of knowing the object has these methods", because that just makes more sense. But...that's too long to say, so people would rather confuse each other for years instead by saying ridiculous but catchy things like "duck typing."

Let's instead call this: "try the methods, don't check the type" typing. Or, perhaps: "method-call type-checking" ("method-call typing" for short), or "indirect type-checking by method calls", since it uses the calling of a given method as "proof enough" that the object is of the right type, rather than checking the object's type directly.

Note that this "method-call type-checking" (otherwise confusingly called "duck typing") is a type of dynamic typing. But, NOT all dynamic typing is necessarily "method call type-checking", because dynamic typing, or type checking at run-time, can also be done by actually checking an object's type rather than by simply attempting to call the methods called on the object in the function without knowing its type.

Read also:

  1. https://en.wikipedia.org/wiki/Duck_typing --> search the page for "run", "run time", and "runtime".
4
votes

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.

4
votes

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.

3
votes

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?

2
votes

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 ;)

2
votes

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=" ")
0
votes

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.

0
votes

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).

0
votes

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!

-2
votes

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.