Don’t Expect Things To Work

Matt
News on the Bloc
Published in
6 min readNov 12, 2014

--

They won’t.

Conversations are based on collaboration. If I opened the door to the café in front of us and said to you “go ahead”, you would understand what I am trying to convey. Not because I am being unambiguous or even clear, but because you can take in the salient points of the situation and infer the most likely interpretation. When you succeed at this and enter the café first, I know you understood me. If you had not, I would have added something else. I would have helped you understand.

No such luck with software. Computers do not share in this covenant of collaboration.

In front of that café, I might have been holding the door open, with my face tilted towards the inside of the café. I said “go ahead” while looking at you. All this context helped you understand my words.

No such luck with software. Computers cannot use context to interpret code. There is no interpretation at all. Things have to be exact.

It’s quite natural to transfer our expectations about conversations to the act of coding, but that habit leads to undue optimism.

What’s wrong with optimism while coding? A lot.

Optimism leads to:

  • Disappointment: we expect things to work and they don’t. Things rarely work the first time around!
  • Magical thinking: we waste time on solutions that aren’t anchored in reality. We write code as if the necessary objects were automatically available. We call functions that don’t exist.
  • The streetlight effect: we waste time tweaking things we understand or things we have control over. In other words, we restrict the problem domain to things we understand.

Of course, simply being pessimistic about code isn’t going to make it work. What can we do when things just aren’t working?

Here’s a short guide to staying sane while fighting stubborn computers.

The streetlight effect

Test Your Assumptions

What are you expecting and what makes you think it should work? It can be difficult to pinpoint a problem when the feature you are building is high-level. It helps to break things down and test each assumption one by one. Don’t assume you understand the problem. As James Golick said in a great talk:

If your assumptions were right, you probably would have written the right code in the first place. And then there wouldn’t be a bug.

As an example, if you’re trying to add a button that will delete a comment from the page, you could draw up the following assumption chain:

  1. Is there an event handler on the button?
  2. Is the event handler being called?
  3. Is the event handler triggering a request to the server?
  4. Is the request received by the server?
  5. Is the comment found in the database?
  6. Is the comment being deleted from the database?
  7. Is the browser receiving the response?
  8. Is the response handler being triggered?
  9. Is the response handler removing the comment from the page?

All these questions can be answered with a mix of Chrome’s Developer Tools, a database explorer, and some server-side debugging. If you have no idea how to test one of these assumptions: relish the opportunity and figure it out. Chances are you will be learning something important in the process.

In theory, the assumption chain can be infinitely long. You could add a lot of assumptions to that chain above if you were willing to doubt the instructions at the CPU level. Common sense is your friend.

Still, if answering all these questions feels like a lot of work, make sure to start by testing an easy assumption around the middle of the chain. Then move on to the assumptions below or above depending on what you find. Is the expected response coming back from the server? If so, concentrate your effort on the client side.

Enter Into A Dialog With The Computer

Baking is hard: you have to round up all the ingredients; stir them the right amount in the right order; place them in a baking tray and leave all that in the oven for an hour. Only after an hour and a lot of anxiety do you know whether or not you succeeded.

Coding should not be like baking. Much better to turn coding into a conversation and get feedback every step of the way.

Unfortunately, computers are not good conversationalists. They can barely answer questions. We have to make the best of it and ask a lot of questions.

Write tests for your code and treat them as a dialog with the computer. Does the code run? Does it work? Did we introduce a bug? Run the tests to get answers.

Another way to enter into a dialog is to utilize interactive consoles — also known as REPLs. Most modern programming languages have them (e.g. Python, Ruby, JavaScript, etc). Ask these consoles questions. If you haven’t used reduce in a while, go in the console and try to use it on a simple array. If you’re not sure whether your Rails associations are set up correctly, go into the console and create models and associate them one with the other. Not sure if Angular’s scope contains the right value? Inspect the scope in the JavaScript console and check its content. Invoke your event handlers manually. Always be asking.

To enter into a more advanced dialog, we need to shed light on the various parts of our application. What is a specific process doing right now? How much memory is consumed by this request? Classic Unix tools can help here: ngrep, lsof, strace, ps, or top. Beyond these basics, the appropriate tool will depend on the technology stack.

If an assumption would take too much time to test, try to test the previous and the subsequent assumption in your assumption chain. You could save a lot of time.

A Problem Has A Specific Solution But Multiple Causes

If you are having trouble with a button not displaying on the web page, there will be a specific solution: perhaps the HTML template is in the wrong directory; perhaps some CSS is hiding the button; perhaps the button markup is invalid. The problem can be fixed with a specific action.

Once you’ve found a fix, don’t move on just yet. The button could have been broken for a variety of reasons:

  • The CSS is badly formatted and hard to understand at a glance.
  • The Developers Tools were closed and you did not see the error messages in the console.
  • You are customizing functionality that should be managed by the CSS framework.
  • Syntax highlighting was not enabled in the text editor, which made it harder to understand why the selector was not finding the element.
  • The HTML markup was not indented properly and ended up being invalid, which confused the rendering and invalidated the CSS selector.

Any or all of these causes might have contributed to the problem. You can fix the CSS selector and be on your way, but you might want to spend some time fixing the other causes.

Coding can be hard. It takes a toll to constantly fight quiet uncooperative computers. To alleviate this sentiment, engage computers in conversation. Make them talk: always be asking questions.

When things go awry, list your assumptions and test them one by one. Somewhere in-between two assumptions lies the bug you are looking for.

--

--

Matt
News on the Bloc

I'm a software developer writing mostly about tech and philosophy.