In my first semester at grad school
(wow, now 18 years ago... I'm old), all CS master's students were required
to take two intensive “this is what you should have learned during undergrad classes”, CS801 (theory) and CS802
(practice). The latter was taught by Dr. Dan Bergeron, who was
— and probably still is — an excellent teacher, but whom I remember most
as a man of stellar integrity and fairness — a good father-figure that
most collegiate environments lack.
Anyway, while rummaging around some old papers the other day, I found this handout on “coding commandments” from the class. (It
seems that programming in the class was done in Pascal
— ugh.) The commandments are still as relevant today as then (well,
perhaps the last one is more “advice” than
“commandment”, and about some others, I do remember bristling
at some of them, but I no longer remember which.)
I thought some of you might enjoy this, so pass it along...
Coding Commandments CS802 - Fall 1987 October 30, 1987
The programming style conventions listed below shall be followed for
programs submitted in this course. I firmly believe programs that follow
these guidelines are more readable, more comprehensible and more
maintainable than programs that do not follow the conventions. Furthermore,
these conventions are consistent with well-established philosophies that
define what constitutes good software engineering and are not just my
idiosyncrasies (in spite of the fact that lots of existing software does
not follow these guidelines). Finally, I will be the last to claim that
there are no circumstances in which these guidelines should be violated.
(In this course, however, there will be no exceptions!) |
(1) | Every
procedure/function shall have exactly 1 return statement and that
statement will appear at the bottom of the procedure as the last executable
statement of the procedure. | (2) | Every identifier used
in the program shall have an associated comment that describes what the
function of the identifier is. This includes symbolic constants, types,
fields in records, parameters, variables, etc.
| (3) | Every
procedure/function shall be preceded by a clear separator (such as a row of
asterisks or dashes or whatever) with a clear indication of the procedure
name and a brief comment describing the essential function provided by that
function.
| (4) | A long
procedure is a bad procedure. All the code for a procedure should fit on no
more than one page, so that it can be readily comprehended by a reader.
| (5) | Indentation of code is a
very important tool in producing understandable code in which the control
flow is readily discernible. Use good indentation that clearly shows the
control flow. Don't let comments or debugging code obscure the indentation.
Don't indent more than 2-4 blanks per nesting level.
| (6) | Use a
blank line to clearly identify major loop or conditional statements. A brief comment at the end of the line with the statement keyword is also
very helpful if it tells at a high level what the statement does. If you have a loop or conditional that covers more than 8 lines or so, make sure
that the end statement includes a comment that identifies which
statement is being ended. If there are nested statements of the same type,
be sure to include enough information to clearly identify the right one.
(For example, end { while i <> 0 })
| (7) | If you
have an if-then-else statement with 1 short alternative and one long
alternative, arrange the condition so that the short alternative is the
then clause, and the long one is the else.
| (8) | Use
nested else-if in preference to nested then-if.
| (9) | Every
loop should have exactly one exit. Do not use a loop statement if a
while or repeat is what you mean.
| (10) | Use
meaningful variable names.
| (11) | Use
symbolic constants excessively.
| (12) | If
you use arrays, you must always check the index for exceeding the bounds
before trying to access the array element indicated by the index.
| (13) | If
you use lists, use a dummy sentinel, so that no list is ever empty.
Generally, it is also wise to always have a tail pointer for efficiency of
search and addition to the list. For searching, store the key you wish to
search for in the tail (which is the sentinel), so that you are guaranteed
to find it. Finally, if you are bothering to implement a list at all, you
might as well implement two-way lists. The extra overhead of having the
back pointer is insignificant and it makes deletion much easier.
| |