Notes on the practice of programming, mostly learned from Bjarne Stroustrup's "Programming 2nd Edition" (2014).
Programming is always about producing useful systems.
As programmers we always prefer to work at the highest feasible level of abstraction. The ideal is to express solutions in as general a way as possible.
In broad terms, when programming we strive for:
- Correctness: the program provides correct solutions and rarely fails unexpectedly
- Maintainability: the code is easy to extend, debug and port to new hardware; withstanding the test of time
- Performance: the program does not require unreasonable amounts of time or energy to perform its task
- On-time delivery: striving for good structure and optimizing for testing and iteration will ultimately speed up development.
We develop programs in four phases:
The development phases are not a linear procedure: they are more like a pyramid where the latter depends on the former. Code problems arise when testing, design problems arise when coding, analysis problems arise when designing. We go back to our previous steps and refine them in order to arrive at a finished program.
Programming is understanding - to solve a problem you must begin by understanding the problem itself.
- Use pen and paper
- Discuss with your friends
- Write down a description of the problem - answer the question "what needs to be solved?" in detail by breaking down the problem into smaller problems
The difference between an experienced programmer and a freshly starting programmer is how they use the tools at their disposal in order to solve the problem.
- Research available facilities that already solve your problems
- Discuss with your friends
- Write down what components the program consists of - which problems they solve and how they fit together
When writing the code itself you must especially focus on the maintainability of your solution. Imagine someone who has never seen your program trying to fix a bug in its code, extending one of the program's components or maybe even replacing a core dependency.
- Be consistent - use the same conventions throughout your code
- Be a minimalist - strive to only add features that are guaranteed to be useful
- Write understandable code - strive to make your code a direct expression of your ideas
- Abstract when possible - strive to create components that solve a general problem
We try to structure our programs so that we can convince ourselves that they are correct, but proving the correctness of a program is extremely complicated.
- Build up a large collection of tests that have proven to be useful for finding bugs in the past
- Never throw away a bug report - but do strip away the unnecessary information and note the real problem
- Remember the program's purpose - focus on testing for errors that hinder the usefulness of the program
- Know what to look for - errors often hide in the boundaries of what we expect: the strange and extreme
Testing is not to be looked down upon. Being an excellent tester means you have the power to teach yourself how to write good code.