Trevor Magnusson
![]()
This document lists some of the programming philosophies I have developed and learned over the past 21 years. During this time, HYDSYS code has grown from a handful of programs running on a 4.77MHz IBM PC under DOS to the comprehensive Windows system it is today. Along the way it has run on a Fujitsu FACOM mainframe, and a Sun workstation under Unix. In the future we expect elements of the current system to be migrated into published COM objects and possibly converted to / integrated with C++ and/or Java. Further ahead still we cannot see.
Long Haul programming has two aims:
To minimise the impacts of unforeseen changes, or “future-proof” the system
To maximise the ability of "not enough" programmers to maintain and develop "too large and complex" systems
What it's not...
"Walkaway" projects. "Chaos, panic, disorder - my work here is done" - if you only do short-term contracts, and you'll never have anything to do with the code you write after you've finished, then you might not need long haul programming.
"Trade show" programming. Ever been to trade shows / product launches / vendor conferences where the presenters
demonstrate the latest RAD tool, and it sounds something like this:
"I'll just open a new form here... drop a data component on it here... now excuse me, I've got to type a line of code here, sorry about that, I'll get the team to look into it, so we won't have to next time... now I'll drag this connection here... the server's running on this laptop for the demo, but it could be running in another city, and I'd just have to change the protocol setting to http... now I'll run it, and... voila - three-tiered application!" |
"IDE-time" binding. Using the "object inspector" to store database connection information, or having it hard-wired in code - in long haul programming, everything's GOT to be in a configuration file of some sort.
When it's needed
Long haul has some costs and may not always be required. However, the more of the following criteria apply to the project, the greater the need for a long haul philosophy:
Your product is large, complex and has (or is expected to have) significant longevity.
You have (or aim to have) lots of clients, each with different corporate policies and requirements.
You have an ongoing relationship with your clients (ie annual licence fees, maintenance/support contracts).
Your clients have invested heavily integrating your product into their business/procedures, (possibly via methods such as scripting, customisation etc.) forcing you to evaluate each new change in terms of its impact on these customers.
Long haul programming and SDLC
Long haul programmers sometimes find themselves at odds with managers familiar with SDLC methodologies. Projects of the sort that require long haul programming do not fall within traditional SDLC pigeon-holes:
They have a lifetime measured in decades
Over their lifetime they evolve slowly and in small increments, following a process of continuous improvement
At each point in their evolution they remain fully functional, marketable and deliverable
The individual enhancements are the points at which we must apply SLDC methodologies
Those atomic elements of evolution are large in number, varying in size and scope, and there are often several occurring simultaneously.
Remote control
Modifying a user's configuration file is much better than having to recompile an app and send it down the line.
Using a data dictionary / schema can allow things to be changed at the user's site without needing to send a new app.
Funnelling
Funnelling is a technique for minimising the workload when changes need to be made.
Use const constants instead of literals;
Use over-typing (eg treal instead of double);
If you have any duplication of a few lines of code, consider putting it in a routine;
If you are using anything non-standard, funnel it so that if you need to change it in the future, you only have to do it in one place, and everything will work fine.
Comments in code
Once of the most common criticisms of programmers is that they do not write enough comments in code. A "clever" programmer might respond "But this code is simple - anyone can understand it just by looking at the code." An even more clever programmer will realise that this "obviousness" depends on context - it's obvious because you've just been working in that area for a few days.
Pretend that you won't be the one maintaining the code, some complete dolt will have to;
Five years down the track you will greatly appreciated these comments, and will be shown up as a complete dolt if they are not there;
Especially important if you're doing something "clever".
Interface / Implementation disparity
Some programming languages (C/C++ and Delphi) let you specify the full function declaration
in the interface, then down in the implementation you can leave off all the functions' parameters.
DON'T do this. Keep the two declarations as identical as possible.
It's much easier for someone working on the implementation if they can see the full declaration at the top of the function
It minimises assumptions - things are spelt out explicitly
More errors will be picked up at compile time rather than later
Layout
Along with comments, good code layout makes debugging, enhancement and redevelopment easier.
Consistency is more important than legislated taste.
Reliance on third-party tools - "kid in a candy store"
The more your code is tied in with third-party tools or non-standard language features
of the compiler, the harder it will be if you ever need to switch tools or compiler / language.
There is obviously a balance to be struck here.
The third-party may go out of business;
Use funnelling if possible.
Reinventing the wheel
It is inefficient to have lots of programs with the same algorithm, coded slightly differently by different programmers. Don't spend lots of time developing something if it has already been done. Teamwork and communication help here.
Check to see if something like what you need has already been done:
In the library modules - reuse;
As a third-party too - funnel;
If something that is almost what we need is available in the units, consider enhancing and generalising it.
This point seems to fly in the face of the "kid in candy store" point. So a balance needs to be achieved.
Hacking
Complete this sentence: "Nobody loves a ...";
Too clever by half is not clever at all;
If you can do something in two lines or ten, go with the ten;
C++ is a brilliant language for clever hacks, and you can write C++ code in many languages! Don't.
Only break this rule where significant performance is at stake (in crucial tight loops, event handlers etc, and make up for it with comments!)
If a "not very good" programmer can understand your code at a glance, you're doing very well! Remember that something is always obvious when you're in the middle of working on it. Years later, it may be a complete cipher.
The night of the long knives
Kill Kill Kill! (obsolete code).
Obsolete code and old ways of doing things are like a ball and chain.
When a new object or system is developed, go through the entire library and application source, and upgrade instances of the old way.
Although funnelling is a good idea - don't have wrapper around wrapper around wrapper for each new method - that is a short-term shortcut that only makes it more difficult to do the job properly later.
The most rewarding thing a long-haul programmer can do is delete lines of code.
The most rewarding thing a long-haul programmer can do is delete lines of code.
Yes, I'm repeating myself.
Deleting lines of code is even more rewarding that writing some fantastically cool program or module.
Assert your assumptions - "trust no one"
If you assume that certain conditions will be in place when writing code, put in some Assert calls so that if those conditions do not hold, a helpful error message will be displayed. Better yet, minimise the assumptions you make.
When comparing strings, use a case-insensitive comparer, Uppercase them manually, or assert that they are uppercase - don't just blindly assume it.
It is better to write code that has multiple calls to Uppercase and StrTrim all up and down the hierarchy, than to have code that is vulnerable because it assumes that everything will be OK.
Muzik-Smith's law
Tony Muzik-Smith, one of the programming stars of HYDSYS in the 90’s, was once asked by a first-year computer science student what single piece of practical advice he would give to beginner.
If you start something, finish it right away, then go put stuff in the middle:
begin..end, open..close, repeat..until, (), {}, '', create..free, getmem..freemem.
Magnusson's addendum to Muzik-Smith's law
If the language supports it, use resource-protection blocks to ensure the cleanup always occurs, irrespective of exceptions. (In Delphi, this means try..finally. In the Delphi editor, if you type tryf then press ctrl/j, it will generate a try..finally..end template.)
Summary
Long Haul programming minimises the impacts of unforeseen changes.
Long Haul programming can be distilled into two pieces of advice:
Pretend that tomorrow you (personally) will need to convert the entire product to another operating system,
for which none of the current third-party tools are available.
(This has happened three times in the past, and there is no reason to believe it won't happen again.)
Pretend that the person who will be maintaining your code and enhancing it in future, is a complete thickie.
(You don't need to pretend, and it will probably be you.)
Home
Copyright 2005 Trevor Magnusson