593

What does duck typing mean in software development?

8
  • 1
    @Mitch i tried and got something as its some form of inheritance. But could not follow much. Sorry if i asked the wrong question. Nov 17, 2010 at 14:08
  • 4
    @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. Nov 17, 2010 at 14:11
  • 61
    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. Jun 27, 2014 at 3:10
  • 8
  • 1
    imo every question under the sun should be documented in a part of the StackExchange community Sep 3, 2019 at 18:50

19 Answers 19

400

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

The idea is that you don't need to specify 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.

12
  • 27
    Be wary of using Strong Typing. It is not that well defined. Neither is Duck Typing. Google Go or Ocaml are statically typed languages with a structural subtyping-construction. Are these duck typed languages? Nov 17, 2010 at 15:27
  • 12
    a better phrase for duck typing is: "If is says it is a duck.. well that's good enough for me." see pyvideo.org/video/1669/keynote-3 28:30 or youtube.com/watch?v=NfngrdLv9ZQ#t=1716
    – tovmeod
    Oct 1, 2013 at 0:50
  • 9
    Duck typing isn't necessarily just used in dynamic languages. Objective-C isn't a dynamic language and it uses duck typing.
    – eyuelt
    Oct 5, 2013 at 7:59
  • 14
    Both Python and Ruby are strong-typed languages and both have Duck Typing. String Typing does not imply in not having Duck Typing.
    – alanjds
    Apr 18, 2014 at 1:01
  • 12
    I'm downvoting this. Duck ducking has nothing to do with the strength of type, just the ability to be able to use any object having a method, wether it implement an interface or not.
    – Bite code
    Jan 12, 2015 at 2:31
261

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.


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.

4
  • 5
    didn't you mean : void f(IQuak x) { x.Quak(); } (instead of K.Quack) because function f's parameter is IQuack x not Iquack k, very small mistake but I felt like it needed to be corrected :) Jul 8, 2013 at 18:47
  • 2
    According to Wikipedia, your last example is "structural typing", not "duck typing".
    – Brilliand
    Apr 17, 2014 at 15:12
  • Well, it seems there's a separate question for that discussion: stackoverflow.com/questions/1948069/…
    – Brilliand
    Apr 17, 2014 at 15:26
  • 4
    So if I understand what you said, the difference between a language that supports duck typing and one that does not is just that with duck typing, you do not have to specify the type of objects that a function accepts? def f(x) instead of def f(IQuack x).
    – PProteus
    Jan 5, 2017 at 19:16
201

Simple Explanation

What is duck typing?

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

We're interested in what "objects" can do, rather than what they are.

Let's unpack it with an example:

Explanation of Duck Typing

See below for further detail:

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.

What about languages like 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"). This can be done via a technique called: "polymorphism" or by using "interfaces" - they're kinda the same thing. If you like cartoons and want an explanation, check out my cartoon on interfaces.

Summary: Key take-out

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

Code Sample

But how can a golf club "drive" like a car? Aren't they different? If you're using a language like Ruby, we don't care about what the object is:

class Car
   def drive
      "I"m driving a Car!"
   end
end

class GolfClub
   def drive
      "I"m driving a golf club!"
   end 
end

def test_drive(item)   
   item.drive # don't care what it is, all i care is that it can "drive"
end

car = Car.new
test_drive(car) #=> "I'm driving a Car"

club = GolfClub.new
test_drive(club) #=> "I"m driving a GolfClub"

# welcome to duck typing!

PS. I wanted to cut out the academic rigmarole: this answer is not scientific, but hopefully it gives you a vague understanding of what is going on via analogy.

PPS. if you wanna laugh and got some time to spare, check out: Matt Damon's explanation of duck typing in Good Will Hunting ;)

5
  • 1
    I find interesting the premise about you care more about the behavior, that's it's definition. No doubt BDD is so successful in languages like ruby. Oct 30, 2018 at 18:31
  • 7
    Best explanation for sure. I'm so tired of this "duck" explanation, and so are you too it sounds like (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. Mar 6, 2021 at 5:42
  • 1
    I felt too passionate about this, and had to add my own answer too :). Mar 6, 2021 at 6:06
  • Also, I think you should put your "Summary" right at the beginning. That's the key takeaway. Maybe leave it at the end but also put a copy of it right at the beginning too. Mar 6, 2021 at 6:33
  • But isn't the drive of a car different from the drive of a golf driver? Dec 15, 2022 at 12:20
47

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

2
  • 2
    Nice explanation, What are any advantages? Nov 10, 2015 at 14:19
  • 5
    This answer is simple, clear, and probably the best for beginners. Read this answer along with the answer above it (or if it moves, the answer that talks about cars and teacups)
    – DORRITO
    Mar 31, 2018 at 15:24
32

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.

1
  • 1
    Great! Some might also state it means a technique when an object's type is determined not by its inheritance but properties (i.e. fields, methods etc.). Related: stackoverflow.com/a/4205164/5113030 (Answer by Chris Baxter...)
    – Artfaith
    Sep 26, 2023 at 11:46
29

Don't be a quack; I've got your back:

"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()
    duck_or_duck_like_object.swim()

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(), fly(), and swim()) 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".
3
  • 6
    thanks sir! i mean "bravo!!" this is amazing, should be upvoted way more!
    – bermick
    Apr 3, 2021 at 14:31
  • Thanks, this made more sense. So is JavaScript duck typed?
    – manish
    Aug 30, 2021 at 21:21
  • 1
    @manish, I don't know JavaScript, so I can't say. If it is a scripted language with weak, unspecified types that aren't automatically checked for errors (either at compile time or run-time) in function calls when you pass in parameters, then the answer is "yes". Python fits this description. It doesn't throw an error when you pass in a parameter with the wrong type to a function, rather, it throws a run-time error when you try to call some invalid method on that object type and it fails. Mar 9, 2022 at 4:27
21

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.

4

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

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.

4

Matt Damon explains Duck Typing in Good Will Hunting

Transcript is as below. Video link here..

CHUCKIE: All right, are we gonna have a problem?

CLARK: There's no problem. I was just hoping you could give me some insight into what duck typing is actually is? My contention is that duck tying is not well defined, and neither is strong

WILL: [interrupting] …and neither is strong typing. Of course that's your contention. You're a first year grad student: you just got finished reading some article on duck typing, probably on StackOverflow, and you’re gonna be convinced of that until next month when you get to the Gang of Four, and then you’re gonna be talking about how Google Go and Ocaml are statistically typed languages with structural sub-tying construction. That's going to last until next year, till you're probably gonna be in here regurgitating Matz, talkin’ about, you know, the Pre-Ruby 3.0 utopia and the memory allocating effects of sub-typing on the GC.

CLARK: [taken aback] Well as a matter of fact I won't, because Matz drastically underestimates the impact of —

WILL: "Matz dramatically underestimates the impact of Ruby 3.0's GC on performance. You got that from Donald Knuth, The Art of Computer Programming, page 98, right? Yeah I read that too. Were you gonna plagiarize the whole thing for us—you have any thoughts of—of your own on this matter? Or do—is that your thing, you come into stack overflow, you read some obscure passage on r/ruby and then you pretend, you pawn it off as your own—your own idea just to impress some girls, embarrass my friend?

[Clark is stunned]

WILL: See the sad thing about a guy like you is in about 50 years you’re gonna start doing some thinking on your own and you’re gonna come up with the fact that there are three certainties in life. One, don't do that. And two, if it walks like a duck then it is a duck. And three, you dropped a hundred and fifty grand on an education you coulda got for zero cents via a stack overflow answer by Ben Koshy.

CLARK: Yeah, but I will have a degree, and you'll be serving my kids some cheap html via react at a drive-thru on our way to a skiing trip.

WILL: [smiles] Yeah, maybe. But at least I won't be unoriginal.

(a beat)

WILL: you got problem 3 ? I guess we can step outside and sort things out.

Clark: there's no problem

Some time later:

WILL: Do you like apples?

Clark is like, huh?

WILL: How do you like them apples? (Boom: Will slams a letter up against a window.) I gotta offer from Google! (Shows the letter of acceptance to Clark showing his interview answer: a picture of a duck walking, and talking, and acting like a... goose.)

Roll Credits.

THE END.

(This is a footnote to the old answer here:)

3 Advent of Code problems.

3

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

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

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

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

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

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!

0

Duck Typing:

let anAnimal 

if (some condition) 
  anAnimal = getHorse()
else
  anAnimal = getDog()

anAnimal.walk()

The above function call will not work in Structural typing

The following will work for Structural typing:

IAnimal anAnimal

if (some condition) 
      anAnimal = getHorse()
    else
      anAnimal = getDog()
    
anAnimal.walk()

That's all, many of us already know duck typing is intuitively.

0

In programming, types can be divided into nominal and structural types. Nominal types consider the entire structure of a type. So from whom inherited etc. They are clearly more complex than structural types. One uses nominal types for example in C# and Java.

Structural types do not consider these points at all. For structural types only the structure of the single type is important. So how it looks like. In the example of a class. Does it have the same parameters and the expected types. This is called Duck Typing. Duck Typing finds its origin in the Duck Test.

A Dugtest means: If something looks like a duck. If it swims like a duck. If it quacks like a duck. Then it is a duck. Conversely: If a test case does not apply, then it is not a duck. (https://en.wikipedia.org/wiki/Duck_test)

-1

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.

1

Not the answer you're looking for? Browse other questions tagged or ask your own question.