Object orientated versus functional programming
One of my favourite koans is from Anton van Straaten:
The venerable master Qc Na was walking with his student, Anton. Hoping to prompt the master into a discussion, Anton said "Master, I have heard that objects are a very good thing - is this true?" Qc Na looked pityingly at his student and replied, "Foolish pupil - objects are merely a poor man's closures."
Chastised, Anton took his leave from his master and returned to his cell, intent on studying closures. He carefully read the entire "Lambda: The Ultimate..." series of papers and its cousins, and implemented a small Scheme interpreter with a closure-based object system. He learned much, and looked forward to informing his master of his progress.
On his next walk with Qc Na, Anton attempted to impress his master by saying "Master, I have diligently studied the matter, and now understand that objects are truly a poor man's closures." Qc Na responded by hitting Anton with his stick, saying "When will you learn? Closures are a poor man's object." At that moment, Anton became enlightened.
A lot of my early experience with programming was with mainstream object-orientation through C++ and later Java. In particular, I spent a couple of internships at youDevise writing mainly Java with some excellent colleagues. While there, I learnt a few things.
Firstly, I discovered that I really disliked (implementation) inheritance. I find the template pattern to be a bad way of structuring code, with composition being much simpler to understand. Inheritance makes it easy to introduce cycles in the dependency tree of your code, which is generally a bad sign. Composition tends to be simpler, and makes the flow of control more explicit, while still having much of the same power. In the interest of testing extremes to explore the idea, I started trying to write code without using any inheritance (unless forced to by somebody else's design), and seeing how far I could get before I had to resort to using inheritance again. Several years later, I'm still at that extreme, and quite happy there.
I also learnt that JavaScript is a lot nicer than I had previously realised. As with many people at the time, I had assumed that it was a toy language, and that my difficulty in writing clean JavaScript was entirely the fault of the language, rather than my fault in not learning how the language actually works.
I eventually realised that closures combined with object literals in JavaScript could be just as powerful as classes and objects in Java, and (arguably) conceptually far simpler. It was that realisation that first piqued my interest in language design, leading to further questions:
- What features do programming languages need, and which are somewhat redundant?
- If we carefully choose the features of a language, can we conceptually simplify the language?
- Does this conceptual simplification come at some cost? Does it make code harder to read and write?
- What trade-offs do we make in a language? What happens if we design a language so that code is as understandable and readable as possible, even at the cost of, say, speed of writing that code?
- How can we design a language to make certain bugs less likely, or even impossible?
- How do features in a language interact?