Our WorkAbout UsOur ApproachThe Journal
Contact »
« Back to the journal

Fail Faster | A pragmatic approach to programming


Jerrod Long

on 12/3/2015

As a freshman CS student at Transylvania University, the majority of my time was spent alternating between confusion and trepidation. I felt confusion over new concepts like floating points, arrays, and linked lists, and trepidation of Linux and adjusting to college life. However, one fear stood out above all others: compiler errors.

For reasons unknown to me, compiler errors felt worse than correctly compiled code that did not function as expected. They made me feel so wrong. Not only did my program not perform its intended task, it did not even run. If the code compiled and ran you at least got the satisfaction that it did something. (Often, psychologically, I needed that something.) This sub-conscious bias shaped the way I coded for a long time, it was not a good thing. Had my bias against perceived failure not been as strong, perhaps I could have avoided some pitfalls and not written as much bad code.

Fear of Failure = Bad Programming Practice

Many of the early C++ programs I wrote were designed to help us as students better understand the concepts we were covering in class. I spent many hours manipulating data: sorting, converting between data types, and running calculations.

At the time it seemed like busy work but it should have taught me a valuable lesson. Instead of concerning myself with building something cool, I should have better internalized the differences between a char, unsigned char, and signed char to the program.

It made so much sense as a human: a ‘3′ as a char is just another character, a ‘3′ as a signed / unsigned char, or integer, is a number that can be mathematically manipulated. While this example may be a bit opaque to non-developers, the critical point is you have to have an understanding of what you think the program is doing and, more importantly, what the program thinks it is going on.

One assignment gave me massive problems. The program was supposed to read input from a file that contained mixed input of chars and signed / unsigned chars, determine the type of data each line was based on context, concatenate the chars into a single string, perform a set of math equations on the integers, and write the output to a new file. The specification was well defined and feeling confident I understood how to proceed I began coding. I badly neglected understanding what the program understood to be happening. In the end, a correctly functioning program was achieved, albeit in a poorly executed manner.

The final product was one huge (around 100 lines of code was unprecedented for me at the time) function. Consisting of one loop with many conditional statements my program was a great example of bad programming practices. My code was difficult to extend, hard to understand, non-performant and tightly coupled. Basically, it was the programming equivalent of trial and error.

Each error I encountered lead to another conditional to handle that particular problem. The program was trying to tell me it did not know what I wanted it to do, I just was not listening. The program did not know how to add or subtract the character ‘j’ to the integer ‘3′ or concatenate the integers ‘5′ and ‘3′? What I perceived as incorrectness or failure was actually just a poor understanding of what the program was doing and what it was trying to tell me. I was asking the program to perform tasks outside its understanding simply because of my bias against failure.

A better solution to this problem would have been multiple functions that each performed a single aspect of the overall functionality. A function to open the input buffer, one to parse the file line by line, one to determine the datatype of that line, one for the integer mathematics, one for character concatenation and a final one to write to the output buffer.

With the approach above the program would have been acutely aware of what I was asking it to do, the input it accepted, and the output I expected it to provide. If the input file would not open, a function received an incorrect datatype, or the output buffer could not be written a simple message could be displayed allowing the problem to quickly be fixed. Which is the exact opposite of my trial and error approach and an entirely better practice.

While this example does not have a practical application it is not difficult to envision how the lessons learned during this assignment (along with many other trials along my programming journey) can lead to better code as a developer and a better experience as a user.

Proper Failure = Better User Experience

Have you ever spent a few minutes filling out a large form, perhaps on an ecommerce site, submitted it thinking all was well, only to have the site reload the page (hopefully with persistent form data) to display errors in your input? Perhaps you did not enter a properly formed email address, or you entered a two digit year when the form was expecting the four digit version.

The majority of us have probably been there and felt this frustration. There are many similarities between this form example and my CS project. My program was unaware of the input it was getting and did not know what to do next until after it had attempted data manipulation. The form is behaving in a similar manner. The form was unaware the email you entered was not formatted correctly until it attempted to save it, at which point the program did not know what to do so it reloaded the page and asked you to correct the issue.

While reloading the form and asking the user to correct the input is better than saving incorrectly formatted data, it is still not ideal. If the form had been aware of the type of input that was expected of the email field, along with proper validation, would have allowed the form to prompt the user prior to submission that something was not right. Clearly, this is better as the program gets the input it expects so it can function properly and the user has a faster more satisfying experience. The user and the program had an equal understanding of what was being asked and therefore how to proceed.

We can all agree that while failure is not an inherently good thing, the fear of failure is no reason not to try. Understanding why you failed, what steps to take to correct it and how to avoid / better handle it in the future will lead to better code, better experience for users, and a better life in general.

Share to

Related Posts

Where Do We Start? The Technical Audit

By: Kim Clark on 3/15/2010

Any solid SEO program should begin with at technical audit of your website.

Read More »
VIA Studio Joins Google Apps Authorized Reseller Program

By:Jason Clark on 3/25/2010

VIA Studio today announced it has become an authorized reseller of the Google Apps suite of communication and collaboration tools. VIA Studio provides setup, integration & support services for businesses and organizations using Google Apps.

Read More »