Chapter 6. Datatypes and Protocols
While programming in other languages, many of us have experienced this situation: you have crafted beautiful interfaces obeying all laws of good design, just to realize that you must deal with an object provided by another module over which you have absolutely no control. There’s little hope that the maintainers of this module will ever add support for your interface—be it for technical, political, or legal reasons. In no time you are now juggling (drowning in?) adapters and proxies.
The luckiest among us work in languages dynamic enough to allow monkey-patching, where classes are open and methods can be jammed into those classes when necessary in order to bridge the distance between one interface and another. Thankfully, the term is disparaging enough to make you twitch and think twice before using it, since such surgery carries an armload of complexity, caveats, and pitfalls.
The fundamental problem behind these symptoms has previously been named the expression problem:
The Expression Problem is a new name for an old problem. The goal is to define a datatype by cases, where one can add new cases to the datatype and new functions over the datatype, without recompiling existing code, and while retaining static type safety (e.g., no casts).
—Philip Wadler, http://www.daimi.au.dk/~madst/tool/papers/expression.txt
Some argue whether the expression problem in dynamic languages is still the expression problem as originally coined by Philip Wadler. We are ...