Sunday, June 12, 2011

"Don't trust maxims ... "

A lot of books, articles or teaching materials are full of "Maxims" or "aphorisms". The intention is to strike the reader and convince him with a strong idea. Based, on my own experience, I'll start this article with my own maxim:
"Don't trust Maxims !"
Ok, I ended up with the traditional "don't trust me, I'm a liar". But this contradiction serves my vision: Maxims are most of the time meaningless and of no use unless provided with the right explanations. In fact, my own maxim should be read:
"Don't trust Maxims, understand them !"
 So, this is general thoughts, what is the relation with programming ?

After several years of teaching programming and computer science, I often heard students quoting aphorisms religiously and most of the time completely irrelevantly ! Why, because they haven't read the original sources, nor they tried to understand the true meaning behind.

The most interesting example is the famous:
"Gotos are evil !"
This is one of the famous mantras of the structured programming approach. Are "gotos" really evil ? Probably not, there's a lot of legitimate uses of gotos (basic exception mechanism, loop escaping ... ) So, why should gotos be considered evil ?

Let's us go back to the elder ages of computer, when programming languages were no more than macro-assembly. In that time, the goto instruction were the only way to structure programs. Have you ever read a code with no functions, no procedures, no while loops ? These codes tend to be as cryptic as poem written by a drunk schizophrenic !

You don't even need to go back to the 60's. The first programming language that I learned was BASIC (for zx81 computer), the last time I read a bunch of code I wrote in those day make feel seek ! It was full of indirections, stupid line numbering and intricate gotos, I was unable to understand it !

So, yes, used that way gotos are evil, but this does not mean that you should not use it. This is only a matter of code semantic, take a look at the following examples:

void user_accept()
{
  again:
  printf("confirm with : ");
  if (getchar() != 'y')
      goto again;
}

(Remarque: this code works badly due to the newline read with the input char ... )

This code make sense, this is not a loop, all you want is to read 'y'. So, the goto is not evil in that case. Of course, you should have used a while loop to obtain the same result, but the meaning is the same. On the other hand, the following code is a bad use of goto:

int f(int **p)
{
  if (!(*p))
    goto getsome;
 doit:
  **p = 42;
  goto end;
 getsome:
  *p = malloc(sizeof (int));
  goto doit;
 end:
  return **p;
}

The previous code is just stupid (but anyway, it is inherently stupid) and its use of goto is just misleading. In fact. Of course, we shouldn't have write it this way, this is bad style programming, but it reflects the idea of evil goto: using it in place of functions or procedures (here, we can even do it without, but this how you should read it, jumping to a specific piece of code in order to solve some issue before returning to normal behavior.)

So, returning to our subject, we illustrate a case where a maxim is right but need further refinement. This lead us to my last maxim of today:
"Never restraint yourself for a bad reason, any programming features can be useful."