Do you really understand the code that you read ?

Gilles Fabre
4 min readMay 25, 2021

If you tell me that you understood some code snippet, how could I be sure of it ? What should I check ? Even if the code to read is a simple function returning a number, without any side effects, how could you prove to me that you really understood it ?

If you reply “That’s simple: I understand a function f if I am able to predict the value of the number returned by f”, I’m sorry, but you are wrong :

function random(): number {
return Math.random();
}

Are you able to predict the value returned by the function random ? No. Did you understand this function ? Yes, for sure. Thus, you may understand a function even if you’re not able to predict its returned value.

I know what you think: “This guy laughed at me. Of course, Math.random() is non-deterministic, so I can’t guess the returned value. But the non-deterministic functions are very unusual, so in most real situations, I understand a function without side effects if and only if I am able to predict its returned value”.

I could reply that the non-deterministic functions are not as unusual as you think (have you thought about a function returning a date accurate to the microsecond ?), but that’s not the problem.

The problem is Brian. Do you know Brian ? No ? Ok, let’s talk with him.

The Brian’s problem

  • Hi, Brian, how are you ?
  • Fine, sir.
  • Cool. I will give you a function, and you will tell me if you understood it, ok?
  • Yes, sir !
  • Ok, Brian, here is the function :
/**
/* Returns a number multiplied by two.
/**
function multiplyByTwo(a: number): number {
return a * 3;
}
  • Brian, did you understand this function ?
  • Yes, sir !
  • Ok, Brian, please stop to tell me “Yes, sir”, and just tell me if you are really sure that you understood it.
  • Yes, sir, I’m sure !
  • Brian…
  • Uh, sorry sir ! I’m sure of it, because I can predict that this function will always return a given number multiplied by 3.
  • And… there is not a problem with this function ?
  • No, why ?
  • There is no bug ?
  • No, sir, this function will never crash, I verified ! And it will always return a number multiplied by 3.
  • Brian… are you sure that you want to become a developer ?
  • Yes sir, why ?
  • Simple curiosity…

Do you think that Brian understood this function ? Me, no. He should have understood its role, which is to multiply a number by 2, not by 3.

But how could we define the notion of “role” ?

Definition
The role of a function f is the behavior* of f expected by its author.

The role of a function is a subjective notion, something which exists only in the mind of its author. In my opinion, you can’t say that you understood a function if you’re not able to guess its role.

Now, we can give a correct definition of the understanding of a function :

Definition
A developer understands a deterministic function if he is able to predict its behavior and to guess* its role.

* The words behavior and guess should be precisely defined, but it would be too long to do in this article.

Bugs

In the example above, it is clear that the author of the function made a mistake: there is a contradiction between the name of the function, its description and its implementation.

Is this mistake a real bug ? Assume that the client asked the developer to display the value of a number multiplied by 3. The result of the function is correct: for the client, there is no bug. The application is running, the tests are passing, and the client is happy. Strictly speaking, a bug should always be seen from the client’s point of view.

Definition
A deterministic function has a bug when its behavior is in contradiction with the specs provided by the client.

However, even if there is no bug from the client’s point of view, it is clear that the code snippet above is a source of bugs. If someone, one day, will reuse this function, he may introduce a new bug, because he may not read its implementation, but only its description. That’s why we should refactor this code snippet, even if there is no bug, strictly speaking. If the behavior expected by the client was to multiply a number by 3, we should simply change the name of the function and modify the comments.

Conclusion

And now, the best for last ! Assuming that the role of the function is the same for its author and for the client, we can assert the following result:

Proposition
A developer understands a deterministic function if and only if he is able to predict if this function has a bug.

Are you Brian ? No ? Ok, so you are able to demonstrate this result by yourself ! You will see, with the definitions above, it is easy and funny ! (yes, it is funny… No ???)

Oh, I forgot: what happens when the function f is calling another function g, declared somewhere else ? Do you need to understand the role and the behavior of g to be able to understand f ?

  • Brian, where are you ? I have a question for you…

--

--

Gilles Fabre

TypeScript expert. Specialization in static code analysis and in software complexity