Next: Mimickry Principle Up: Modularity Principle Previous: Separating Parser from


Breaking Down Composite Functions.

If a function performs two tasks, there should be individual functions to implement the two tasks. This separation will allow calling one of the two parts separately, as well as the benefits described in the parser example.

In essence, TypeCheckExpr and CodeGenExpr help to encapsulate their respective design decisions, while ExprAction encapsulates the decision in how these two components are composed (e.g., how a type checking error is handled).

/*
 * ExprAction has at least two tasks to perform.
 *  Rather than inlining them, separate them.  This
 *  allows using the typechecking and code generating
 *  routines separately, debugging them separately,
 *  and reusing them separately, etc.
 */
SymTabEntry ExprAction(SymTabEntry A, int Op, SymTabEntry B)
  {
  Type restype;

  restype = TypeCheckExpr(Op,A,B);  /* first task */

  if (restype != ErrorType)
    CodeGenExpr(restype,Op,A,B);    /* second task */

  return restype;
  }

Note that in general, a single function is not sufficient to encapsulate a design decision. Usually a set of related functions is required. For example, there must be additional functions for type checking procedure declarations.


William Griswold
Sun Dec 31 18:26:15 PST 1995