Codecamp 2019: Question everything: The art of reducing bugs by challenging assumptions – Part 2

Part 1 can be found here. Please read that first.

How to write the code

What’s important when writing code, is to reduce the assumptions that people can make regarding our code.

How to write variables

When we write a variable, we need to keep two things in mind: the name, and the scope.

Is it clear what we store in that variable, based on its name?

If the variable type changes (from integer to a string, for example), will the name still be appropiate?

Is it clear, based on the variable name, if it’s a function parameter, a class member, a local, or a global object?

Let’s take two examples.

Let’s see what happens if we add a prefix.

We have globals starting with g, class members starting with m, and locals without any prefix. Isn’t it easier to read now?

Did you know that currentPlaylist (from first example) was a class member, and not a global? Did you know that playingNow was a global, if it wasn’t displayed a bit above that function?

Let’s now talk about the variable scope.

What i mean by that? It means the moment where the variable is added into the context (into the function) and when it is required/used.

Let’s take an example.

Once we read the first three lines, we have them in our minds. We know we need to keep track of them, and see where the values change. But we don’t need to have them in that scope, since after the for loop, we use only the index_to_fire variable. Let’s modify the code and place the variables in their correct scope.

How to write functions

When we write functions, there are a few things we need to consider.

First of all, validating input should exist to all functions that receive parameters.

We need to make sure that the input is correct, and leave the function in case that’s not happening.

After we checked the input and we know it’s ok, we no longer need to worry about them inside the function.

There are a few questions we need to ask ourselves if the input is not valid:

  • Can we continue with the function, or we need to return?
  • If we can’t, is it clear to everyone that calls the function?
  • Is there a return type that can be checked further, by the function that called this function? (eg. bool instead of void)
  • Are we throwing an exception?

Other questions worth mentioning, regarding the input, would be:

  • If we receive an object as input, is it by reference or by pointer? If it’s a pointer, people would assume that the function can continue without that object.
  • Can we modify the data received as parameter, inside the function? If not, can we make them read-only? (const)

Once we finish with the parameter, let’s discuss about what the function is supposed to do.

If the function returns void, we can assume that either one of the parameters will be modified (out parameter – non-const, by reference) or that the state of the object is modified (for class member functions).

If the function doesn’t return void, ideally we should have only one return (single point of return) except for the early-exit for the preconditions.

If the function calls another function, we need to make sure that that call is performed – if there are multiple branches, we either make sure that the response is called in all of them, or we move it outside the branches.

In this case, ideally would be to have a log message that wee can search to be sure that the response was performed.

In the end, we need to handle the output.

We can verify what we’re sending as return type, and log an error message if something is not as expected.

If we return an error, it should be something explicit, not a default error (such as ERROR_UNEXPECTED). This will help us in the future when we’re debugging after such error occurred.

Ideally, we should also have some unit tests that validate pairs of input-output.

Going further, when we call a function, we need to verify the result from that function, and do error handling in case errors or exceptions are thrown.

Let’s see an example.

As an ending for this post, we need to keep in mind to be consistent with the project, and think about what’s not in our code – because what doesn’t exist in the code, will become assumptions for the developers that will read it later on.

You may also like...