How to write dirty, rotten, no-good Javascript… and win!
This was the them of a five-minute lightening talk I gave at Coder Camp Hamilton this month. It was about my js13k game I had made and some tips and tricks when you’re optimizing for code size and prototyping. And it started off with a well intentioned cast off of best practices.
Worst Practices
I’m writing this because in the discussion afterward someone had pointed out that they do some of the things I said, “were bad.” And that made them feel bad for doing them! I assured them they shouldn’t feel bad but I’m afraid that assurances are not good enough in these tough times.
One of the worst problems we have as software developers is pointing out when people are wrong (or when we simply disagree with them). I cringe whenever I hear someone use the words, well actually. There is a world of difference between teaching someone something they don’t know than it is to smear their face in the fact that they didn’t know it to begin with. That’s what, well actually, does: it informs the person you’re addressing that you’re more sophisticated and intelligent than they are. That doesn’t help them understand anything.
I didn’t well actually this person! We explained things and had a delightful conversation. I just want to write this to put the thought to word and share it with my fellow programming friends. The following is an incomplete list of, “bad practices” and why you should avoid them.
Unless you are writing a throw-away prototype and just want to get a feel for the interaction!
Global Variables
If you haven’t learned this yet the common wisdom in programming is that global variables are bad. The reasons for it are numerous and old. Many of us simply take this rule-of-thumb for granted.
In the precense of concurrency and assignment it turns out that global variables will cause race conditions, deadlocks, and strange errors. That’s because global variables are a communication channel between loosely connected parts of a program. If not carefully constrained they can lead to strange, difficult to debug behaviors. Many consider them more trouble than they’re worth and hence the maxim, never use global variables!
In my talk I suggest exploiting them. If different parts of your program need to access a single instance of an object then instantiate it once into a global variable and save yourself a few bytes. Remember: when prototyping we’re not optimizing for correctness, maintainability, or speed: we’re optimizing for code size and speed. Combine global variables with assignment and you have the most simple, inelegant communication channel we know. If you need to change some global state in your program: use a global variable!
In practice avoid them.
Mutating Arguments
This is actually a practice that is quite common in C code so I cannot, in good faith, disparage it. However it is often frowned upon in other languages that do not have the same restrictions on argument passing that C has. So we tend to avoid it.
What do I mean? Take the following code:
const foo = bar => {
bar.baz = computeSomething() // oops!
...
}
This is relatively common yet considered by many to be a poor practice. The reason being that by mutating bar
our function might be causing errors in other parts of the program. Remember how assignment is a communication channel? With a global variable it can be somewhat obvious but when you start calling deeply-nested sequences of functions that mutate their arguments the caller has to be aware of their dependencies. If you call the functions in the wrong order we end up with a game of broken telephone and your program might be in an unknown or error state.
Conclusion
I’m sure there are other things I might’ve mentioned in my talk that I missed afterwards and here. The point is: if you’re aware of a “best practice,” and consider it common knowledge… there is bound to be someone present for whom it isn’t common knowledge. Instead of beginnig your next sentence with, “well actually…” or acting like you’re surprised that this might be true: teach. Explain the best practice and the reasoning behind it.