Whoever said working hard is a virtue never met a programmer. Yes, ditch diggers who work hard generate longer ditches than those who daydream, and farmers who lean into the plough plant more food than those who stare off into the sky. But programming isn’t the same. There is no linear relationship between sweat on the brow and satisfied users.
Sometimes it helps if programmers pull all-nighters, but more often than not it’s better for programmers to be smart -- and lazy. Coders who ignore those “work hard, stay humble” inspirational wall signs often produce remarkable results, all because they are trying to avoid having to work too hard. The true geniuses find ways to do the absolute minimum by offloading their chores to the computer. After all, getting the computer to do the work is the real job of computer programmers.
Here are 13 techniques and tools that prove the power of lazy programming. The next time the boss tells you it’s time to roll up your sleeves and lean into the console, head to the nap room instead.
Somewhere along the line, smart programmers realized their software would run faster if it didn’t dutifully calculate every single part of an expression. This feature, sometimes referred to as “call by need” or “lazy evaluation,” is now officially part of programming languages like Haskell, F#, and Python 3.0.
The simplest example is the strategy’s use in checking for null pointers. The object
x is checked to be non-null before the calculation routine begins in this statement:
if (x && x.calculation()) then …
Testing the existence of
x prevents crashing. In more elaborate examples, lazy evaluation saves endless amounts of calculation that will be thrown away by looking ahead to see when the computation tree can be pruned. If the quick test is the first one executed, it can save a bazillion cycles later. When the data structures are potentially infinite, as they are in some number-theory examples, then lazy evaluation allows the program to actually finish.
The technique is not only useful for speeding up functional languages such as Haskell. Smart programmers won’t spend hours calculating values if only a few of them are going to be used. They’ll embed lazy switches that trigger the computation only when someone wants to use it. Here, doing the minimum amount of work makes sense.
Why repeat yourself? Anyone who’s programmed for the web knows there’s a lot of repeating yourself to everyone who shows up at your site. Caching is the answer -- and not only for websites. Any code that recomputes the same problem can be sped up by keeping copies of the answer around.
It doesn’t have to be the final answer. Sophisticated caches can keep partial answers for various parts of the problem. If some parts need to be recomputed, they can still tap the cache for the parts that don’t need to be redone. Websites that assemble web pages, for instance, often cache blocks for different parts of the page, then assemble the full pages from the blocks.
Extralazy people may complain that caching is more work for the programmer. After the code for finding the answer is done, it’s time to write another layer that sits on top to keep a cache of the answers. They may be right about this extra layer, but they’re missing the other work that’s being saved. Good caches can save us all of the work of scaling the server farm to handle the extra load. Scaling is often more work than writing some caching code.
Specify everything only once
One of the most important rules I learned about programming is that each constant should be written only once in the code. If the software is spec’d to put a one-inch margin around a page, the value of one should appear only once in the definition of a constant. Then the constant is used everywhere else.
This simple bit of organized laziness pays off down the road. If you want to change the value -- say, by boosting the margin to 1.5 inches -- you need to make only one change to the code.
You can also work in a bit of self-documentation into the name of your constants, giving your margin value a name like MarginSizeInInches. That can save you the trouble of writing a separate comment, and this constant-as-comment will follow the constant throughout the code.
Sure, longer constant names could mean more typing, but then most programming editors offer autocomplete to save you even more.
Frameworks: The ultimate shortcuts
On one project, a suit wanted a new website, so I whipped one up and made the mistake of telling him I was using WordPress. That was no good. One of his buddies down at the golf course told him that WordPress was for blogs and this was going to be brochureware. Was I an idiot?
So he bullied the CFO into allocating $5,000 for a professional website. The results looked great and it functioned very smoothly, as it should because the guts were all WordPress. The company that charged him $5,000 was smart enough not to mention what they used for a foundation.
Some people like custom code for the same reason that some people hike Mount Everest: They like to do it themselves, no matter what the costs. Smart programmers download a good open source framework like WordPress or Drupal and stand on the shoulders of giants. If any new code is written, it’s no more than a few lines.
Breaking a sweat to write your own code is often a big mistake. The open source code for the frameworks is already well-tested by hundreds if not thousands of people. It’s not always ideal, but it’s like starting at the 99-meter line in a 100-meter dash. Furthermore, as you test the code and upload any bug reports or fixes, everyone else’s installation benefits.
Automation: Better than ever
Some C jockeys still love to malloc their own memory and free it when they know it’s done. As they see it, reference counting and garbage collection are for wimps. Of course, there also might be some coal miners who still use a pick axe, just like John Henry.
A good part of programming language development is automation, and the tools have never been better. Memory management, type checking, and parallel processing are being reinvented as automatic tools, replacing all the grungy background work programmers used to do themselves.
Lazy programmers aren’t resisting these tools. They know that for all of their flaws, they’re still better than the average human on an average day. Oh sure, a very clever hacker can spend extra time and produce an insanely fast work of art, but that makes sense only for the inner loops of the most important parts of the system. The rest of us are better churning out average code and letting the automated tools keep us from making some of the worst mistakes.
Devops: Laziness personified
Some people sneer at the script writers who craft the instructions for keeping the code up-to-date and the servers running. What’s so hard about unzipping some files or copying over some directories?
Of course most of the housekeeping isn’t that hard, and most of the common Unix commands are only two characters, but that misses the point. Being lazy and automating the deployment and maintenance ensures it will be done quickly and -- most important -- consistently. The midnight shift will do things exactly like the 8 a.m. team -- and it won’t matter if either had coffee or not.
Automation brings rigor and stability. Sure, the devops team looks fat and lazy when it doesn’t even push a button because the crontab triggers it, but everything runs smoother. There aren’t as many mistakes when the humans are out of the loop.