Kelly Mears

Duck Typing

Treating an object as suitable for a role based on what it can do, not what type it's declared to be.

Computation & Algorithms2 min read284 words8 out · 6 in
also calledStructural Typing

Duck Typing decides whether an object fits a role by checking whether it supports the operations that role requires, not by checking its declared type. "If it walks like a duck and quacks like a duck" — a Python function that calls .read() on its argument works on a file, a socket, or an in-memory io.StringIO, with no shared base class required, because none of them need to declare "I am readable" up front; they only need the method to exist.

This is a runtime discipline in dynamically typed languages: nothing checks that the object supports .read() until the call actually happens, so a duck-typed program can fail with an AttributeError deep inside a function, well after the mismatched object was first passed in. Statically typed languages get a checked version of the same idea through structural typing — TypeScript's interfaces and Go's interfaces are satisfied by any type with the matching shape, with no explicit implements declaration needed, so the compiler verifies the "quacks like a duck" claim before the program runs instead of after.

The distinction that matters is structural vs. nominal typing, not static vs. dynamic: Java's interfaces require an explicit implements clause (nominal — the type's name is what matters), while Go's and TypeScript's require only the right method set (structural — the shape is what matters), and duck typing is the dynamically-checked, no-declaration-at-all limit of the structural side.

The common failure is an object that has the right method name but a subtly wrong contract — a .close() that doesn't release the resource, a .length that isn't actually a count — passing every duck-typing check while breaking the caller's assumption, since nothing in the mechanism verifies behavior, only presence.

See also8

Type Inference

A compiler deriving a value's type from how it's used, so a programmer doesn't have to write it down.

Computation & Algorithms10 connections

Reflection

A program inspecting or modifying its own structure — types, methods, fields — while it runs.

Computation & Algorithms5 connections

Schema Validation

Checking data against a declared shape at runtime, and using the result as the typed value.

Agents & Language Models22 connections

Pattern Matching

Testing a value against a shape and binding its parts to names in one step, instead of inspecting it field by field.

Computation & Algorithms7 connections

TypeScript

Microsoft's typed superset of JavaScript, whose types are checked at build time and erased at runtime, and the deliberate trade-offs that made it the default for large web codebases.

Web Platform8 connections

Type System

The rules a language uses to classify values and reject operations that don't fit, checked before the program runs or as it runs, and the cheapest form of verification most programmers use every day.

Testing & Verification12 connections

Generics

Writing code once over a type variable so it works for any type, how languages implement it by erasure or by copying, and what constraints on type parameters buy.

Computation & Algorithms7 connections

Prototype Pollution

A JavaScript vulnerability where attacker-controlled keys like "__proto__" modify the prototype every object inherits from, silently adding properties everywhere, and how merge utilities and parsers let it in.

Web Platform10 connections

Linked from6