Thursday, March 31, 2011

Simple Rules for Source Code Control.

Only check in one functional change at a time. Then when someone else has to merge the changes, or to undo one of them, or to cut a release, they will not be forced to question your progeny.

Add function overloads after the original function.  Otherwise diff and merge can make an unholy mess of figuring out what changed where. Especially if anything else in the original function changed.

Put in a decent comment in the source code control. Yes someone can look at the files to see what you did, but the poor fool may be merging 6 months of work in one branch with 6 months of work in another. They really don't have time to play detective. You may even end up being that poor fool, and not remember every change that you coded 6 months ago. "Fixed bug 102312" is not an acceptable comment. Do you really want to have to log on to the bug tracking system and chase up each bug by reference number while you sort out an interesting part of a merge.

Don't manually apply the same change to 2 different branches. There is a special place in hell for programmers that do this. Use the Source Code Control System to push your change from one branch to another. Then the SCCS will have a history, and the shared base file will be updated. It may seem like a Royal PITA, but it will not be nearly as much as a PITA as the merge will be if you manually apply the same change to two branches, especially if you have add the functions in different places, or if the formatting is different because when you CUT & PASTE a function, the Environment automagically formats it.

SCCS should be a mandatory class in any degree that has any pretentions to Software Engineering. And one of the keystone projects should involve merging 2 code branches and producing a report of good practices that would make the merge easier. Ideally give each student changes to make to a branch, and randomly pair them and make each student merge to the other branch*.

(*Hey I never said I was a nice person)

Tuesday, March 8, 2011

Let the compiler do the work

If you have data that can be transposed it will surely be.

Look Mizuho, Instead of selling 1 share  at ¥610,000, they sold 610,000 shares at ¥1 each.

A function that takes two parameters CalculateArea(double length, double width) will eventually be called with width and length. In this case, for most geometries that we care about, no harm done.

But what about some process function like :

void AddDilutedAcid(double ml, double PartsPerMillion)?

The following will compile, run, and cause all sorts of problems.

void MixUpDangerousChemical()
     double ml = getVolumeToAdd();
     double ppm = getConcentration();
     AddDilutedAcid(ppm, ml); // Nicely transposed. Should be ml, ppm

It would be nice to find that bug at compile time, not at runtime.

What if we had a simple Concentration class. At it's simplest, it would just contain and expose a double.

 public class Concentration{
     public double ppm {get;set;}

void AddDilutedAcid(double ml, Concentration PartsPerMillion) {...}

void MixUpDangerousChemical()
     double ml = getVolumeToAdd();
     Concentration ppm = getConcentration();
     AddDilutedAcid(ppm, ml); // This throws a compiler error now !!

Let the compiler do the work. It always pay attention. Always.

Thursday, March 3, 2011

I'll Just....

If an electrician came to your house, and offered to save you running new wiring by using the fact that the Aluminium Window frames are pretty conductive....

So why do we do the same thing in software?

"I'll just add this feature in here" translates directly to "Man is this ever gonna be a mess in a few years time".

It's an invariant. The words "I'll Just" almost always precede a short term fix that will eventually pile up with all the other "I'll Just" fixes until the whole thing becomes a tangled mess of surprises.

You look in a function and find that it's also doing something else unrelated. "Ah yes, they wanted to be able to do.... so I just added it here"

There's a name for this one, "accidental coupling", and no, that has nothing to do with being drunk in a nightclub. Things get tied together because they happen together by coincidence.

Of course, later someone wants to do them separately. And in code, surprises are almost* never good things.

The PrintInvoice() function also sets the credit limit. Who'd have thought that? "Well we did that because we usually set the credit limit then..."

It was a wrong thing to do, and any and all justifications don't change that. Great, You've just used the Aluminium window Frame to carry the current to the Outside Lights. Nice.

There is a minimum amount of work that is required to do something right. You cannot avoid that work forever. You can put off that work, but when it comes to tidying up all the shortcuts, you may not like the interest and penalties that build up on all the work you should have done up front.

*Almost Never ~ ok, let's just say Never