The Tina libraries are written in C. This section has been written with the view
of trying to define some reasonable rules of thumb for efficient use of that language.
It is primarily intended for naive C programmers, but competent programmers may find
some of our opinions `interesting' if they have not explicitly thought about
the way they use the language previously 2.1.
All rules of thumb are expected to have exceptions in specific circumstances
, unless preceeded by ``ALWAYS'' or ``NEVER''.

Serious software
engineers may insist that software must always be formally designed before coding.
However, in the area of algorithm development, the final
form of a piece of software cannot be envisaged until enough research has been done
to define the algorithm. This is an obvious problem for people
new to the research area who will need to try a few things out before
settling on an approach. However, the situation also applies equally where the
research has generated an unexpected result.
At any stage, deciding to redesign and rewrite the software raises the possibility of
introducing new errors, abandoning the effort already expended in debugging.
If we acccept that algorithm testing should ALWAYS drive the deign of software
(not pre-conceptions), this inevitably leads to the need for an approach which
supports rapid incremental modification and puts less emphasis on a-priori design.

The C programming language has some very useful properties
with respect to approaches to software development which require gradual
change. In particular, the language is so flexible that it is generally
possible to identify a continuous development path between any one specification
of function and any other. This flexibility can be directly attributed to
the separation between the sequential form of functions and data structures
(and can be lost once some object oriented approaches are adopted).
This can be used for the purposes of either algorithmic variant evaluation
or general improvement and minimises the time required for subsequent de-bugging
(see Debugging below).
This flexibility supports maximal reuse of existing software and easy integration of
packages.

Anything which adds overhead to the development cyle has to be weighed according
to its utitlity and impact upon research productivity.
It is because of this that conventional software design methodologies
(as found on large scale industrial projects), which use formalised
ways for programmers to contribute towards a software product via a rigid versioning
system, are not necessarily appropriate for research software development.
However, formal design methods and version control of software are not
necessary on research projects provided that you follow some simple rules.
These rules basically involve following common sense programming practice; regular backups
and testing software modifications before inclusion into common libraries (See Appendix A).
It also helps to have some guidelines for good programming practice.

So what constitutes good programming? Well it certainly isn't exploring all of the
various complexities of the language, or minimising the total line count
by embedding several statements within one line. This may be considered
fun but is not particularly productive.
It is our opinion that the main goal of algorithmic reasearch is not the
generation of cleverly defined software, but a more fundamental understanding of how
to extract information from data.
Good programming must result in
software that others can understand, use and potentially modify.
Good programming is well defined by the phrase ``KEEP IT SIMPLE STUPID'', while
at the same time adopting a development methodology which will
ultimately eliminate the maximum number of bugs.
Keeping your software simple is ALWAYS the best method of ensuring others can
understand it. So don't try to be too clever, reserve that for the
algorithms not the software design.