Software is now considered by many as a scientific instrument, and it has assumed the same importance as “telescopes and test tubes.” This is certainly an opinion I share, and one shared by Aruliah et al. in their paper “Best Practices for Scientific Computing.” I think everyone involved in scientific computing ought to read this paper. As well as giving a summary of best practices for scientific computing, it is a rich source of references in the field of computational practices, with more than 60 references in all.
Scientific software is not yet developed, tested and validated with the same care and attention to detail as physical scientific apparatus, and the authors cite a number of examples of how this has caused serious errors in research results, and has led to corrections in published papers and sometimes retractions of papers.
Ten best practices are given. They are based on many years of experience in teaching, studies of computing and software development, and guidelines from open source and commercial projects. Bear in mind as you read that software should not be written simply to run on computers, but written for humans to read, understand, test and modify.
1. Write programs for people, not computers.
- .. a program should not require its readers to hold more than a handful of facts in memory at once (1.1).
- Names should be consistent, distinctive, and meaningful (1.2
- Code style and formatting should be consistent (1.3)code style and formatting should be consistent (1.3)
- All aspects of software development should be broken down into tasks roughly an hour long (1.4)
2. Automate repetitive tasks.
- Rely on the computer to repeat tasks (2.1) rely on the computer to repeat tasks (2.1)
- Save recent commands in a file for re-use (2.2)save recent commands in a file for re-use (2.2)
- Use a build tool to automate their scientific workflows (2.3)
3. Use the computer to record history.
- Software tools should be used to track computational work automatically (3.1)
4. Make incremental changes.
- Work in small steps with frequent feedback and course correction (4.1)
5. Use version control.
- Use a version control system (5.1)
- Everything that has been created manually should be put in version control (5.2)
6. Don’t repeat yourself (or others).
- Every piece of data must have a single authoritative representation in the system (6.1).
- Code should be modularized rather than copied and pasted (6.2)
- Re-use code instead of rewriting it (6.3)
7. Plan for mistakes.
- Add assertions to programs to check their operation (7.1).
- Use an off-the-shelf unit testing library (7.2)
- Turn bugs into test cases (7.3)turn bugs into test cases (7.3)
- Use a symbolic debugger (7.4)
8. Optimize software only after it works correctly.
- Use a profiler to identify bottlenecks (8.1).
- Write code in the highest-level language possible (8.2)
9. Document the design and purpose of code rather
than its mechanics.
- Document interfaces and reasons, not implementations (9.1)
- Refactor code instead of explaining how it works (9.2)
- Embed the documentation for a piece of software in that software (9.3)
10. Conduct code reviews.
- Use code review and pair programming when bringing someone new up to speed and when tackling particularly tricky design, coding, and debugging problems (10.1).
- Use an issue tracking tool (10.2)