Table of Contents
On ducks
Walter Reuther, who summoned the United Auto Workers into being was asked whether he could recognize Communists infiltrating the labor movement. See, he was asked, in the Fifties, everyone had completely forgotten that in the Thirties the rather bland American version of the godless Ruskie communism wasn't in all that bad odor. Until the word came down that everyone had to stop denouncing Hitler as the Devil once he and Stalin hooked up pre-war and then had to reverse course quickly on the roads to Moscow. "How do you identify communists, sir?"
If it looks like a duck, walks like a duck and quacks like a duck, then it just may be a duck.
The bot version
From my buddy Claude, because I'm too lazy to evaluate the question.
Duck typing is a concept in dynamic programming languages which refers to determining how to handle objects based on their properties and methods rather than their explicit type. The name comes from the phrase "if it walks like a duck and quacks like a duck, it must be a duck".
Here are some key points about duck typing:
- Duck typing avoids the need to explicitly declare types and rather relies on the presence of certain methods and properties on objects to determine their compatibility and behavior.
- It is commonly used in languages like Python, Ruby, JavaScript, and PHP where variables are not bound to specific data types but can hold data of any type.
- When using duck typing, type checking happens at runtime rather than compile time, so errors occur if expected properties or methods are missing.
- The advantage of duck typing is increased flexibility - new classes can be usable without having a subclass or inheritance relationship if they simply implement the required behavior.
- A downside is that it makes applications more prone to errors, harder to document, and less compatible across versions if assumptions about object capabilities change.
In summary, duck typing is an approach that provides greater flexibility and abstraction in dynamic programming languages by treating objects based on their current properties and capabilities rather than their formal type metadata. It allows polymorphic use of components if they share common behaviors.
Why do we care
Static typing requires that we decide in advance whether a variable name that we create is going to hold fish or fowl. Is it the character "9" or is it the integer 9, or is it a float 9.0? That's just the tip of the iceberg.
Where did this come from
Of old memory was precious. How precious? Bill Gates never said
nobody will every need more than 640kb memory
but we insist that he did, just as Larry McMurthy misquoted The Man Who Shot Liberty Valence
when you had to choose between history and legend, print the legend
when that was a ten-fold improvement over the first gen home computers, as they were then quaintly called.
It mattered because there was only so much memory space to go around (the same limitation that resulted in the ominous sound of disk thrashing as programs swapped into and out of memory from the horse-and-buggy hard drives). You had to explicitly reserve yours.
void* malloc(size_t size);
(and then be sure to take out the garbage later).
The Noah of modern languages, C
was pretty mellow about this—it would just refuse to compile. It's offspring C++
is kind of like a paroachial school teach—you are not permitted to put either your immortal soul nor the Word of Assembler into hazard and it will choke on every possible ambiguity or deficency. The Reformation is lead by languages like Rust
that attempt to implement type safety without all the moral opprobrium by making wrongful expressions just plain non-syntactical.
The there is Python
and its wannabes. Life in an interactive session is short, too short, to be overly concerned in these days of abundant memory to bother with such niceities as declaring the type of a variable. In fact, let's procratinate and not even bother to allocate memory at all unless we really have to. Might not even get around to it, after all.
How it hangs
All very well and good, but really? Let's change from abstract to concrete.
In the R
programming language an assigment of a value to a variable is done using the assignment operator, which is represented by the symbol <-
. You can also use the =
symbol, which has the unfortunate side effect of messing with old habits that reserve this token for the equality operator, which is actually ==
. St. Brian of Kernighan justifies the convention in the context of the C
language by the quite reasonable observation that assignment is more common than equality tests.
Stevie Nicks, a pop goddess of the last century had a signature look—free-spirited, bohemian aesthetic, "groovy", "witchy," featuring dramatic hats, handkerchief hems, beaded and fringed shawls, and ribbon-adorned tambourines and the long black dresses of vintage materials, fringed, flared sleeves and flowing lines. When asked about it once, she owned the characterization, saying
When I started dressing that way, I didn't know that I'd be stuck with it forever.
Drives me batty, but what are you going to do? I try to be particular sticking to <-
by using a keyboard macro. So,
x <- 10
y <- "z"
are the characters .la meaning left assignment
that automagically expand to <-
.
The assignment operator should be conceptualized creating a label, x
that associates with a value in memory, expressed as 10 decimal referred to as an object
because everything in R
is an object, down to the three amigos in function signatures— $\text{some_function}(x,y, ...)$ that stands for "maybe some optional arguments here and if provided memory will be allocated for that purpose."
In making assignments, by default R
is agnostic. It won't decide whether values are fish or fowl until it's time to cook with them. R
is famously lazy, wasting no effort keeping track of types until asked to do some operation that depends on what type it is. Some don't,
> print(x)
[1] 10
> print(y)
[1] "a"
The print
function is happy to accept objects without complaint and then gaze into its navel to pick a method for display; in this case x
displays the number 10, without quote marks, and y
displays the letter a
with them. Of course
> x <- "10"
> print(x)
[1] "10"
there is implicit typing like that.
What's not to love?
Stay tuned.