Believe it or not, I've been writing code since I was 7 years old. Since I'm 39 on October 4th, that puts me at about 32 years of coding experience. I've put in well over 50,000 hours into writing, debugging and shipping code to customers. For those keeping score, my last shipped project was a little game called "Draw Something." My company was contracted to build that game for OMGPOP based on their design. It took off big time. Who knew?
No bones about it, I'm a master level programmer. You could learn a lot from me.
Sure, when I first started out, I was simply copying BASIC programs from magazines into my family's TRS-80. We all have to start somewhere. I can't really put my finger on exactly why this happened, but I was just fascinated by code. There was something magical and enchanting about making the computer do things just by typing. I still have a fond memory of my father showing me a crappy ASCII man walking across the computer screen. He sat me down and showed me how that worked. From that moment, I was hooked!
It wasn't just making any old thing happen on the computer that got my blood pumping. It was games that really got me excited. I got addicted to games at an early age. And, seeing how they were made was a huge draw. Some kids liked taking toasters apart to see how they worked. I liked taking games apart to see how they worked. I learned a tremendous amount from reverse-engineering code and stripping copy protection from games.
My first computer, the all-powerful TRS-80! OMG, where's the mouse?!
I tinkered with BASIC programs for many years before graduating to Turbo Pascal, x86 Assembly and C / C++. I got my first professional programming job when I was 17 years old. I dropped out of high school, moved out of the house, headed for California and started following my passion of making video games. That's another story altogether. Just suffice it to say, I am a veritable encyclopedia of coding expertise. I'm also a self-taught coder. I've never sat down in a college classroom to learn this stuff.
Today, I'm a master of many languages and technologies. I still lean toward C++ for my game programming needs simply because it's the most performant choice. Although I'm skilled in many languages, frameworks and technologies, I've settled on C, C++, Lua, C#, PHP, Javascript and x86 ASM for my day-to-day work.
It's a rare day when I meet a coder with similar levels of skill. Maybe I just need to get out more. I don't know. But, for whatever reason, there's just not that many coders out there that can match wits with me. Hey, I'm okay with that because it makes finding work that much easier for me.
I know... I know... this all comes across as some kind of douche-baggery. Am I just some douchebag nerd-raging coder that wants a little recognition for his skills? Nah, not in the slightest. I got over those urges years and years ago. What I haven't gotten over is the terrible suck-ass code that's out there. The fact is that your code sucks and it needs to get better!
You read that right. Yes, your code sucks. That's the good news. Admitting it to yourself is the first step to improving as a coder. If you don't want to improve your skills, why are you coding in the first place?! It must be for the money and ladies... right?
I started this blog to impart my coding wisdom to you. My code has sucked in every way possible. Learn from my mistakes and leapfrog your way to better coding habits. Or don't. Hell if I care. Just think of me (and this blog) as your own personal Master Kan. Use it to master your craft.
"When you can snatch the pebble from my hand..."
How Your Code Sucks
Your code sucks is so many ways, it'll take years to list them all. I'll start by listing the top 5 ways that your code sucks. Immediately start avoiding these basic issues and your code will vastly improve. Ignore these suggestions at your peril!
1) Your Function Names Suck
Code is nothing but a collection of functions that do stuff, right? With that basic idea in mind, you'd think that more coders would name their functions sanely. And, by sanely, I mean in a way that other coders can understand without having to reverse engineer the code. In my experience, that's just not the case. All too often, coders take unnecessary shortcuts in naming functions that make their code demonstrably worse.
Let me show you two function name examples and see if you can determine what they do:
- callTMres
- approximation_scale
Give up? Yeah, I thought so. These kinds of function names violate my first rule of writing non-suck-ass code. Name your functions in plain English (or whatever your language is). This goes a long way toward making your code understandable.
Now, consider these names and see if it makes any more sense:
- callMetatableFunction
- get_approximation_scale
Definitely an improvement. You immediately get a sense of what the hell the coder was thinking when they typed that code.
2) Your Variable Names Suck
Once you get into a function, now we're dealing with variables. Code is nothing but a collection of functions that do stuff, right? Well, the "stuff" that it does invariably involves variables. How you name your variables will make or break your code in the eyes of other poor coders tasked with interacting with it.
I shit you not, in one company I worked at, there was a programmer who made a mini-golf game for one of our products. In that game were the most horrific coding practices I've ever seen. I only know this because it was also a buggy piece of shit. So, I got sent in to do some cleanup work on it. To my dismay, all of this coder's variables were named some variant of: x, a, y, j, j1, x2, v1 and z. I couldn't find a single example of a variable name that told me anything about how the functions worked. Thank goodness I'm a master debugger and could reverse engineer the mess.
Rule #2 of writing non-suck-ass code? Name your variables with real words that represent what the variable contains. Prefer "index" to "i" and "Operation" to "o".
This same coder seemed to loathe the idea of constant variables as well. I mean, why use something like MAX_VELOCITY throughout your code when you can just as easily type "41" in each place where the variable was needed. Like I said, it was a nightmare of coding retardation.
Rule #3 of writing non-suck-ass code? If something might EVER change, store it in a variable. Constant variables exist for a reason, use them.
Honestly, you should NEVER use a single letter to name a variable unless it's a coordinate element (x,y,z). Sure, you might save some typing by being concise in your variable names, but your code sucks because of it. Stop doing that!
3) Your Class / Structure Names Suck
Assuming you use some kind of structured programming, you likely create classes and/or structures to hold your data. Well, similar to points #1 and #2 above, there are many examples of coders naming their structures in an obtuse and difficult to comprehend way. Thankfully, this is a bit less common than some other offenses. But, it's still all too common.
Structures and classes organize your functions and data. They're the conceptual framework that other coders will use to map your code into their brains. Picking appropriate names for these framework pieces is critical to making clean code.
Here's a few examples of bad class / structure names:
- CIwPTVert
- BtLock
- utsname
Seeing a pattern here? Coders taking shortcuts that make for overly abstract solutions that other coders need to make extra effort to understand. There's really no excuse for this kind of sloppiness.
Consider the alternatives:
- PostTransformVertex
- ActiveBTreeLock
- UnixName
Rule #4 of writing non-suck-ass code? Always use descriptive words to label your structures / classes.
4) Your Abstractions Suck
Coders like to think of themselves as clever. And, to be fair, many times they are quite clever. But, this cleverness has a dark side. Many coders suffer from suck-ass abstractions in their code. Clever coders create systems with too many or too few layers of abstraction. It's a tough balance to find but a critical one if you hope to make good code.
Code abstraction comes in two main flavors: classes and functions. Some clever coders get class happy and end up making way too many classes. Other clever coders get function happy and end up making way too many functions. Sometimes they do both. Clever optimization-minded coders will do the opposite and block copy their way to difficult to maintain code.
There's a simple rule of thumb to follow when creating abstractions in your code: If you're block copying something inconsequential in your code more than twice, abstract it.
I remember one engineer I worked with that was working on a virtual machine for a scripting system we used at the company. We were porting some old code to C++. This coder ended up making a class for each opcode in the VM, complete with a virtual function that implemented each opcode's functionality. What a great example of cleverness and over-engineering at its worst. This wasn't some noob coder either. This guy had been in the industry for over 10 years!
Rule #5 of writing non-suck-ass code? Realize you're not as clever as you think you are. Your cleverness makes you suck. Keep a critical eye on when you decide to add an abstraction layer. If it's not necessary, don't do it! Similarly, if you find that you're block copying code then you need more abstraction.
5) Your Optimizations Suck
My final "top 5" entry is near and dear to me. I make video games. As such, performance is important to me (and my users). So many coders just don't understand optimization. As such, their code sucks. It's slow, bloated and creates terrible experiences for the user. There are exceptionally few coders out there that truly understand this problem.
Consider a contract I took last year to help optimize a live MMO that was using the Hero Engine. Users were complaining about bad frame rate issues since beta but the team was too busy to dig into the issues themselves. I spent the better part of three months optimizing various aspects of the engine to improve things. You know what the #1 offender was? An n-squared lighting calculation. During the render process for a frame, the engine would check each piece of visible geometry against each light in the scene to determine how to light things. This is an incredibly naive way of doing things. And it's in an off-the-shelf 3D graphics engine! Rewriting this system gave us a 30% frame rate improvement on average (even higher in some extreme cases).
Some coders say, let's just make it work and worry about optimizations later. I call bullshit on that. You need to be thinking about writing performant code starting from day 1. This doesn't mean that we're hand-tuning each loop in the code to maximize performance. That's stupid. What it does mean is that we spend the time necessary to research the problems we're trying to solve and pick the proper algorithmic solution to them. 90% of the optimziation problems out in the wild could be avoided by proper algorithm selection up-front before typing a line of code.
If it takes you a month to make the right choice, so be it!
Rule #6 for writing non-suck-ass code? Optimize your algorithm choices before writing a line of code!
Chew on these nuggets of wisdom until next time. And make your code less suck-ass!
Finish this sentence for me please :
Premature optimisation is ... (D. Knuth)
Posted by: Coder39 | 09/25/2012 at 03:02 PM
...worse than premature ejaculation?
Honestly, who wants to spend time optimizing prematurely? It's the wise coder that understands that optimization is something to do early and often. Noobs wait until the very end. :)
Posted by: Stephen Nichols | 09/25/2012 at 05:05 PM
Noobs also underquote Knuth and claim that he thinks optimization is best left till later:
"We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3 %. A good programmer will not be lulled into complacency by such reasoning, he will be wise to look carefully at the critical code; but only after that code has been identified. It is often a mistake to make a priori judgments about what parts of a program are really critical, since the universal experience of programmers who have been using measurement tools has been that their intuitive guesses fail."
Posted by: MikeNicolella | 09/25/2012 at 05:23 PM
It's interesting how you put traditional advise upside down.
Posted by: Victor | 12/03/2012 at 07:23 PM