The Witcher universe (the books/games) features a group of folks called 'witchers': mutated superhumans, trained in the ways of sword combat and battle-magic, who can imbibe toxic potions to enhance their abilities to almost supernatural effect.
They readily take on 'witcher contracts' - issued by individuals, communities or even kings and queens, whose selves, villages or towns/states are plagued by humanly, elvenly or otherworldly beings - and take down monsters and magical/supernatural (and sometimes political) threats.
The interesting part about witcher tales isn't always the monsters; rather, it's the philosophical or existential discussion invoked by the encounter, and this question: are they really the monsters? So contracts often involve a witcher investigating an issue, tracking down the problematic human/creature involved and then deciding what course of action to take - slay, negotiate, or release?
Here's the thing though: if I were a king with a vampire infestation problem, and I had a Go programmer as the hiring-administrator of my realm, how would I let him hire a witcher who meets the interface/standards of my vampire-killing bounty?
People can be classified differently, but one very common way of classifying them is by what they do.
Some people do very specialized things; for instance, some people may be especially competent at killing. Depending on context, we call them 'soldiers', 'mercenaries', 'bounty hunters', 'sellswords', and so on.
But what do those types of persons have in common? They have a method of killing others, i.e:
kill_person()
Well, what of people especially competent at killing specific monsters, say vampires and basilisks? They would have these methods:
kill_vampire()
kill_basilisk()
You could call the above folks 'vampire killers' or 'basilisk killers'. But what about some people who can do both? You might call them instead 'monster hunters' - a more general idea of what they can do. And you could say that the dualist-types implement these methods:
kill_monster()
We therefore have our first abstraction.
Consider as follows:
In the Go programming language, interfaces are "a set of method signatures".
Any separate type that implements the specified methods has (implicitly) implemented the interface.
Interfaces are sometimes called 'contracts' because they 'enforce' contracting types to meet their requirements. (As a lawyer myself, I see interfaces more as terms of contract - because they signify the points of the promise to be met by a contracting party, not the promise itself.) Thus:
A 'contracting party' must be a type of person who is able to meet their promises.
And they have certain methods of meeting those promises.
Now let's talk about witchers. Who or what is a 'witcher'?
Witchers are professional killers, who are methodically trained in the art of killing not just humans, but all manner of relevant beasties:
"...Silver for Monsters, Steel for Humans"
In Go, you could then create a Witcher
interface, specifying the abilities/methods that witchers must have:
type Witcher interface {
kill_human() ...
kill_beast() ...
kill_monster() ...
kill_elemental() ...
kill_hybrid() ...
kill_insectoid() ...
kill_necrophage() ...
kill_ogroid() ...
kill_relict()) ...
kill_specter() ...
kill_vampire() ...
}
Thus any type of person who can do those things (who "implements the methods") are (implicitly) witchers, they having the methods of and 'qualified' by the Witcher
interface.
(Note: in the universe, a person is a witcher by the fact of having gone through the 'Trial of Grasses'. That's a 'formal'/explicit recognition of sorts. But in Go, and unlike other programming languages, interfaces don't have to be explicitly declared. So for discussion's sake, it doesn't falsify the metaphor to assume that witchers are automatically qualified by what they can do, rather than by explicit declaration that they are witchers.)
We return to our king, whose realm suffers from vampiric pestilence.
His Go programmer/administrator, by flourish of his fancy feather-quill IDE-pen, drafts the qualifications (parameters) of his king's bounty to be thus:
I, Lord of the Realm, seek to hire a person with vampire-killing skills, to dispose of the vampires infesting my kingdom.
So we know that an interested applicant needs to have these methods at least: kill_vampire()
and kill_higher_vampire()
.
But what if the administrator penned this instead?
I, Lord of the Realm, seek to hire a Witcher, to dispose of the vampires infesting my kingdom.
...Why is this specification change, to a Witcher
interface, significant, or 'better'?
Because it asserts to all intending contracting parties that the person to be relied on must be a type of person with certain methods, who can reliably kill not just vampires, but more.
Seen from the perspective of the King, the use of the Witcher
interface for his bounty is arguably 'better', by virtue of:
modularity - the King isn't stuck with having to name a certain person ('only Richter Belmont/Guillermo de la Cruz need apply'), or certain types of person ('Vampire Killers only');
enabling assumptions/reducing type specifications - the King need not care what type of person applies, and in fact can assume that all persons applying must be qualified (and equipped with the killing methods of a witcher);
reducing refactoring - the King doesn't have to reissue/amend his decrees, if some classy palatial paladin raises his sword to the task, and demonstrates that he is as equally equipped with the requisite killing methods of a witcher (even though paladins aren't witchers);
designing to interfaces, not specific types - the King does not have to figure out in advance what types of monster hunters are out there (and there can be many) - he just says, "I want someone Witcher-like", and then waits for someone to meet the standards of witchers (instead of the king continously revising his bounty to meet the differing standards of monster hunters).
The Go programmer-administrator has therefore rightly served his king, by opening the king's problems to more types of persons who can solve or handle it, through his use of the Witcher
interface.
When learning programming languages, I like to learn new concepts through metaphors and association. Metaphors are leaky (like all abstractions are), but it's a quick way to understand programming abstractions! (And it's often faster to course-correct from inaccurate assumptions, than to generate new mental models.) This article demonstrates such an attempt.