Tag Archives: writing software

CS101: Four Principles

If nothing else (and I think there is plenty of else), I can look back on all those years of writing code and pick out the main themes and principles, the things that seemed to matter most. That’s what this CS101 series is about: things I think matter most when it comes to designing software.

Lately I’ve been looking into fours, doing things in fours. With that in mind, here’s Four Primary Principles for Programmer:

  1. Learn to learn.
  2. Learn to look stuff up.
  3. Learn to communicate.
  4. Learn your craft.

That’s right; learning your craft is number four! I think the first three are good principles in general. All three are useful skills in life, but I’ve found them to apply particularly to software design. I’m not saying software is unique in this; many professions need constant access to stored knowledge. No one knows all the details, so everyone needs documentation at some point!

Knowing your craft is certainly important—it made it into the top four! But the first two are constant job requirements, and the third is an invaluable skill. All three apply regardless of your craft. Let me explain them in more detail.

Learn to learn. This is a required skill. Programmers constantly learn new things. There are new tools, new languages, new processes, new standards, new client contexts and new technology. This is an evolving field; there’s always something new. I’ve learned as much in this past year as in every one of the 30+ past years I’ve been doing this.

In fact, I advocate teaching yourself one new computer language a year. I don’t make the recommendation to exercise your learning skills, although it does do that. I think learning new programming languages is important to your understanding of what they are and how they work.

It’s like a musician learning many instruments. If it’s about the music, then the tools—the instruments, the programming languages—don’t matter. Which is not to say that becoming a virtuoso on an instrument isn’t a valid choice. But the job pool is limited, so you need to be a true virtuoso.

Each year,  just pick a new language and learn it (the interweb makes that very easy). You have plenty to choose from: Python, Ruby, Scheme, Haskell, Smalltalk, Lisp, Erlang, Prolog, APL, Forth, Eiffel, Perl, Ada,… The list continues, and those are just a few of the slightly to somewhat off-the-mainstream languages! You might be amazed at how many programming languages there actually are.

Learn to look stuff up. Another required (and acquired) skill. No one can know it all, so the key is knowing where to look stuff  up. As I said, we all need the documentation sometimes. That was Scotty’s secret, you know. He had access to Wikipedia!

Seriously, Wikipedia is wonderful for technical research. The quality of Wiki entries is high on technical material (probably because of the many technical people involved in Wiki and in the interweb). And technical material doesn’t have the political freight as does some social material. Genuine error is rare, let alone deliberate disinformation.

The interweb in general was always rich in technical resource. Its origins were technical, so for a long time its content was also heavily technical. But recent searches turn up results with a lot of (a) people already asking your question and (b) people guessing at the answer for group (a). It has become harder to sift out the actual answer.

But it’s usually still there. The interweb remains a great, if noisy, technical resource!

Learn to communicate. This covers tools, such as Word and Excel (or whatever), but also has to do with improving your writing, and possibly speaking, skills. You may need to do documentation for others, or give a presentation, but you’ll find that skill with documentation and analysis tools is also a benefit to you.

This occurs in two ways. First, you can use these tools to explore a problem or at least put it down on paper. Sometimes a diagram or a flowchart or some kind of drawing is very helpful in breaking down and understanding a problem. Second, documenting your work using modern tools for the job is almost pleasant; the result definitely is!

You will want to be familiar with a good authoring tool (such as Word), a good data analysis tool (such as Excel), a good drawing tool (programmers make many diagrams), and maybe a presentation tool (PowerPoint; sorry about all the MS Office references, but they are very good tools) and a database tool (guess what: MS Access).

The world is increasingly electronic, and it is more and more common to communicate by electronic means. You’ll want to be facile (which includes being literate and clear) with email as well as with whatever other tools make sense in your business. Increasingly, communication means the interweb, so you’ll want to be interweb aware if not savvy.

Interesting how the interweb manages to be a part of all three first general principles. Think it’s invaded and permeated our life much?

Learn your craft. Well, duh. Naturally you want to be good at what you do. That includes the background knowledge, such as knowing the programming language, as well as specific knowledge, such as the data scheme of your database. The stronger your background knowledge, the more you can see of a system, the more of that system you understand. The more you can see, the better you are at debugging or making changes.

Background knowledge also tends to transfer from position to position better than specific knowledge. XML, for instance, is used in so many areas of the computer world now that knowing it is a big benefit. Knowing how computers work and communicate on a general level can be extremely helpful in giving you utility in many areas. It gives you a strong foundation on which to build.

Knowing a given language, such as Java, is fairly useful, but can narrow down the field some. And consider that a C programmer, or a C++ programmer, might well have felt like a Java Programmer does today. This, by the way, is why you want to learn new languages! It looks like Java is here to stay, it looks like there are plenty of Java jobs, but eventually the next new thing does come along. Background knowledge (and the ability to learn!) helps with the next new thing.

There’s a lot more to it, of course. Programmers need attention to detail, for example. When it comes to software, you do have to sweat the small stuff. Each bit matters!

CS101: Always Use LT

Here’s a simple tip! I can’t begin to count how many potential code bugs this has eliminated. It takes some getting used to but once you make it automatic it’s a real help in keeping code and your thinking correct. The tip is this: when you write relational expressions, always use less-than, never use greater-than.

Tip: Always write (B < A), not (A > B).

Make Less Not More

Always write your relational expressions to use less-than and so that a true evaluation puts the lesser quantities on the left of the greater quantities. In rare cases a language doesn’t allow the appropriate syntax, but in most cases you can write the less-than version of any expression. This is especially important when testing a value range (for example, between ‘A’ and ‘Z’).

By the way, I admit to assuming the Euro-American left-to-right bias here. In cultures with strong right-to-left orientation, I hope my logic works in mirror reverse.  The  point is to use instinctive mathematical less-to-greater orientation in relational expressions to help avoid logic errors.

The intent is to apply the left-to-right orientation of the number line to relational expressions. On the (Euro-American) number line, values run from lesser on the left to greater on the right. If you pick a number, L, from the line and pick another number, R, to the right of it, the relation (L < R) is always true and (L > R) is always false.

If the expression logic follows number-line logic, the expression logic makes more sense. For example, if we want to test that x is in the [A–Z] range, one way to write the expression is:

(‘A’ <= x) AND (x <= ‘Z’)

The test value, x, visually falls between the ‘A’ and the ‘Z’. In this form, the expression resembles a common mathematical form:

(‘A’ <= x <= ‘Z’).

Most computer languages do not allow the above syntax, but nearly all allow the first one, which comes very close. Compare this to a common alternative, that places the variable first:

(x >= ‘A’) AND (x <= ‘Z’)

In a complex expression, following mathematical number-line logic can make an expression more clear and help highlight logical errors. For example, consider this (which is not at all untypical code):

((‘A’ <= x) AND (x <= ‘Z’)) OR ((‘a’ <= x) AND (x <= ‘z’)) OR
((‘0’ <= x) AND (x <= ‘9’))

And compare it to this:

((x >= ‘A’) AND (x <= ‘Z’)) OR ((x <= ‘a’) AND (x <= ‘z’)) OR
((x >= ‘0’) AND (x <= ‘9’))

I think it’s much easier to use the first one! In fact, did you spot the error in the second version? The first version is much easier to debug, because you know all the arrows point to the left.

Note that this follows the standard looping conventions:

{J=0;  J < N;  next J}
{J=1; J <= N; next J}

It takes a while to train yourself to use less-than strictly, but once you do, your coding skills will be stronger. You may even find yourself going back and “correcting” old code. It will start to look “wrong” to you!

CS101: Clarity Trumps Everything

Clarity is the #1 priority when writing code. Clarity trumps everything else; it’s even more important than the code being correct! One of the biggest wins a serious programmer can offer is writing clear, readable code.

Source code is for the human reader; it’s not written like that for the computer. If it were up to the computer, humans would use the same ones and zeros it does. It would be much more efficient that way. But us (inefficient) humans need ways to write and talk about computer programs. We use many invented languages, computer languages, to do that. And when we write in these languages, it is crucial to be clear.

Clarity is more important than correctness (which is still very important!), because clear code can be fixed if it’s incorrect. Unclear code is harder to work with. It’s harder to find, let alone fix, bugs. Clear code also helps debug as you write; you are more likely to catch your own errors when you write clear code.

Clarity is more important than comments (which are still very important!), because clear code is readable! Part of clarity is using good object names, and that helps the code be self-documenting. On the other hand, writing clear code means writing good comments, so don’t skip commenting just because you think you write very clear code.

To be honest, writing good comments is such a close second, it’s hard not to argue it’s tied for first as being a #1 priority when writing code. It’s a wash as to which mess I’d rather not clean up: clear code with no comments; code with good comments but no clarity. I think it would be easier to add my own comments to the clear code than to clear up the commented code.

Clarity is important, because it enables change. Clear code has a longer life. Unclear code can be difficult (or impossible) to maintain.  I have sometimes found it easier to throw code away and start fresh, than to try to work with “a big ball of mud.” Clear code is maintainable and reusable.

The Lesson for Today

Always think about the next programmer who has to read and understand your code. That programmer is quite possibly you in six months when you have to revisit your code. Except now you’ve forgotten it all and it looks as new to you as to anyone else! Writing clear code benefits you when you revisit it as well as when you write it.

Write code that a human being can read. (Assume a human being that is a programmer who knows the language.  You don’t have to write code for novices.)

Write a Formal Letter

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 was designed to be very readable by humans, and literate programming tools could 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 book 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.

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. I’ve also mentioned the importance of good comments. (I’ll talk about good comments vs bad comments another time.) There are other important ways you write clear code.

The names of your variables go a long way in communicating your intent. The compiler couldn’t care less, but a longer, descriptive name can be a blessing for a human reader. Don’t be afraid to use descriptive variables names. The days of compiler length restrictions are safely behind us, and editing environments help remember and type names for us. Besides, programmers should be good typists, right?

At the same time, don’t go nuts. Verbosely long names can make the code look cluttered and ungainly. You want some degree of streamlining; that’s a part of clarity, too.

The thing about variable names is that you want a naming convention. You want a way of going about the business of variable names that gives you the same name in the same situation. I’ll talk more about that another time, but one example is that my loop indexes are always ix. The i changes to other letters, but the two-letter name ending in x is a standard I use faithfully.

After years of doing this, I sometimes surprise myself by how well variable names match across a project. Sometimes on a large project I’ll start to create a new class and then realize something like it already exists in the project or in a library. If it’s one I made in the last few years, chances are the one I just started looks surprisingly the same. Source code is one place where you want to be predictable. You want some moves to be instinctive.

A more 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;

Just 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!