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.