今日推荐英文原文：《You Should Write Bad Code More Often》
今日推荐英文原文：《You Should Write Bad Code More Often》作者：Ygor Rebouças Serpa
You Should Write Bad Code More Often
And how to spot bad coding adviceEvery week a “don’t do this” article is posted somewhere. Don’t use inheritance, never write a singleton, scrum is dead. But are we really supposed to abandon it all? Is an if-statement really that bad a thing? How can we tell what advice is worth listening to?
There isn’t a perfect programming language, nor is there a right way to code. There are guidelines (and known pitfalls). Browsing through programming advice on the internet today is terrifying — everyone is telling you to stop doing something. Soon we’ll be out of commands to use. Everything is a source of bugs.
Consider this analogy: You don’t send a truck down a wooden bridge and expect it to reach the other side. That doesn’t means wooden bridges are dead nor that you should stop using trucks.
Programming languages give us tools. It’s up to us to know when, why, and how to use them. Don’t throw your hammer away because you hit your finger — improve your aim.
How to Spot Bad Advice?Good advice has three parts. First, the information itself, second, its when, and third its when not to. Bad advice often lacks the second and third part — it’s presented as something that always works.
A common theme is to “avoid inheritance at all costs.” If left without the when or when not to, you might end up blindly following this and lose one of OO’s most essential tools. Instead, consider the following: “inheritance is a great tool. However, deep hierarchies are often harmful.” This time around its clear that the problem is depth. This explanation is far more precise and provides a direct insight into the matter, telling us that shallow hierarchies are fine.
Another thing to keep an eye on is language. Many writers are trained to “write boldly and never ask forgiveness.” This kind of tone is known to do well on the internet and particularly Medium. The problem is that boldness for the sake of boldness is damaging. People forget to add that their advice is not for every case. To avoid sounding weak, they ignore the when not to.
Good advice is friendly, not intimidating. Recall all the genuine help you have had over the years. Has any of it been given angrily?
Rules of ThumbWhen it comes to coding, in particular, two rules of thumb apply:
1. Languages are expensive to create and maintain. If a feature keeps being added to new languages, it still has an important role to play.That’s why the global scope is still a thing, as is inheritance and the if-statement. Any article stating that those should be avoided entirely is missing a pretty important aspect of these features.
It is no wonder TypeScript is a thing. Typing has returned as loosely typed languages — you type just enough, the compiler fills the rest. This idea was so successful that it entered the C# and C++ worlds, through the var and auto keywords, respectively. Even Python has typing features by now.
In the opposite direction, the second rule of thumb is:
2. Modern languages have taken down all the really nasty stuff by designThat’s why we don’t see macros anymore or goto statements or explicit memory management. Java had quite some bad press for its GC back in the day, but GCs have outgrown the JVM to pretty much all modern languages.
A recent removal is the null pointer exception. Modern languages like Kotlin and Swift enforce null checking by design. C# 8 is following a similar route. Raw threading and async callbacks have also had their share of problems. Now, we code asynchronous tasks with handy async/await constructs.
All this brings us to the following:
If you want to be a better coder, learn about programming language historyWhile most languages were born out of individuals with an excellent sense of tooling, their developments are led by committees. Whenever new features are added, there is an entire body of work dedicated to discussing their relevance and worth to the community, as well as to perfect its design. The same goes for changing and removing features. Python 3 brought many breaking changes that were hard to ignore, but it all paid off.
Write Bad Code More OftenAll we use is the product of decades of innovations and failed designs.
You can only truly grasp the beauty of a garbage collected language if you dive on some nasty C/C++ code. Until then, all you can do is imagine how painful it was back in the day. The whole hate over singletons can only really be understood by those that got to write one and faced the many issues associated with them (such as writing tests).
Theres a whole world between textbook samples and real-life experience. The former is no more than a hint; the latter really changes how you code.
Most of us, back in our beginner days, coded without Git or Unit Tests. These projects tended to be buggy, and, more often than not, they would stop working at all. Without Git, you couldn’t tell what you might have accidentally changed. Without tests, things would stop working days before you bumped into them again. This experience is what motivates us to use these tools every day.
To truly understand how to write good code, you must write bad code first.
There a couple of ways you can force yourself to write bad code (or to see ugliness in your current snippets). It all boils down to one thing: try coding some other way. This will either show you how much better your solution is or how stupid it was (“was” because you’ll change it, right?)
Here’s a list of things you can do in your spare time:
- Learn a Parent Language: Kotlin, for instance, is inspired by Scala. Swift, among other things, tries to solve Objective-C issues. C# superseded Java. Learning parent languages teach you how much of “what you have now” was not present back then (and what it solves). It will teach you to appreciate more a lot of things you might otherwise think are crap.
- Learn LISP: This is a weird one for many. LISP has no variables. It is a fully functional programming language (that’s easier than Haskell). You don’t need to be any proficient with it, but try writing some algorithms, such as Fibonacci, quick-sort, or Huffman coding. If you take your time to do so, you will realize how variables are, many times, unnecessary.
- Write a Text Processor in Plain-C: Given a path to a text file, open it, remove all line breaks, and add new breaks after every period (.) character. Then, shuffle each word keeping the first and last characters unchanged. Bonus points if you process each line in parallel. This will (quickly) show you how string processing has evolved dramatically.
- Look for Design Patterns: Take a list of design patterns, such as this one（https://sourcemaking.com/design_patterns）, and open up some project you work or worked on. Take your time to read about each pattern and try finding places that could benefit from one of such patterns. For each one you see, try picturing how much cleaner it would be if you had used it (bonus points if you refactor it). This is the best way to incorporate design patterns into your repertoire.
Besides, I am not telling you what’s wrong or what is right, nor how to code. Instead, I invite you to…code. Code in a new language. Try doing the same thing in two different ways. Coding is the way to be a better coder. Not reading some random blog posts on the internet.
Thanks for reading!