- The way to learn to program well is be seeing, over and over, how real programs can be improved by the application of a few principles of good practice and a little common sense.
- The principles of style are applicable in all languages, including assembly codes.
- It is more important to make the purpose of the code unmistakable than to display virtuosity.
- The problem with obscure code is that debugging and modification become much more difficult, and these are already the hardest aspects of computer programming.
- Don't branch around branches: turn relational tests around if it makes the program easier to understand.
- The trouble is, although any single weakness causes no great harm, the cumulative effect of several confusing statements is code that is simply unintelligible.
- Jumping around unnecessarily in a computer program has proved to be a fruitful source of errors, and usually indicates that the programmer is not entirely in control of the code.
- Writing arithmetic expressions and conditional (IF) statements is usually the first aspect of computer programming that is taught. It is important to master these fundamentals before becoming too involved with other language features.
- Most compilers accept non-standard constructions, and standards themselves change with time. Remember, though, that unusual features are rarely portable, and are the least resistant to changes in their environment.
- Don't treat computer output as gospel.
- If you learn to be wary of everyone else's programs, you will be better able to check your own.
- Writing a computer program eventually boils down to writing a sequence of statements in the language at hand. How each of those statements is expressed determines in large measure the intelligibility of the whole; no amount of commenting, formatting, or supplementary documentation can entirely replace well expressed statements. After all, they determine what the program actually does.
- Library functions are one way to reduce the apparent complexity of a program; they help to keep program size manageable, and they let you build on the work of others, instead of starting from scratch each time.
- Code that is excessively clever is at least as hard to understand as code that is too simple-minded.
- Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it?
- The fewer temporary variables in a program, the less chance there is that one will not be properly initialized, or that one will be altered unexpectedly before it is used.
- The harder it is for people to grasp the intent of any given section, the longer it will be before the program becomes operational.
- Trying to outsmart a compiler defeats much of the purpose of using one.
- Repeated patterns of code catch the eye when scanning listings. Since the computer is a tool for handling repetitious operations, we should be alerted by such patterns to look for oversights--why didn't the programmer let the computer do the repeating?
- When abbreviating, always keep first letters, favor "pronounceable" forms, and above all be consistent.
- Similar identifiers are dangerous in general.
- Try to choose names that differ widely; typos and misspellings are less likely to be disguised. Of course, choose names that mean something as well, so the intent of the code is clearer.
- One of the most productive ways to make a program easier to understand is to reduce the degree of interdependence between statements, so that each part can be studied and understood in relative isolation.
- Zero is zero, so adding more digits won't make it more precise.
- A useful way to decide if some piece of code is clear or not is the "telephone test." If someone could understand your code when read aloud over the telephone, it's clear enough. If not, then it needs rewriting.
- Judicious use of De Morgan's rules often improves the readability of programs by simplifying logical expressions.
- Programs are not used once and discarded, nor are they run forever without change. They evolve.
- If you find your code branching around branches or around single statements, turn relational tests around.
- Be sufficiently general that your routine can be used in future applications and by other people.
- Make sure conditional tests read clearly.
- As much as possible, a program should be written so the control flow structures lead the reader quickly and directly to an understanding of what the program does.
- A useful way to write a complex program in any language is to code it first in a convenient, expressive pseudo-language and then, when it appears correct, to translate it into the language at hand.
- Not only is the pseudo-code readable and precise, but it is sufficiently close to normal programming languages that we can apply principles of programming style to it just as if it were executable.
- When a program is well-structured, its layout can be made clean.
- Indentation is no substitute for organization; tasteful formatting and top-to-bottom flow is no guarantee that the code cannot be improved.
- No amount of commenting can rescue bad code.
- If it [your code] does take too much time, and you have measurements that prove it, then and only then should you re-write it.
- Choosing a better data structure is often an art, which we cannot teach.
- Excessive use of labels (statement numbers) and GOTO's is often the hallmark of undisciplined design, a sign that a program is out of control.
- No program is ever perfect; there is always room for improvement.
- "Optimizing" too early in the life of a program can kill its chances for growth.
- Combining too many functions in one module is a sure way to limit its usefulness, while at the same time making it more complex and harder to maintain.
- One good test of the worth of a module, in fact, is how good a job it does of hiding some aspect of the problem from the rest of the code.
- The fact that a four line comment is needed to explain what is going on should be reason enough to rewrite the code.
- A powerful tool for reducing apparent complexity is recursion.
- In a recursive procedure, the method of solution is defined in terms of itself.
- Learning to think recursively takes some effort, but it is repaid with smaller and simpler programs.
- A module should hide from its fellows the details of how it performs its task, for otherwise one module cannot be changed independently of others.
- Never trust any data.
- A good program tests its input for validity and, in critical cases, for plausibility.
- Computers count better than people; let them do the work.
- It's much better to have all input and output in one place than scattered randomly throughout a large program.
- Input/output is the interface between a program and its environment.
- Two rules govern all I/O programming: NEVER TRUST ANY DATA, and REMEMBER THE USER. This requires that a program be as foolproof as is reasonably possible, so that it behaves intelligently even when used incorrectly, and that it be easy to use correctly.
- Worrying about the "cost" of using a debugging compiler is false economy. Your time is worth more than the small amount of machine time involved.
- Where one bug is found there may be an infestation.
- Another way to head off potential disasters is to "program defensively." Anticipate that in spite of good intentions and careful checking, things will sometimes go awry, and take some steps to catch errors before they propagate too far.
- One of the first lessons that must be learned about floating point numbers is that tests for exact equality between two computed floating point numbers are almost certain to fail.
- Floating point computations should be used cautiously when controlling an algorithm. They should seldom be used for counting, nor should two computed floating point values be compared only for equality.
- Machines have become increasingly cheap compared to people; any discussion of computer efficiency that fails to take this into account is shortsighted.
- "Efficiency" involves the reduction of overall cost--not just machine time over the life of the program, but also time spent by the programmer and by the users of the program.
- If a program doesn't work, it doesn't matter how fast it runs.
- Sometimes a preoccupation with minutiae lets obvious things slip by unnoticed.
- A faster-running program is often the by-product of clear, straightforward code.
- Fundamental improvements in performance are most often made by algorithm changes, not by tuning.
- Time spent selecting a good algorithm is certain to pay larger dividends than time spent polishing an implementation of a poor method.
- For any given algorithm, polishing is not likely to significantly improve a fundamentally sound, clean implementation.
- A useful and cheap way to measure how a program spends its time is to count how many times each statement is executed. The resulting set of counts is called the program's "profile."
- "Efficiency" should concentrate on reducing the expensive parts of computing.
- The best documentation for a computer program is a clean structure.
- Flowcharts and program descriptions are of secondary importance; the only reliable documentation of a computer program is the code itself.
- Only by reading the code can the programmer know for sure what the program does.
- Anything that contributes no new information, but merely echoes the code, is superfluous.
- A comment is of zero (or negative) value if it is wrong.
- Comments should help the reader over the difficult spots in a program.
- The physical layout of a program should also assist the reader (whether the original programmer or a later modifier) to understand the logical structure.
- The single most important formatting convention that you can follow is to indent your programs properly, so the indentation conveys the structure of the program to the reader at a glance.
- Good formatting is a part of good programming.
- One of the most effective ways to document a program is simply to describe the data layout in detail.
- The self-discipline of writing it cleanly the first time increases your chances of getting it right and eases the task of fixing it if it is not.
- Most professional programmers spend much of their time changing their own and other people's code.
- Clean code is easier to maintain.
- Principles
- Write clearly--don't be too clever.
- Say what you mean, simply and directly.
- Use library functions.
- Avoid temporary variables.
- Write clearly--don't sacrifice clarity for "efficiency."
- Let the machine do the dirty work.
- Replace repetitive expressions by calls to a common function.
- Parenthesize to avoid ambiguity.
- Choose variable names that won't be confused.
- Avoid unnecessary branches.
- Use the good features of a language; avoid the bad ones.
- Don't use conditional branches as a substitute for a logical expression.
- Use the "telephone test" for readability.
- Use DO-END and indenting to delimit groups of statements.
- Use IF-ELSE to emphasize that only one of two actions is to be performed.
- Use DO and DO-WHILE to emphasize the presence of loops.
- Make your programs read from top to bottom.
- Use IF...ELSE IF...ELSE IF...ELSE... to implement multi-way branches.
- Use the fundamental control flow constructs.constructs.
- Write first in an easy-to-understand pseudo-language; then translate into whatever language you have to use.
- Avoid THEN-IF and null ELSE.
- Avoid ELSE GOTO and ELSE RETURN.
- Follow each decision as closely as possible with its associated action.
- Use data arrays to avoid repetitive control sequences.
- Choose a data representation that makes the program simple.
- Don't stop with your first draft.
- Modularize. Use subroutines.
- Make the coupling between modules visible.
- Each module should do one thing well.
- Make sure every module hides something.
- Let the data structure the program.
- Don't patch bad code--rewrite it.
- Write and test a big program in small pieces.
- Use recursive procedures for recursively-defined data structures.
- Test input for validity and plausibility.
- Make sure input cannot violate the limits of the program.
- Terminate input by end-of-file or marker, not by count.
- Identify bad input; recover if possible.
- Treat end of file conditions in a uniform manner.
- Make input easy to prepare and output self-explanatory.
- Use uniform input formats.
- Make input easy to proofread.
- Use free-form input when possible.
- Use self-identifying input. Allow defaults. Echo both on output.
- Localize input and output in subroutines.
- Make sure all variables are initialized before use.
- Don't stop at one bug.
- Use debugging compilers.
- Initialize constants with DATA statements or INITIAL attributes; initialize variables with executable code.
- Watch out for off-by-one errors.
- Take care to branch the right way on equality.
- Avoid multiple exits from loops.
- Make sure your code "does nothing" gracefully.
- Test programs at their boundary values.
- Program defensively.
- 10.0 times 0.1 is hardly ever 1.0.
- Don't compare floating point numbers just for equality.
- Make it right before you make it faster.
- Keep it right when you make it faster.
- Make it clear before you make it faster.
- Don't sacrifice clarity for small gains in "efficiency."
- Let your compiler do the simple optimizations.
- Don't strain to reuse code; reorganize instead.
- Make sure special cases are truly special.
- Keep it simple to make it faster.
- Don't diddle code to make it faster--find a better algorithm.
- Instrument your programs. Measure before making "efficiency" changes.
- Make sure comments and code agree.
- Don't just echo the code with comments--make every comment count.
- Don't comment bad code--rewrite it.
- Use variable names that mean something.
- Use statement labels that mean something.
- Format a program to help the reader understand it.
- Indent to show the logical structure of a program.
- Document your data layouts.
- Don't over comment.
20170309
"The Elements of Programming Style" by Brian Kernighan & P.J. Plauger
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment