Code layout

Let us change our traditional attitude
to the construction of programs.
Instead of imagining that our main task is
to instruct a computer what to do,
let us imagine that our main task is to explain to human beings
what we want a computer to do.

— Donald E. Knuth, Literate Programming

Any fool can write code that a computer can understand.
Good programmers write code that humans can understand.

— Martin Fowler,
Refactoring: Improving the Design of Existing Code

Computer programs must be understood by human beings as well as by computers.  This is why the layout of the source code of a program, i.e., the disposition of the code on a sheet of paper or on a computer screen, is so important.  The two main elements of the layout are

The layout of a program should follow the same principles as the layout of any other kind of text (a book, a newpaper article, a blog, etc.).  It is easy to get used to produce a good layout.  With a little practice, the fingers of the programmer, dancing on the keyboard, will do the the right thing, leaving his mind free to take care of more important things.

Table of contents:

A good layout

Here is a sample of a excellent layout. It follows the recommendations of many gurus and experienced programmers:

int func (int n, int v[])
{
   int i = 0;
   while (i < n) {
      if (v[i] != 0)  i = i + 1;
      else {
         for (int j = i + 1; j < n; ++j)  
            v[j-1] = v[j];
         n = n - 1;
      }
   }
   return n;
}

Notice how easy it is to check the matching of { and }. It is also easy to delete a line and to insert a new line, if needed, with the help of a text editor.

The sample code is set in monospaced font (i.e., a font in which all the characters have the same width). This is the ideal font for displaying code. Note how the characters of each line are vertically aligned with the characters of the previous line. Normal fonts (in which each character has a different width) are not good for displaying code, as the following example shows:

int func (int n, int v[])
{
    int i = 0;
    while (i < n) {
        if (v[i] != 0)  i = i + 1;
        else {
            for (int j = i + 1; j < n; ++j)
                v[j-1] = v[j];
            n = n - 1;
        }
    }
    return n;
}

A compact layout

The layout below uses less vertical space than the previous one. It is good for writing programs with pencil on paper (but not so good for making changes with a text editor). Correct indentation is essential in this layout.

int func (int n, int v[]) {
   int i = 0;
   while (i < n) {
      if (v[i] != 0)  i = i + 1;
      else {
         for (int j = i + 1; j < n; ++j)  
            v[j-1] = v[j];
         n = n - 1; }}
   return n; }

A bad layout example

The layout in the following example is very bad:

int func ( int n,int v[] ){
   int i=0;
   while(i < n){
      if (v[i] !=0) i=i +1;
      else
      {
         for(int j=i+1;j<n;++j )  
            v[j-1]=v[j];
         n =n- 1;
      }
   }
   return n;
}

This layout puts spaces in the wrong places and supresses spaces where they are really needed. The spaces in code are as important as the pauses in music! Moreover, the layout is inconsistent: it writes things first in one way and then in another.

Layout tips

When writing code, we should apply the same layout rules as books, newpaper articles, blogs, etc. Hence,

The expression  while(j < n)  has the same unpleasant flavor as  whilej is smaller than n.  Therefore,

There are three notable exceptions to these rules:  write

Moreover, it is usual to supress the spaces before and after the multiplication and division operators.  Hence, write  x*y  and  x/y  instead of  x * y  and  x / y  respectively.

I suggest you put a space between the name of a function and the following left parenthesis, even if this is contrary to traditional mathematical notation.  For example, I suggest you write

function (arg1, arg2)

instead of  function(arg1, arg2),  since the first layout is easier to read than the second.

Exercises

  1. Which of the lines below has a more civilized layout?
    for j ranging from 1 to n, do
    forj ranging from1 to n,do
    
  2. Which of the lines below has a more decent layout?
    for(j=0;j<n;++j){
    for (j = 0; j < n; ++j) {
    
  3. Which of the lines below has a better layout?
    for (j = 0; j < n; ++j) {
    for(j = 0; j < n; ++j) {
    
  4. Which of the lines below has the best layout?
    for (j = 0;j < n; ++j){
    for (j = 0; j < n; ++j) {
    
  5. Rewrite the piece of code below using a good layout.
    int func(int n,int v[]){int i,j;i=0;
    while(i<n){if(v[i]!=0) ++i;
    else{for(j=i+1;j<n;++j)v[j-1]=v[j];
    --n;}}return n;}
    
  6. Rewrite the following line of code using a decent layout. Then, write a simpler version of the line.
    for(i = 23; i --> 0;)
    
  7. Improve the layout of the text below.
    Debugging is twice as hard as writing  the
    code in the first  place.Therefore ,if you
    write the code as cleverly as possible,
    you are,by definition , not smart enough
    to  debug it .
    
  8. Rewrite the following piece of program using a decent layout.
    left= 0; right=N-1;
    i=(left+right)/2;     /*"middle"of r[]*/
    while(left <= right && r[i] != x){
       if(r[i]<x) left = i+1;
       else right = i-1;  /* new "middle"of r[] */
       i= (left + right)/2;
       }
    

Layout tips