

Is Go Duck-Typed?
source link: https://bionic.fullstory.com/is-go-duck-typed/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Suppose you see a bird walking around in a farm yard. This bird has no label that says 'duck'. But the bird certainly looks like a duck. Also, he goes to the pond and you notice that he swims like a duck. Then he opens his beak and quacks like a duck. Well, by this time you have probably reached the conclusion that the bird is a duck, whether he's wearing a label or not.
The previous quote was not the first invocation of the duck test but it is the most famous. The usage of this test may date back to the early 20th century as a way of arguing that “given the properties I can observe about some object, I’m going to classify it as what it appears to be.” It is sometimes deployed as a counterargument to claims that something is not what it seems.
The question before the house today is this: Is go duck-typed? Other languages claim to be so (see below), and the go team has mentioned in public presentations an affinity for this particular type strategy.
Duck Typing
In programming languages, duck typing can be roughly approximated as the application of the duck test to objects. To increase the precision slightly, a type is defined to be a collection of things that the type can do. Let’s try a go-ish example:
Thus, we will define some type to be an Animal
if it can return the number of legs it has. The previous is an example of an interface in go, so it implies that there are one or more implementations. An interface in go is a “test” in the sense of the duck test above; this type declaration is an animal test .
Given the animal test, let’s define a whole zoo!
Given the current Animal
interface definition, these are all duck-typed as Animal
:
Spider Dog Stool
Surely, one cannot have intended a three-legged stool to be an animal?!? Well, if one applies the—admittedly weak—animal test that we constructed with the interface Animal
above, the stool certainly passes. The critical idea of duck typing is “can I use the object in question in the way I want” and if so, the object passes the test. Clearly we can improve our definition of the animal test in this way:
With this better version of Animal
we can (correctly?) disallow a stool to be considered an animal because it has no Genus()
method. This example may seem contrived but by perusing the go standard library one will notice that a great many of the go standard interfaces have one or two methods. In fact,with a small program, one can compute the histogram of the number of methods that occur in interface declarations in the go standard library.

The histogram above indicates that number of interfaces with one or two methods is greater than three times all the others combined!
Duck Typing and Comparative Programming Languages
The notion of a “type” in a programming language goes back to the origin of programming languages. The arguing about what is a “type” in programming languages goes back to five minutes after the origin of programming languages. Many Ph.D. theses have been written about these arguments, entire conferences are dedicated to the subject, and books are written in an attempt to formally define a type (for example, A Theory of Objects or the Z notation ).
For the purpose of simplicity we will define an interface to be a type that specifies a contract about how an instance of the type will perform his duties. One could say that the first widely known programming language with the “object must meet the contract” paradigm was Eiffel in 1985, although this is arguable. Given our (simplistic) definition of an interface/contract how do programming languages differ? We’ll divide languages into two categories: those that require the specification of the interface and those that do not.
The most common reason for requiring that an interface be defined is performance, although there are others. The general reason that specifying interfaces provide additional performance is that a traditional compiler or a Just-In-Time (JIT) compiler can make assumptions about the underlying memory layout so long as the specification of the interface is enforced by the language. To use our improved example above with Animal
, a hypothetical compiler could assume that the method NumberOfLegs
is 0 bytes from the memory address of the instance implementing Animal
and the method Genus
is located 8 bytes from the memory address of the instance. So long as said compiler also enforces this requirement when compiling the implementation of Spider
and Dog
, the code that accepts an Animal
can 1) not need to know the true type of the instance passed as a parameter and 2) jump (branch) directly to the memory address of the implementation of NumberOfLegs
or Genus
for fast performance. Today, many compiled, object-oriented languages from Java (1991) to C# (2000) and from Rust (2010) to Swift (2014) operate with these explicit interfaces (this list is far from exhaustive!).
The other alternative is, well, to just wait. This is the case that is usually considered to be duck typing. In this formulation, you simply pass any type as a parameter to any function or method and wait to see if the parameter is used in a way that is acceptable. So, if type Spider
is passed to method Anatomy(a)
as the parameter a
, there is no check to see if Spider
will work in all code paths inside Anatomy
. We simply try to run the program and see if the method calls on a
( neé Spider
) work out. If they don’t, we generate an error and abort Anatomy
. You can easily imagine a dumb definition of Anatomy()
which only calls NumberOfLegs()
and since that is allowed on Spider
, the Spider
as a parameter is ok. Notably, the use of Stool
as parameter a would be ok too! In this model, the “contract”–if one can be said to exist–is implicit and varies with the exact code path that is taken through the function Anatomy
. Languages like Python (1990) and Ruby (1995) operate in this fashion; the Python community popularized the phrase “duck typing” for this behavior.
Duck Typing and Go
Go is an unusual hybrid of these two ideas. Let’s think about an example: Joe has defined and has exported this package somedwarf
:
Joe compiles this code and makes it available to his team. A week later, Mary writes this code:
If Mary runs her code from main()
she’ll see “dwarf is sad” and then on the next line “dwarf is happy.”
Given our poor man’s definition of duck typing earlier, when the language waits to see how the type is used, which case are we in here?
Does go have duck typing or not?
One can make the case that in the small we are in the first case explained above: the interface has to be explicitly defined. Within the code written by Mary, it seems fairly clear that the interface IsHappy
is defined so that it can be used to type check the uses of the parameter h
in PrintHappy
. As we explained previously, IsHappy
is being used to accelerate the call to h.Happy()
inside PrintHappy
.
In the largethough, one can easily argue that we are in the duck typing case above. Joe’s code didn’t know or care about Mary’s code, and since g
in Mary’s code worked because it had the proper method for Happy()
that is used in (Mary’s) PrintHappy()
that effectively we just waited to see if Grumpy could legitimately be used successfully in PrintHappy
.
What do we conclude from this? Sometimes, you have to embrace the ambiguity!
Happy go-ing!
Recommend
-
42
-
19
Duck-typing Programming 2019年11月13日 翻译自Duck Typ...
-
10
Dependency Injection, Duck Typing, and Clean Code in Go 22 Apr 2015 3 Comments Along the path to learning...
-
10
Welcome to the refuge... now duck! Writing Software, technology, sysadmin war stories, and more. Thursday, March 7, 2013 Welcome to the refuge... now du...
-
10
The art of Rubber Ducking or Rubber Duck Debugging Sponsored By It works. Really. "Put a rubber duck on your monitor and tell it how the code is supposed to work."
-
10
Rubber duck debugging From Wikipedia, the free encyclopedia Jump to navigation
-
4
Get it? Quack quack quack quack Quack quack quack quack Weird Al Yancovic,“I Want A New Duck” Mypy make...
-
7
Duck Typing in JavaScript and TypeScriptDuck Typing for beginnersPhoto by Anne Nygård on
-
8
Duck typing vs type safety in Ruby Posted on November 2, 2016 by solnic Blog
-
7
Introducing ducktor: Duck typed constructors for Rust structs with wasm-bindgen JsValue Interacting with JavaScript objects in WebAssembly can be challenging, especially when it comes libraries providing an ergonomic API for e...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK