Duck Typing
- Summary
-
Discussion
- What's the origin of the phrase "duck typing"?
- What's the advantage of having duck typing?
- Isn't duck typing more like late binding than a type system?
- Can you compare duck typing with structural typing?
- Can we say that duck typing is another name for implied interfaces?
- What is goose typing?
- What languages support duck typing?
- How is duck typing related to LBYL and EAFP?
- Milestones
- Sample Code
- References
- Further Reading
- Article Stats
- Cite As
Duck Typing is a way of programming in which an object passed into a function or method supports all method signatures and attributes expected of that object at run time. The object's type itself is not important. Rather, the object should support all methods/attributes called on it. For this reason, duck typing is sometimes seen as "a way of thinking rather than a type system".
In duck typing, we don't declare the argument types in function prototypes or methods. This implies that compilers can't do type checking. What really matters is if the object has the particular methods/attributes at run time. Duck typing is therefore often supported by dynamic languages. However, some static languages are beginning to "mimic" it via structural typing.
Discussion
-
What's the origin of the phrase "duck typing"? The phrase originates from an old saying,
If it walks like a duck, swims like a duck, and quacks like a duck, then it probably is a duck.
What does this mean? Even a non-duck entity that behaves like a duck can be considered a duck because emphasis is on behaviour. By analogy, for computing languages, the type of an object is not important so long as it behaves as expected. This behaviour is defined by the object's methods/properties/attributes while expectations are set by those who invoke the methods/properties/attributes.
For example, a
Book
class is expected to have an attributenumPages
and a methodgetPage(number)
, wherenumber
is an integer. Let's say a functionsearchPhrase(book, phrase)
is meant to search for a given phrase in a book. This function callsbook.getPage()
for allbook.numPages
of the book. ANewspaper
is obviously not a book but with duck typing this doesn't matter. IfNewspaper
has implementednumPages
andgetPage(number)
, it can be passed intosearchPhrase(book, phrase)
as if it's a book. Though it's not a book, it's sufficient that it behaves like one within the context ofsearchPhrase
. -
What's the advantage of having duck typing? It's been said that dynamic typing in general cuts down development time. There's less boilerplate code. Code is easier to hack. With static typing, compile-time checks slow down the development process. Static typing could be used at a later point to get better performance. Others recommend duck typing only for prototyping and never for production.
While it's true that compile-time checks are useful to catch potential problems early, duck typing enforces following coding conventions, documentation and test-driven methodologies.
Since duck typing isn't exactly a type system, it gives programmers flexibility. In Python, for example, common things are simpler to code. While static typed languages use interfaces, such interfaces may involve excessive refactoring of client code.
-
Isn't duck typing more like late binding than a type system? It can be argued that duck typing is not really a type system in the sense of run-time or compile-time type systems. Type systems typically prescribe rules for defining types, for deducing types from expressions, for determining legality of expressions or storage based on types, and so on. Duck typing doesn't do any of these. Joe Esposito has commented that, "Duck typing is based around conventions, written in the docs instead of code. This allows the language to defer the type system".
Late binding is when an object or method is bound to a name at run time. Duck typing looks similar to late binding except for a subtle difference that it's based on behaviour rather than declared type.
One way to understand this is to recognize that C# (a static typed language) allows for method overloading where methods differ only by their arguments types. This is not possible in Python (dynamic typed language) but duck typing fills in since run-time behaviour is emphasized rather than the type of the object passed to the method. Also, because it's interpreted and does late binding, duck typing is easy to do.
-
Can you compare duck typing with structural typing? Joe Esposito makes a distinction between static duck typing and dynamic duck typing. With the latter, compile-time checks are skipped and this is what we mean when we refer to duck typing. Static duck typing is similar to structural typing that some static typed languages (Scala, F#) support. Structural typing allows for some compile-time checks, not on types but on the supported methods/attributes. Structural typing may be seen as a compiler-enforced subset of duck typing. However, we should also note that structural typing is essentially static typing while duck typing is dynamic.
Just as duck typing is for dynamic typed languages, so is structural typing for static typed languages. Erlang's Behaviours can be seen as static duck typing, that is, with compile-time checking.
Among the languages that support structural typing are Scala, OCaml, Go, Elm and PureScript.
-
Can we say that duck typing is another name for implied interfaces? Static typed languages use explicit interfaces. In C#, we use interfaces: any type that implements an interface can be passed into a method/function that accepts that interface. This was how flexibilty was built into static typed languages but this required upfront interface declaration.
Python doesn't have explicit interfaces: interfaces are implied. For Python, this is not different from duck typing. However, implied interfaces are supported by C++ (for example) in its STL library. Given that C++ does compile-time checks, we can't say in general that implied interfaces is the same as duck typing. Note that when interfaces are implied, there's no formal interface definition, and at best, it may be a shared documentation.
-
What is goose typing? In Python, duck typing is an implied or informal interface. This is sometimes called a protocol. For instance, any class or object that implements
__len__
and__getitem__
is said to conform to the sequence protocol. Therefore, it can be accessed as if it's a sequence. The sequence can be indexed or sliced.With goose typing, the interface or protocol is made explicit. This is done using an Abstract Base Class (ABC). In the call
isinstance(obj, cls)
, the second argument must be an ABC. The ABC class itself can't be instantiated but another class provides an implementation of the expected interfaces. However, this other class is simply registered (via a decorator) as conforming to the ABC's interface; that is, it's not explicitly derived from the ABC. For this reason, we call goose typing as "virtual subclassing of Python ABCs."Among the languages supporting goose typing are Python, TypeScript and Go.
-
What languages support duck typing? - Python and Ruby support duck typing, both of which are dynamic typed languages. In general, dynamic typed languages such as JavaScript and TypeScript support duck typing. While C# doesn't, some parts of .NET use duck typing.
- In Ruby, for example,
StringIO
doesn't haveIO
in its class hierarchy. Yet, it behaves like anIO
due to duck typing. In fact, we may say thatStringIO
andIO
share a common protocol, which is exactly how the duck typing concept is seen in OOP languages such as Smalltalk and ObjectiveC. This can be said of Python as well. For example, an iterable is one that supports the iterator protocol, which is nothing more than implementing necessary methods for an object.
- In PHP, PHP's dynamic typing system and object-oriented features enable duck typing to a certain extent.
- It's interesting to note that duck typing has inspired the creation of a new language called Duck.
-
How is duck typing related to LBYL and EAFP? LBYL expands to Look Before You Leap while EAFP expands to Easy to Ask for Forgiveness than Permission. Both these concepts are typically discussed in Python (and possibly other languages as well). Python prefers the EAFP approach, which is the opposite of LBYL.
With LBYL, we typically check if an object is of a compatible type before performing operations on it, such as calling its method. Python has a built-in function
isinstance()
to do this. With EAFP, we simply call the object's method, expecting that method to be present. If it's not, an exception will be thrown by the Python interpreter, which the code is expected to handle.With duck typing, validating an object's type is not Pythonic. Thus, duck typing plays well with Python's preference for EAFP though the use of
hasattr()
can be used instead.
Milestones
Emil Mazey states at a meeting that "I can’t prove you are a Communist. But when I see a bird that quacks like a duck, walks like a duck, has feathers and webbed feet and associates with ducks—I’m certainly going to assume that he is a duck." The phrase might have originated earlier from James Whitcomb Riley (1849–1916).
2000
What may be the one of the earliest use of the term "duck typing" among programmers, Alex Martelli discusses it on the comp.lang.python
Google Group as an alternative to method overloading of C++. He states that duck typing is closer in spirit to polymorphism of C++. He clarifies,
You don't really care for IS-A -- you really only care for BEHAVES-LIKE-A-(in-this-specific-context), so, if you do test, this behaviour is what you should be testing for.
Sample Code
References
- Adamko, Martin. 2022. "Duck Types for PHP." Github, January 17. Accessed 2022-01-17.
- Atten, John. 2014. "Is Duck Typing a Type System, or a Way of Thinking?" January 4. Accessed 2017-12-28.
- Beust, Cedric. 2005. "The Perils of Duck Typing." Otaku. April 15. Accessed 2017-12-28.
- C2 Wiki. 2013. "Walks Likea Duck." Cunningham & Cunningham. June 14. Accessed 2017-12-28.
- C2 Wiki. 2014. "Duck Typing." Cunningham & Cunningham. January 7. Accessed 2017-12-28.
- Cannon, Brett. 2016. "Idiomatic Python: EAFP versus LBYL." MSDN blog. June 29. Accessed 2020-05-27.
- Cook, William R. 1992. "Interfaces and specifications for the Smalltalk-80 collection classes." Proceeding OOPSLA '92 conference proceedings on Object-oriented programming systems, languages, and applications, Vancouver, British Columbia, Canada, October 18-22, pp. 1-15. Accessed 2018-08-28.
- Cui, Yan. 2015. "Why I like Go’s interfaces." The Burning Monk. May 11. Accessed 2017-12-29.
- Foord, Michael. 2011. "Duck Typing in Python: What Type is My Data?" Voidspace. August 2. Accessed 2017-12-28.
- Haack, Phil. 2014. "Duck Typing Is More Than Quackery". Haacked. January 4. Accessed 2017-12-28.
- Hettinger, Raymond (ed). 2019. "What’s New In Python 3.8." Release 3.8, October 14. Accessed 2021-11-23.
- Janmyr, Anders. 2010. "Static Typing." Jayaway blog. April 14. Accessed 2017-12-28.
- Kim, Don. 2017. "Duck Typing vs. Goose Typing, Pythonic Interfaces." Blog, tl;dr, July 17. Accessed 2021-12-15.
- Langa, Łukasz. 2018. "PEP 569 -- Python 3.8 Release Schedule." Python Developer's Guide, January 27. Accessed 2021-12-15.
- Levkivskyi, Ivan, Jukka Lehtosalo, and Łukasz Langa. 2017. "PEP 544 -- Protocols: Structural subtyping (static duck typing)." Python Developer's Guide. March 5. Accessed 2017-12-29.
- Lippert, Eric. 2014. "What is duck typing?" Blog: Fabulous adventures in coding. January 2. Accessed 2017-12-28.
- Martelli, Alex. 2000. "polymorphism (was Re: Type checking in python?)." comp.lang.python, Google Groups, July 26. Accessed 2018-08-28.
- Mastracci, Matt. 2014. "Succinct and accurate." Twitter. November 23. Accessed 2017-12-29.
- Mikera. 2011. "What is the supposed productivity gain of dynamic typing?" StackExchange. November 29. Accessed 2017-12-28.
- Programiz. 2017. "Python Iterators." Accessed 2017-12-28. Accessed 2017-12-28.
- Python Docs. 2017. "Glossary." V3.6.4. Python Software Foundation. October 4. Accessed 2017-12-11.
- Ramalho, Luciano. 2015. "goose typing is a new term coined by..." Tweet, on Twitter, January 28. Accessed 2021-12-15.
- Ramalho, Luciano. 2020. "Overview of the 4 approaches to typing available in modern #Python." Tweet, on Twitter, October 15. Accessed 2021-12-15.
- Reigel, Alexis. 2012. "Static vs dynamic vs strong vs weak vs duck typing." March 19. Accessed 2017-12-28.
- Ronacher, Armin. 2014. "Revenge of the Types." Thoughts and Writings. August 24. Accessed 2017-12-28.
- Schafer, Corey. 2016. "Python Tutorial: Duck Typing and Asking Forgiveness, Not Permission (EAFP)." YouTube. February 9. Accessed 2017-12-28.
- Schuster, Werner. 2007. "Duck Typing and Protocols vs. Inheritance." InfoQ. November 30. Accessed 2017-12-28.
- Shannon, Mark. 2021. "[Python-Dev] Re: Keeping Python a Duck Typed Language." Python Mailing List, April 21. Accessed 2021-12-15.
- Shindich, Alex, and Curt Hagenlocher. 2001. "Implied Interface." Shindich.com. November 30. Accessed 2017-12-28.
- Sirkovský, Marek. 2016. "Duck typing in C#." Medium, October 31. Accessed 2018-08-28.
- Sitaker, Kragen Javier. 2002. "isinstance() considered harmful." The Canonical Hackers. March 1. Updated 2016-11-30. Accessed 2017-12-28.
- Telastyn. 2014. "How can a statically typed language support duck typing?" StackExchange. August 11. Accessed 2017-12-28
- Underwood, Tim. 2017. "A Brief Intro to Scala." SlidePlayer. Accessed 2017-12-29.
- Wikipedia. 2017. "Duck typing." December 25. Accessed 2017-12-28.
- Wikipedia. 2018. "Duck test." August 25. Accessed 2018-08-28.
Further Reading
- Atten, John. 2014. "Is Duck Typing a Type System, or a Way of Thinking?" January 4. Accessed 2017-12-28.
- Block, Glenn. 2014. "On Duck Typing." Code Better. January 5. Accessed 2017-12-28.
- Scarioni, Carlo. 2013. "Duck Typing in Scala: Structural Typing." DZone. February 20. Accessed 2017-12-28.
- Brown, Gregory. 2010a. "Duck Typing in Practice, Part 1." Practicing Ruby. December 28. Accessed 2017-12-28.
- Brown, Gregory. 2010b. "Duck Typing in Practice, Part 2." Practicing Ruby. December 31. Accessed 2017-12-28.
- Zemek, Paulo. 2010. "DynamicObjects – Duck-Typing in .NET." Code Project. November 5. Accessed 2017-12-28.
Article Stats
Cite As
See Also
- Static vs Dynamic Typing
- Strong vs Weak Typing
- Nominal vs Structural Typing
- Early vs Late Binding
- Class Inheritance
- Object-Oriented Programming Concepts