Moving from C++ to Objective-C was a revelation to me.
In C++, dynamic lookup was a chore. Because the language was relatively static, if you wanted to go from an arbitrary key to code, you had to write your own custom lookup table.
I remember writing a lot of registration code, a lot of boilerplate. For each class or method I wanted to look up, I would put an entry in the lookup table. Maybe it was part of an explicit factory method, maybe it was a C macro, maybe it was some sort of template metaprogramming magic. But there had to be something, and you had to write it every time.
Boilerplate, boilerplate, boilerplate. Over and over again.
In Objective-C, the dynamic lookup mechanism was built into the language: dynamic dispatch. Look up any class, any method, with just a string.
I remember reading somewhere — I wish I remember where — a post where someone pointed this out, that the C++ technique and the Objective-C technique both required lookup tables, but in the latter case, it was maintained for you by the Objective-C runtime. Objective-C didn’t reduce the inherent complexity, it just hid it, made it uniform.
The LLVM team, on the other hand, has been trying to kill dynamic dispatch for a long time.
Since ARC, calling arbitrary methods by string, the core of dynamic dispatch, by default triggers a warning.
And of course, in pure Swift, dynamic dispatch is completely absent. Everything must be known ahead of time by the compiler.
I understand why. They want to make it more safe.
Does that mean we’re seeing the reinvention of the custom lookup table in Swift?
Swift enumerations, for example, make this relatively easy, since you can pair methods, i.e. arbitrary code, with each enumeration case.
If I have to write a new enum case for every new class, though, then I consider that unnecessary boilerplate, a throwback to C++ techniques. Boilerplate.
And I wish we didn’t have to go back down that road.