Thursday, February 11, 2010

The Cardinal Rule of Functions

Functions should be:
  • short
  • easy to understand
  • well-named
  • reusable
  • maintainable
All these desirable properties follow from obeying the Cardinal Rule of Functions.
One Function to a Function
That is, the code implementing a function should have one and only one task to do. Example tasks are:
  • Calculate: using primitive operators, calculate a value; this includes arithmetic, string operations, list building, and so on
  • Read or write: get data from or send data to files or users
  • Parse or format: convert text into structured data or construct text representations of structured data
  • Combine: apply several other functions to a set of arguments
  • Dispatch: decide which of several other functions to apply to a set of arguments
  • Iterate: repeatedly apply another function to a list of argument values
Notice that the latter tasks correspond to classic control structures (composition of function calls, conditional branching, and iteration). A symptom that the rule has been broken is when several of these control structures appear in one function. Another symptom is when you have trouble keeping a function to less than a dozen lines of code, and/or its lines to less than 72 characters.
Another good sign that the rule has been broken is difficulty naming the function clearly, or using names like scan-and-compress-and-print.

Tuesday, February 9, 2010

Names (first in a series)

It's hard to over-emphasize the importance names bring to the maintainability of code. They're the first thing a maintainer sees, and they're often the last thing a novice code thinks about. Textbooks provide notoriously bad examples that students follow in the real code.

If you haven't already, spend some time at Roedy Green's How to write unmaintainable code. Note that the longest essay there is on naming.

Unfortunately, there is no formula for generating names, just some good heuristics, and some major "don't"'s, like names that are
  • cryptic, e.g., bltx

  • vague, e.g., data

  • verbose, e.g., first-item-to-delete

  • misleading, e.g., num for something that holds a
    list of numbers
Good names are:
  • short
  • plain English or conventional
  • accurate
A function name should
  • say what a function returns or does, e.g., get-test,
    never how it does it, e.g., search-recursively
  • be either a verb-object, e.g., get-test, or
    qualified-verb, e.g., string-sort
  • be semantic for application-specific functions, e.g.,
  • be generic for general utilities,
    e.g., reverse-sequence

Much more to come on this topic.

Addendum: Just to reinforce the importance of naming, see
page 5 of Where the Wild Bugs Are.