Using advanced programming languages features

Introduction

In this section, we examine the problem of what advanced features of your programming language should be used, and how there should be used.

The reason for the existence of this section is that we often hear students argue that a particular way of writing code should not be used because it is said to generate incomprehensible code.

While it is true that one should avoid using features that always result in incomprehensible code, we argue that there are many fewer such features that these students might think. The key to the argument lies in the definition of incomprehensible.

Understandability is relative

What does it mean for a piece of code to be incomprehensible, or just purely hard to read? There are two elements to that decision, namely the code itself and the person trying to understand it. There are therefore two possible reasons for the situation, either the code is intrinsically hard to understand, or the person is just not familiar with that particular way of writing.

Problems with the code

If it is the code that is hard to understand, there could be several reasons why. The variable names could be badly chosen, the control structure of the code could be so complicated that it takes a lot of time to analyze (for instance with to many unstructured gotos). These are all reasons that have to do with the person that wrote the code. But are there features of a programming language that by their very nature always result in incomprehensible code? In that case, it would be a good idea not to use those constructs, and to recommend others not to use those constructs.

With few exceptions, we don't believe that there are any language features that are intrinsically hard to understand. Even goto statements are understandable if used carefully.

Problems with the person

If instead it has to do with the person trying to understand the code, it seems that a better idea would be to change the person than the code. For instance, if a feature of the language was used that the person was unfamiliar with, it would be a better idea for the person to look in the reference manual for the definition of the feature and then try to understand the code.

But what if there is a large number of people who are unaware of some particular feature, say for instance setjmp/longjmp in C? In that case, it may seem as though have a similar situation to that of intrinsically difficult language constructs, but we don't believe that is the case. (We used setjmp/longjmp as an example since that seems to be a feature few professional programmers know about.)

Features such as setjmp/longjmp exist to solve specific problems that are difficult to solve otherwise. Avoiding such features doesn't make those problems go away. It just means that they have to be solved without the feature. Since the feature was created specifically to solve the specific problems, that means that the alternative ways of solving the problems are unacceptable. In this case, setjmp/longjmp exist to solve the problem of nonlocal transfer of control in case of errors or other exceptional situations. The alternative to setjmp/longjmp in this case (returning and testing error codes) is much worse.

This issue is related to that of programming idioms.

Smallest common denominator

What students often argue is that one should avoid constructs that many programmers might not know, because otherwise the program would be hard to understand (and hard to maintain) for those programmers.

We cannot accept that argument. The situation today is that a very large number of unskilled people program. Many of them have no formal training at all, neither in computer science, in programming, in languages, in software engineering, or any other discipline related to programming. Using only features of programming languages that are understandable to these unskilled programmers, would mean depriving programming projects of features that exist to make the code reliable, compact, maintainable, and correct.

We are willing to go one step further. Managers that hire unskilled programmers without training them in the shared culture of practitioners of the language in question, are seriously jeopardizing the future of their company. At the very least, programming activities involving these unskilled programmers are likely not to be competitive compared to companies that hire skilled programmers, or train their unskilled ones. In the worst case, the programs that such unskilled programmers produce will be buggy and unmaintainable, resulting in huge cost and loss of revenue.