Why I Write Simple Code

As per Kernighan’s law: “Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.”

Brian Kernighan, the author of the above law, is among the most famous of all computer scientists. He, along with Dennis Ritchie, authored “The C Programming Language”, one of the most well known of all computer programming books. As such, Brian Kernighan’s ideas carry a lot of weight.

Kernighan’s law sounds simple, but it carries a profound truth – that clever code is bad code. When I was a younger programmer, I thought writing clever code was a great idea. I loved writing code that made me appear to be a wizard of coding. Of course, when you write complex code, you realize the first time you try to fix a bug that the code isn’t maintainable. Now, after 20 years of programming, I aim to write simple code – the simpler the better. I want any programmer – today or in a decade – to be able to look at my code and figure it out without any effort. Simple code is maintainable code.

Do you write simple code? Do you hire programmers that write simple code? More importantly, when you hire contractors do they write simple code? Contractors are notorious for writing ‘clever’ code so that you have to keep them onboard long-term to maintain the code they wrote.  For a business, this is a huge – and costly – mistake! Clever code will cost you far more than you think over the lifetime of an application!

 

Slow and Steady Wins the Race

One of my hobbies is game development. I have been tinkering with Unity for several years now; and I’ve also experimented with  Java, Android, C++, and a few other platforms. Unity is, without a doubt, my favorite. The ease of developing 3D games coupled with their outstanding framework makes it an easy platform for developing games. So, when I was asked to help teach a Unity game development class at the high school a few years back, I was excited and gladly took the opportunity. I teach C# scripting to the students every Friday, and it’s great fun.

This last week, I was going over some simple code on creating projectiles and applying the scripts for their movement and destruction. I had started a project a few weeks before, and most of my code was there. However, when I went to continue the project I found that my code was no longer on the computer. Given that the class is only 50 minutes long, this was a real showstopper. I frantically tried to recreate the project I had before and get it to a point where I could continue with my lesson. Unfortunately, circumstances worked against me and my presentation was less than stellar. This experience reinforced two important lessons from computer programming that I will be sharing with the class next week.

First, I have been busy the last few months with my own business and have not been doing as much game development as I would like. This kept me from being on top of my game at class. I made some noob mistakes, and was unable to perform at my peak since my skills were a little rusty from months of under usage. In the tech world today, this is easy to have happen. The world of software development has so many tools, frameworks, languages, and platforms. Developers are increasingly expected to know countless technologies, and it’s almost impossible to be an expert in them all. For example, I have written plenty of Python code over the years, but I still have to pull up my sample code when I need a new script. Why? Because I don’t use python on a daily basis and I quickly get rusty. To stay up-to-date on skills requires constant effort.

Second, rushing to complete something will cause errors. This is as true in software as it is in any other endeavor in life. As I rushed to complete my code by the end of class, I caused more errors. And, in the end, nothing worked the way I wanted. Had I slowed down, I would have been better able to ensure that what I was doing worked the way I wanted.  However, the imposed deadline made me work without paying attention to the details. This happens in real world projects too. Unrealistic deadlines force programmers to pound out code without paying attention to the details. Errors are made, code is left undocumented, test cases are not written. Then, when the code is released, it doesn’t work as desired. Of course, deadlines are a part of the real world. But if we are rushed to meet unrealistic deadlines, we can be certain that the result will be less than desirable.

In the end, this experience shows some very real truths about software development. Much like the story of the tortoise and the hare, we see that slow and steady wins the race. We have to constantly reinforce the skills we want to use, we can’t let them get rusty. And, we need to take our time to ensure that the code we produce meets more than just timelines – it must be developed so that it is solid and stable.

Google Alerts

One of Google’s most under-utilitized tools is Google Alerts (google.com/alerts). This service allows you to receive emails with new results for particular search strings. While this may not seem useful, it is an excellent tool for being notified of information that may appear on the net about you or your business. With the rise of identity theft and the harm that can come from negative posts about you or your business online, it’s imperative to know what information is being posted out there about you. In Google Alerts, you simply enter the searches you want, and Google will notify you of new results. I encourage anyone who wants to keep an eye on their online-footprint to setup searches for all possible variants of their name and let Google do the rest!

Code Warnings

As a developer, I often look at someone else’s code. It may be a coworker, an open source project, or a code snippet on Stack Overflow. No matter the source, I often look at the code and wonder why something was done the way it was. That’s ok – that’s just part of being a developer. But some things make you seriously question the original developer’s technical prowess. For example, I was looking at some code today that was annotated to ignore all warnings. That’s a pretty brave move, as it assumes you know better than the computer does where problems may be. Reality is, you don’t. And when you ignore all warnings, you set yourself up for failure. For example, today I saw a piece of code with countless variables that were all context-specific in Android. When I removed the ‘hide warnings’ annotation, I saw countless warnings about how these variables would cause memory leaks. That’s pretty serious for a long running application, and it negatively impacts the user experience. Certainly some, in fact many, warnings can be safely ignored. But ignoring all warnings is a recipe for disaster.

Cheap Computers

Yesterday, I started up my spare laptop to load an Android Studio project. The laptop I normally use for this project was at the office, and I was sitting at home. I had to upgrade the version of Android Studio first, and then load the project. But, after over an hour, I still had not written a single line of code. On my Mac, I could have upgraded and had the project open and running in under ten minutes – but my old Windows computer is so slow it’s painful.

Consider the company you work for or the projects you work on. What is the cost of using slow hardware to your organization? What about to your productivity on your projects?

Many people look to buy a cheap computer for work and, indeed, a large number of companies do the same. Why spend too much on computers? Here’s why – when you buy a $500 machine instead of a $1,000 machine, you saved $500. However, during the lifetime of that computer – say two years – you will be less productive than on a more powerful computer that doesn’t have you waiting to work. Do the math and you quickly see that the $500 you saved in cheap hardware is dwarfed by the losses to productivity. If a faster computer allows you to work just a marginal 5% faster, that would mean that – during the course of 2 years – you would accomplish an additional 208 hours of work. (40 hours / week * 52 weeks / year * 2 years * 5%) Even at minimum wage, that comes out to over $1,500 dollars of additional work. Some may argue that the work they do doesn’t require a fast computer. That’s fine, buy cheap computers for those tasks. But for me, as a software engineer, the computer is often a limiting factor to my performance. And, I suspect many other fields are the same.

The power of the machines you purchase for your employees has a direct impact on their productivity. You may think you’re saving money with bargain computers, but long-term you’re losing far more in productivity.

Net Neutrality

Many are very unhappy with the notion of repealing Net Neutrality. Shouldn’t the internet be free of corporate interests? Shouldn’t we be able to have access to whatever we want without infringement on our rights by our ISP? But what about the rights of the ISP? Do they not have rights too? In our nation, the first amendment freedoms we enjoy apply to all – business and individual alike. As such, isn’t Net Neutrality an unconstitutional infringement on the rights of the ISP?

Let’s look at some other big issues over the past few years that share similarities with Net Neutrality. First, the case of the baker who did not want to bake a cake for a gay couple. The bakery argued that their religious convictions prevented them from supporting a gay couple in that way but the courts disagreed. This greatly upset Christian groups and other conservatives across the nation. They argued that the business’s first amendment rights were violated by that decision.  How about the revelation that Facebook was curating the news to push down conservative views and increase visibility of liberal views. Of course, liberals thought this was ok – after all, Facebook has a first amendment right under the constitution to engage politically. The arguments for birth control under Obamacare, and Twitter’s removal of conservative voices are more examples where many argued that it was unconstitutional to limit the free speech of businesses on both sides of the political aisle.

So, both the left and the right has agreed in the past that businesses should have first amendment rights. Now, with Net Neutrality, the American people are unhappy that those rights will be extended to internet service providers. But we can’t have it both ways – whether our political views are liberal or conservative – we need to find a consistent voice in determining what (if any) limits exist in the first amendment rights of corporations.

While I personally want my internet to be free from manipulation by my ISP, as a supporter of the first amendment I struggle how to say such a law is constitutional.

Quality & Service

This morning, I woke up to a light dusting of snow outside. I went to sweep the snow from the front steps, and ended up knocking a vertical bar off the hand railing. As the steps are less than 6 months old, this was very disappointing to me. I contacted the contractor and am waiting for a response. I wish I could say that was the only issue I’ve had with another organization’s quality or customer service this month, but I’d be lying. I purchased an annual subscription to an online news site only to find that their computers say my subscription started in March – instead of December – so my annual subscription will be due 3 months after I paid for it. Their support has still not responded to the issue. I contacted a university in Pittsburgh to get information on taking the HSK exam (Chinese language proficiency) and never heard back. A second university I contacted replied within minutes – with two URLs that were both wrong. And, for one more poor customer service issue, I have been unable to get Google to fix a problem with my account for almost two months now. The problem is on their end, it’s documented in numerous places, but all I am ever told is to upgrade to Silver support to have it fixed. I have to pay them more money to fix a problem that is on their end.

These stories are all just from this month. We live in a world where people have become lazy and sloppy. Quality is increasingly difficult to find, and support is often so bad we’d rather not even try. For me, as a software engineer, this is unacceptable. Every line of code I write – whether for my projects or for a customer – is written so that it can be maintained long-term. I take pride in the quality of my code and the applications I develop. I am more than happy to support the applications and code I write because I create a quality product. My code is a reflection of me.

When you’re looking for development resources for your projects, do they feel the same way? Or will you regret your decision this time next year?

Clean Drive

In the early 2000’s, I purchased several Sun Microsystems computers for putting together a home network of Unix machines. Nothing particularly exciting, I had an IPX, an LX, a Sparc5, and a few others. This was my testbed for tinkering around with Unix system administration. These computers were all purchased from eBay. The IPX and LX were both purchased from the same seller. Typically, when you buy computers on eBay you will find that they do not include hard drives. This is to protect any data that may be on those drives from prying eyes. However, the IPX and LX still had their drives in them. I had assumed they were wiped clean, but that was not the case. Both were fully ready production systems complete with the entire company directory and password file intact! Since I did not have the root password, I removed the drive and placed it in my Sparc5. Then, I updated the password file to use my root password. Finally, I removed the drive and put it back in the original machine. Now, I could run the machine with the new admin password. When it was booted back up, I found all kinds of company data – and this was a fortune 500 company too! This was the stuff that could have been sold on the black market for a substantial sum of money. I took the password file and ran it through Jack the Ripper – a common password cracking program – and before long knew the passwords for all the employees on this system. That same procedure was done on both the IPX and the LX. Lesson learned? Protect your hard drives. Absolutely destroy them before you get rid of them. The cost to company that originally owned these machines could have been enormous – they lucked because all I did was tinker with the machine as a curiosity and then wipe the hard drive clean. You may not fare so lucky when you dispose of your hard drive insecurely.

Stored Procedures

Of all the technologies out there today, databases are among the most important. Boring as the idea may be, the storage of data drives the information age. Indeed, databases are as ubiquitious as the webpage itself. Order information from Amazon, posts on Facebook, content from WordPress sites – all stored in databases. Because of this, database management is hugely important – so much so that people work full time jobs in database management.

One of the technologies that databases provide is what’s called a stored procedure. Stored procedures are code that runs on the database to aggregate data, calculate information, perform business logic, etc. Many people love to put all kinds of logic in stored procedures so that they don’t have to rewrite the business login on multiple platforms. And, indeed, they can be useful at times. However, during my career I have grown to despise stored procedures.  Why? While stored procedures give the promise of simplifying logic on your application code, what they also do is increase the complexity of deployment and circumvent source control systems.

Since stored procedures are external to the application code, deploying an app is more complicated than simply placing an application on a user’s computer. Now, you have to first upgrade the database functions and then upgrade the application. No big deal, of course, since applications often require database updates. However, unlike table structure, stored procedures are more likely to change frequently in order to fix or tweak the logic. Thus, you end up with different versions of the stored procedure on different databases. Now, the same application will behave differently when running against a different database. This becomes a support nightmare. Is the issue a software bug, or is it a problem with the stored procedure? This leads directly to the second problem – no source control. Traditional application code is managed by source control systems. Every change is logged, and the history of the project can be observed for the entire lifetime of the project. Stored procedures are code applied directly to the database, and tweaks are often not entered in source control. Thus, you can’t easily revert back to a previous version since you have no record of it. This lack of history means we can’t see what other developers did and you have no idea why something was changed.

In my opinion, stored procedures often become the wild west of software development. For all the value they can bring, what I’ve seen them bring is additional bugs and confusion to the software process. When I work on projects, I will fight against the use of stored procedures unless an incredibly strong argument can be provided for their inclusion.

REST Tools

REST services are everywhere now. Long gone are the days of RPC and other horrible tools for running functions on a remote machine. This is great news for developers as older frameworks were very cumbersome and far less useful than REST services. What makes REST even more important is that they are used along with JSON to enable all kinds of slick functionality on the internet. Indeed, countless web applications and mobile applications now use JSON-based REST services. And just as there are numerous applications using JSON and REST, there are countless ways you can test REST services and create mockup services. But not all tools are created equal – particular for lightweight, simple testing. For example, a colleague recently said he was using Java and JAX-RS to mockup REST services. Certainly you can do that, but the amount of code you need to write and the frameworks required make it anything but simple. What tools do I use for REST testing? I like to use Python and Flask for mocking up REST services. For example, I can create a simple REST service in Python to return the sine of a number with the following snippet of code:

from flask import Flask
from flask import jsonify
import math

app = Flask(__name__)

@app.route('/sin/<num>',methods=['GET'])
def trig_sin(num):
  rad = float(num) * (math.pi / 180)
  sin = math.sin(rad)
  dict = {'input':num,'sin':str(sin)}
  return jsonify(dict);

if __name__ == '__main__':
  app.run(debug=True)

This is a full service, not a mockup. A mockup would be even simpler – just create the route and return the JSON you want. Nothing could be simpler for mocking a service.

For testing services, I use Visual Studio Code and the REST plugin by Huachao Mao. To test the above service, I can enter the snippet below into a file with a .http extension, and the REST plugin will create a button for me to call the service.

###
GET http://127.0.0.1:5000/sin/60 HTTP/1.1

I can create countless test calls as well as supply headers and JSON POST data. Even better, the .http document creates a documentation that is concise, clear to understand for anybody who develops REST services, and can be interacted with to see the output of the service. These two tools are my default choice for any type of REST testing.