A while ago, Vittorio tweeted the article “In defense of complicated programming languages” and the same way it resonated with him, so did it with me and I wanted to share a few thoughts.
Show Don’t Tell
The first part the author articulates very well, that it’s important for people and especially new beginners, to understand the problem before the solution and I totally agree with that.
You see this often happening, when trying to help a beginner with a topic and they don’t want to simply accept the coding advice given. It’s more often than not, they don’t understand “the problem”, thus the provided solution or path doesn’t make sense to them. It then is important to explain the reasoning behind it and not just point to “good practice” — of course every now and then, you’ll find a stubborn person that is not convinced, for those it’s probably easier to let them make their own hands-on experience, even if it means a lot more suffering for them.
This however doesn’t just apply to coding tips, but also to a lot of situations at work or life in general. When you start with a new feature and you don’t understand the problem this feature is solving, how good of an implementation can you really provide? How much do you rely on perfectly defined specifications or when do you use your own brain to think of better solutions, which can only be inferred by knowing the business case and your own experience with the code base?
Concepts Don’t Need Language Support
The second point essentially destroys a lot of programming language “discussions”, of which language is better than the other and what language has the better features. But first going one step back…
Simplicity of a language is often quite praised; it’s one of the main points people use to describe C for example. But the article makes it clear, that more often than not, you’ll simply end up rebuilding some more complex concepts from other languages, except without “native” language support. C and C++ are such a good example, because C++ originates from “C with classes”, meaning in order to escape the need of ugly macros and struct magic, a new language with native support for classes was born. Yet, you still see plenty of C code, emulating class-behavior to some extend.
Circling back, the different languages have all their use cases, whether “simple” or complex. The important part is to remember the trade-offs you take in either direction. If you stick with C and keep writing class-like code, then you spend a lot of time reinventing the wheel and your compiler doesn’t even help you find potential issues. On the other side, if your main enemy is the missing stable C++ ABI and you write a lot of free functions, maybe switching to C could provide some benefits.
And finally – to not miss the point of the whole article – moving up the complexity ladder might seem or actually be limiting to some extend, but as a trade-off you’ll receive more predictable output, fewer ways to break things and the tooling can help you write better code from the start.
One thing that didn’t make it into the first part is, that I really like the “demonstration” that classes aren’t just constructs that we use, because we can, but that they solve a real issue of managing complexity through abstraction. It’s not uncommon to run into people from the “OOP is the worst”-camp, who then try to avoid classes at all cost. I believe they haven’t understood the problem that classes solve and/or they see classes only as solution to writing big inheritance trees in an object-oriented fashion, which of course is completely wrong…
I hope the article resonates with a few more people and hope that we can all focus much more on explaining or even showing the problem, before trying to force feed our solutions.