Learn the vocabulary of accepting any object that has the right methods, regardless of its declared type.
0 / 5 completed
1 / 5
At standup, a dev mentions passing an object into a function that never checks its declared type, only calling whichever methods it expects that object to have, and it works fine as long as the object actually implements those methods. What is this approach called?
Duck typing is exactly this: a function never checks an object's declared type at all, it simply calls whichever methods it expects that object to have, and the call works fine as long as the object actually implements those methods, regardless of what class or interface it was formally declared as. Generics are a related but distinct concept about parameterizing a function or type over a type parameter, which is a compile-time mechanism rather than duck typing's behavior-based, often runtime, approach. This focus purely on "does it have the methods I need" rather than "what is its declared type" is exactly where duck typing gets its name, from the idea that if it walks like a duck and quacks like a duck, it's treated as a duck.
2 / 5
During a design review, the team writes a function that accepts any object with a `.read()` method, without requiring that object to declare any particular interface or base class. Which capability does this duck-typed approach provide?
This duck-typed approach provides accepting any object that happens to implement `.read()`, regardless of its declared type, without requiring that object to formally implement a specific interface or extend a specific base class first, so a file handle, a network stream, and an in-memory buffer can all be passed into the same function as long as each one happens to have its own `.read()` method. Requiring every passed-in object to formally declare a specific interface would instead exclude any object that has the right behavior but wasn't explicitly written to declare that particular interface. This flexibility to accept anything with the right shape, not the right declared label, is exactly the appeal of duck typing.
3 / 5
In a code review, a dev notices a duck-typed function calls `.read()` on whatever object is passed in with no check at all for whether that method actually exists first, and an object missing that method causes an unhandled error deep inside the function. What does this represent?
This is a missing capability check, since duck typing's whole flexibility comes from skipping any formal interface declaration, which also means there's no compile-time guarantee that a passed-in object actually has the method being called, so without the function's own runtime check, or at least a clear, well-placed error, an object missing that method causes an unhandled error somewhere deep inside the function instead of a clean, understandable failure at the boundary. A cache eviction policy is an unrelated concept about discarded cache entries. This tradeoff, flexibility in exchange for weaker guarantees, is exactly why a duck-typed function benefits from its own explicit capability check or a well-documented expectation, even without a formal interface enforcing it.
4 / 5
An incident report shows a data-processing pipeline crashed with a confusing, deeply nested error message, because a duck-typed function called `.read()` on an object that turned out not to actually implement that method, with no check or clear error message at the point the object was first accepted. What practice would prevent this?
Adding an explicit capability check, or at minimum a clear, early error message at the point the object is first accepted, confirms it actually has the expected `.read()` method before the function proceeds any further, turning a confusing, deeply nested crash into a clean, understandable failure right at the boundary, which is exactly the fix for the incident described here. Continuing to call `.read()` deep inside the function with no upfront check at all is exactly what produced the confusing error message when an incompatible object was passed in. This early, explicit capability check is a standard practice for keeping duck typing's flexibility while still failing clearly and quickly when an object doesn't actually meet expectations.
5 / 5
During a PR review, a teammate asks why the team relies on duck typing for this function instead of just requiring every caller to pass in an object that formally implements a specific declared interface. What is the reasoning?
Requiring a formal, declared interface would exclude any object that genuinely has the right behavior, the right methods, but simply wasn't written or designed to explicitly declare that particular interface, which can rule out perfectly usable objects from unrelated libraries or codebases. Duck typing instead accepts anything with the right shape at the call site, regardless of how it was declared, at the real cost of losing a compile-time guarantee that the object actually has what's needed, pushing that check to runtime instead. The tradeoff is exactly this flexibility-versus-guarantee tension, which is why duck typing is embraced in some languages and contexts and deliberately avoided in favor of stricter interfaces in others.