Tags

, , ,

Think of writing code as you think of writing a formal letter.

When you write a formal letter, you have two goals: you have a message to communicate, and you must follow the protocol of a formal letter. Your message comes through when your writing is clear and good. Following the protocol is a matter of knowing and following some syntax rules.

A message + formal syntax. The result is a document with a context.

Code is the same way. It has a specific message to communicate, and there is a formal syntax the writing must follow.

Following the syntax of the programming language is just one part of the formality of writing code. In a formal letter, every part has meaning. In some contexts (international diplomacy, for example), every sentence, every punctuation mark has meaning. Even the spacing between parts can mean something in some contexts.

So when you write code, think of it as a message you wish to communicate and make your code look clean and readable.

Literate Programming

Literate Programming is a specialized approach to writing code that enables a programmer to write at a more human logical level, somewhat like a story. The source code is designed to be very readable by humans, and literate programming tools can translate the source into both code for the computer and documentation. It’s a huge win when you have the language, tools and practice to use it.

In the meantime we can borrow from the idea of source code as a story that can be read sensibly. A source code file should unfold from top to bottom like a story with a beginning, a middle and an end. The idea is to give the reader a good understanding of the function and purpose as they read.

In particular, you can communicate extra information to the reader in how you arrange your code.

For example, in Java this applies to how your write your class and interface files. Where do you put the constructors? Where do you put the static and instance properties? Where do you put static properties and methods versus the non-static? Where do you put the get and set methods? Is there a specific place for standard methods such as toString, equals, compareTo and hashCode?

The real point is this: the order of things in a code file is important. The order communicates information. If there is no structure in your source code, if the order of things has no meaning, then you lose the chance to communicate to the reader. You lose the chance to give yourself a known environment! Skilled programmers use the ideas behind literate programming and structure their source code to communicate more richly.

This means that once you know a programmer’s structure, you can navigate their code better. You know where things are. You know what they are likely to be named. When code has structure and order, it has a familiar shape.

Clarity, Clarity, Clarity

The order of things is one way you make source code clear. Good comments are a huge part of this. (I’ll talk about good comments vs bad comments another time.) There are other important ways to clear code.

A subtle form of clarity, one that takes experience, has to do with the form of the code. The way the code goes about its business can be opaque or transparent. Source code should be as transparent in its intention as possible. Source code should speak its mind about what it’s doing. There isn’t space here to go into that, but I’m sure I’ll return to the topic often down the road.

Let me end with an example of a very simple form of clarity. It has to do with lining things up in your source code. Compare the two variable lists below:

    protected Logger myLog;
    protected HashMap<String,String> myMappedFields;
    protected HashMap<String,QueryChild> myChildEntityTypes;
    protected String myInstanceId;
    protected WebServiceRequest myRequest;
    protected SAXOnDemandMapping myFieldMap;
    protected SAXOnDemandEntity myCurrentEntity;

Simply aligning the names makes the code easier to read:

    protected Logger                       myLog;
    protected HashMap<String,String>       myMappedFields;
    protected HashMap<String,QueryChild>   myChildEntityTypes;
    protected String                       myInstanceId;
    protected WebServiceRequest            myRequest;
    protected SAXOnDemandMapping           myFieldMap;
    protected SAXOnDemandEntity            myCurrentEntity;

It all boils down to the first rule: Always write source code to be read!