2013-02-03

Be neat, and the rest will follow.

When I review someone else's code I occasionally have to harp on about basic things.  Missing Javadoc, superflous code, superflous methods, lack of attention to thread safety, lack of comments documenting intent, or even lack of unit tests.  And some of the programmers that make these mistakes are not people who just graduated -- some of the programmers that make these mistakes are relatively senior software engineers.

The above are what I see as basic skills.  If you cannot produce code that checks the above boxes consistently, you should consider yourself a novice programmer and you must work harder to become a better programmer.  I don't care if you have been programming for 1 year or 50 years.

I'm not going to speculate as to why many programmes habitually skimp on neatness, but I'll offer some observations.

The first, and most obvious observation is that neat code, in my experience, is more often correct.  It has fewer bugs.  Not always, but more often and by a good margin.  When people make an effort to write code that is eminently tidy and understandable to other people, correctness seems to follow.  And where there is correctness and simplicity, consistent speed often follows.

I am not sure if this is because tidy programmers are inherently better programmers or because tidiness makes correctness more attainable.  But they tend to co-occur.

The second observation is that code produced by messy programmers will be treated with distrust.

When we have to deal with code we do not understand we grow wary.  It is extremely uncomfortable to put trust in what you do not understand.  And it is even more scary to alter or to be responsible for changes to code that is hard to grasp.  You do not want to build your system on top of code you do not trust.

Code that is not trusted is replaced.  It doesn't matter if the code is brand new (although sometimes newness can lead to indecision in throwing the code away).  I've seen people spend months of their life writing code which is then discarded because it was more costly to maintain and develop it than to start over.   Or more importantly:  because the code did not provide a foundation on top of which others could build.  I know of no engineering discipline where so much work is simply thrown away on a regular basis.

It breaks my heart that a good proportion of programmers who have just produced code that is thrown away learn nothing from the experience and go on to repeat their mistakes.

Occasionally people will challenge me on the importance of neatness.  They will point out that neatness is not a goal in itself.  That it is the features, the performance, and not least moving projects forward that counts.

In particular the last argument can be hard to argue with.  In particular when combined with lack of experience or lacking ability to extract learning from experience and mixed in with various popular project management philosophies like the focus on "minimum viable product".

Most software projects, if successful, will be long-lived projects.  What you can do in the short term isn't really that interesting.  What is interesting is what you can do long term -- how long you can maintain forceful forward momentum.

It is important to not knowingly make too many mistakes early on that will necessitate doing a lot of work over if your product or project is successful. Try to see it from an external point of view.  How would you feel, as an investor if I showed you something, you invested in it and then I threw it away saying "of course, what you just saw would never work so I am going to throw it away and build something entirely different".  That happens every day in the software industry.  But we don't always admit it.

Software projects have a tendency to stagnate over time.  Complexity grows, faults and design problems accumulate and at some point everything grinds to a halt.  Focusing only on short term results without having a realistic vision of how to maintain developer speed in the long term means you will have to throw more code away earlier or you will have to suffer low productivity.

(To put numbers to the above: in my experience, projects that are messy tend to reach the point where more effort is spent on debugging and keeping the code afloat than on development after 3-4 months.  However, killing off these projects can sometimes take years, depending on the size of the project owner's cojones)

Neatness may not be a goal in itself, but it is what is called a "keystone habit": habit that has a ripple-effect on everything around it.  It is a prerequisite for writing good code.  If you can't even produce neat code, it is highly doubtful that you are capable of paying much attention to more glamorous things like algorithm design, optimization etc.

4 comments:

  1. I agree with the sentiment, but on one area, my experience differs: I react much more to poor javadoc, than to missing javadoc. My personal strategy is to recommend deleting e.g. the typical vacuous getter-javadoc, rather than to waste more time and space. How do you go about teach how to write GOOD comments

    ReplyDelete
    Replies
    1. Hey Johannes, long time no see!

      You are absolutely right in saying that just having Javadoc isn't enough - it has to be good too. I might have been a bit too unclear on that point.

      Some years ago a Youtube engineer implemented a feature for youtube as a kind of joke/experiment. The thing he wrote used text-to-speech and render the comment you were about to post to a sound file and played it to you. The idea being that most youtube comments are worthless drivel and that if people heard a voice read their drivel out loud, they'd be too ashamed to go ahead and post the comment.

      This is a funny story, but I think Javadoc plays that role for API design. If it is hard to write proper Javadoc for the code, the API is probably not brilliant and one should have another go at beating the code into shape. If the API is not brilliant, other people aren't going to understand how to build on the code.

      Sure, there are things you won't bother with, like toString(), getters and setters and all that chaff. Any time you have something with an @Override you are usually let off the hook as well (unless you have been a bad boy and you need to confess your sins for violating some interface contract :))

      Good code has Javadoc and unit tests that are like a mold: if you throw away the code and get someone to reimplement it using only the Javadoc and the unit tests, and it is easy to make it work again, you have succeeded. I'm not saying one should do that, but this is how good the Javadoc and the unit tests need to be for code that is supposed to last.

      Delete
  2. Hmm. Where's your evidence and scientific method? What you say may well be true but you have no science to back it up. You might as well be harping on about a flat earth!

    Do you have an impartial and reproducible tool to determine neatness for example?
    Do others perception of neatness coincide with yours?
    Any emperical statistics to back up your statement?
    Where is the graph of neatness vs "cost" to back up what you are saying?

    You might be right but you have not shown scientifically that you are right. You could be selling snake oil!

    ReplyDelete
    Replies
    1. @Paddy3118: you are right that all of this is relative to my subjective experience. I have never claimed that any of this is backed up by scientifically valid research and data. It is highly unlikely that I will ever bother performing actual experiments to back up these observations and conclusions. I'll leave that to people in academia or people who want to sell books.

      It is entirely possible that my observations are wrong. My data set might be skewed in some way or there may be some observation bias. I consider the above to be a rather conservative conclusion based on personal experiences from 25 years of software development.

      As for objective measures of neatness: I don't think they exist. I'm not even sure they are needed to support my observations because what if my neatness measure is correlated with the positive effects and yours are not?

      And as for a neatness/cost graph....I don't expect it to be that simple but I find it intriguing that you do.

      (And finally, as for snake oil: take a look at the history of what has been written about, for instance, pair programming and how "scientific" the software engineering community was in dealing with it. Then read Feynman's commencement address "Cargo Cult Science" and ponder whether you would be able to tell science from pseudoscience)

      Delete