Home of TurboCNC, the best open-source CNC control around...

  You are here:
  Homepage -> Articles -> Software tips
Latest release of TurboCNC is v4.01 build 050312
released March 13

Tips on Software Engineering

  Hardware Software  
Articles HOME FAQ's
  Manuals User
Ordering Contact
  Sitemap Links  

  Writing software is a fairly new art, and as such is pretty disorganized in practice with countless individuals struggling to re-invent wheels and chasing bugs in their code.  Part of this is owed to the rapid progress in the field that obsoletes entire languages faster than books on them can be printed. 

  Here are some working rules and guidelines to make your software projects go more smoothly.  I'm assuming a high level language here like Java, C++ or Pascal, but most of the lessons are applicable to machine level assemblers and state logic as well.


   "Keep it Straightforward, Stupid".  I'm changing this over from "simple" used in other design trades, because for the most part programming does not deal with reducibly complex problems as such.

   Customer requirements change, new developers come in, and code needs to be maintained - perhaps even re-written for the language/platform of the month.  The more straightforward the programming model is, the easier your job will be when these things come up.  Very sophisticated and flexible algorithms are nice, but quite often it's the straightforward, easy to understand ones that carry the day.

   Avoid "trick" programming that relies on the special nature of a problem or a particular compiler.  Examples would be things like adding booleans to integers, taking advantage of little/big endian order, or assuming a particular floating point representation or memory model.

Planning, then framework, then finishing

  I think that if most programmers built houses like they wrote their programs, they would start by building the kitchen completely, including the sink and range, and then proclaim: "Well, the kitchen works!  Now all I have to do is get the rest of the house in order."  Next week I'll start on the Foundation class. Whoops!  Need a door here, hmm.  I'll just modify this code here to cut a hole through these two adjacent rooms. Bang!  Looks like I cut through a light switch - oh well! I'll move that to the other side so it's out of the way.  Actually, I think I'll move all the switches to their own special room until the rest of the house is ready.

   Or maybe they'd build a paper-thin house shaped veil of paint first so it looks good, get the customer's approval, and then decide how the house should fit inside it!

   Go ahead and laugh, but a lot of programming projects are done this way. 

    The way to do it right is similar to homebuilding.  Plan first.  Figure out the basic layout (see the section on function mapping) and make sure it satisfies the requirements, number of users, how much it'll cost to build.

   Then frame it up - just skeleton functions that call each other and go through the motions of the program logic.  Get it to compile, but not really do anything useful yet.  You just want to make sure the logic is sound at this point and fix anything that seems strange while it's still simple to do.  The flow of the program and data structures should be notionally clear.

   Once that's taken care of, start fleshing in the actual code that makes it work.  You'll probably find that this goes much more cleanly than trying to make it up as you go along.

Put flexibility only where you need it

   The more flexible you make a program, the more complicated it becomes and the more development time is required. Know where you need to be flexible, and where you need to code "stiff".

   Excessive abstraction is probably the best example of this, as are gee-whiz things like configurable menus and toolbars, or the all elusive "General Case".  Just like the old saw about implementing the constant PI as a variable in case it changes, only code for change where it is legitimately anticipated, or when it simplifies the implementation.

Watch the kLOC

   kLOC stands for '1000 lines of code' and has become a rough measure of the complexity of a project, as well as programmer productivity. 

   You want to keep the number of lines of code down as much as practical. According to research, a programmer generates about 200 lines of code per day as a long term average.  Bugs generally occur at the rate of 5 per kLOC or so, and the complexity of a program goes up pretty much with the log of the number of lines (assuming that good engineering/coding practices are in place).

   So in general, only code what you need and keep it short.  You'll have to scroll back and forth over it, re-shape it, and debug it dozens or hundreds of times over most likely before your project is done - so the less of it you have to thrash around in the better.

Comments & documentation

   Comments and docs are probably the most overlooked elements in coding.  Under pressure to "just get it working", programmers often forgo them in favor of honing algorithms or just getting more code written.  Ironically, comments often save coding time in the long run.

   Good comments should be descriptive, and are especially important at the function and object level.  A comment should not re-state what the code is doing, which is an especially common mistake in assembly programming.


     MOV AX, $0101     // Put $101 in AX reg

     ADD AX, somevar   // AX=AX+somevar

     MOV somevar, AX   // somevar=AX


//Add $101 to somevar


     MOV AX, $0101   

     ADD AX, somevar  

     MOV somevar, AX

 Better still:

//Update the widget now

//Constant $101 is the size of the widget's record

//Somevar is tracking the location

     MOV AX, $0101   

     ADD AX, somevar  

     MOV somevar, AX

   Make sure you update the comments when you change the code!  Otherwise, no one is going to understand it - maybe not even you.  Similarly, ensure that documentation is accurate and is helpful to someone only moderately familiar with the details of your program.

   Likewise, libraries and special functions should be documented - preferably with a page on your desk or a "white paper" that describes how they work so as to make remembering easier.  This saves alt-Tabbing and searching through code so you can remember what the parameters were for the WidgetOf() function again.

 Know your tools

   Take an hour or two every week to glance through documentation for the tools you use (compilers, editors, profilers, etc..) and learn something new that strikes you.  Quite often you'll find some unused capability there that will help you to be more productive.  

  Understand the limitations of the languages and libraries that you use.  Know them thoroughly enough that you can design your programs without stumbling over a bad assumption and having to write "band-aids" to compensate.

   If you write a lot of code, I suggest getting hold of a good keyboard macro utility that lets you create hotkeys for commonly typed blocks like function definitions, loops, and so on.  I was surprised to find how much easier it is to write software with a few good macros.  A simple block-if declaration in Pascal is about 50 keystrokes for example.  Using a hotkey it types itself in a flash, saving energy for the more important things.  

 Function mapping

   Flowcharting is fairly "old school" nowadays, and isn't terribly useful in most situations.  But function mapping is, and should be done as part of the planning/framing stage of a project.

   Essentially, you sketch on a sheet of paper the function tree for a program, or part thereof.  Just the parameters and the returns, and which functions call which.  Put the lower-level functions toward the bottom.

    Don't worry about drawing boxes, or making it neat.  I like to use whiteboard and markers for initial planning.  Object properties/methods are best listed in one block rather than separately.

  This helps get a few of how a program is going to work, and is invaluable in smoking out ways that you might get painted into a corner later on before moving to the keyboard.

   Also, you may spot places where new functions should be created, or where functions can be combined or eliminated.  Even for a small project of 2000 lines this is often helpful where you might have been tempted to just dive in and go.

If you didn't test it, it probably doesn't work

  This is just a re-statement of Murphy's law.  There doesn't seem to be any such thing as a trivial change, so if you add some functionality and then don't test it, it probably doesn't work.  Make sure the new whizzo-bango code actually does what it should be doing before you send it out.

Keep the users' needs foremost

  It has become almost a dogma in programming circles that anything that saves the time of the programmer should be done.  If it's faster to code something a particular way, then do it that way.  I believe this is wrong - programs should be written for the ease of the users so that their time is saved.

  For example, say that you as a programmer can save 10 hours of your time by programming some feature in a particular way that is awkward, but satisfies the letter of the users' requirements.

  Suppose also that this awkwardness will cost each user about 30 minutes on the average to figure out how this feature works and get the results s/he wants.  For even a modestly successful program that has 1000 users, you can immediately see that the balance hangs in favor of conserving the users' time (500 hrs), not the programmer's (10 hrs).  

  They're paying for it and money is portable, so make it good. 

Peer Review

   Have someone else review your code.  If you don't have a buddy, print it out and look it over carefully a week or two after you wrote it.  You'll be amazed at some of the things you find. 

  This is especially important for library type functions that will be relied upon again and again throughout a project or even a career. 

Don't code when you feel lazy

   I feel that good programming is really more a matter of stamina than of intellect.  Going the extra mile to trap all the possible errors, work through test cases, and grind out the obscure bugs all takes significant mental discipline.  If you're feeling lazy, take a break, go for a walk, whatever. Just don't slog out 500 lines of mediocre code, it's not the right time to do it.

Eat your own dogfood

   This one comes from Joel on Software, who recommends that you use your own applications as much as you can - for the purpose they are designed, to get a feel for what the customer has to go through.  How can you make things easier for them?  Any bugs in there that no one has bothered to complain about yet?

Beta test early and often

   Beta testing is an important part of the development process.  Test early on while things are still malleable so that you can incorporate the suggestions of the users upfront.  This is really what can make a good piece of software into a great one.  Use input from the people who need to use it on a routine basis.

Rules you should unlearn

   These have crept into the programming lexicon somehow, and are parroted by many individuals whom, I'm convinced, don't know what they're talking about really.  The tipoff is the "Never" and the "Always", which is a reliable indicator of inflexible thinking.

  1. Never use GOTO.
  2. Never use global variables.
  3. Never use void functions. 
  4. Never use constants or "magic numbers". 
  5. All functions should be a page long or shorter, and each should be in its own file.
  6. Never use a public object property (object oriented languages).
  7. Language X sucks.  Always code in language Y. 

  Now generally, you do want to avoid GOTOs, global vars, void returns, and mysterious constants in your code.  Long functions can be tedious to work with, and many languages are in fact limited.  These are all complicating factors. 

  But strictly following rules 1..7 can lead you to a gangly, awkward implementation in many real-world problems.  Every situation is a little different.  Work sensibly and logically, using your head.  Take advantage of the tools that are effective for the problems you're solving. 

Good luck with your projects!




2001-2020 DAK Engineering.  

All rights reserved.

This page last updated on January 11, 2015 .