in reply to $bad_names eq $bad_design

I agree with the premise: but sometimes the problem isn't actually the design: its that you're trying to abstract something too far.

Consider your example:

# if we have an expense account and the amount is too large if (4223 == $acct and $amount >= 100) {
which became
if ( excessive_expense_account($acct,$amount) ) {
If I don't understand the system, then the second form is probably no better than the first. Although the named function is explicit, I still need to look at the definition because I don't know what an excessive_expense_account is. A better name might help (e.g. "expense_account_is_over_limit(...)"): but, as a maintenance programmer, I'd prefer to see:
if ( $acct->is_expense_account && $amount > EXPENSE_LIMIT) {
This contains meaningful names, which helps me to read the code: plus it has detail, which is needed for me to truely grok it. When we abstract out the detail, even to a meaningful name, then we circumvent the human brain's chunking mechanism. We only have a meaningful name: not the detail that enables the brain to see the patterns.

The summary: don't abstract too far. If you have difficulty finding a name, then by all means use this as a flag to re-examine the design. But if the design look good, then consider leaving it alone: don't force details into function names. Polysynthetic identifier names are all very well, but grammar exists for a reason: to aid comprehension.


Replies are listed 'Best First'.
Re: Re: $bad_names eq $bad_design
by rir (Vicar) on Dec 20, 2002 at 22:02 UTC
    I agree with Ovid's premise. Though it is not always true. Sometimes the writer's energy for naming just failed or the naming was just boggled somehow. Additionally Ovid's premise is just not true, if I have well designed code and randomly change the identifiers I would have obfuscated, well-designed code. I agree because The physical medium in which we construct programs is so facile that it behooves us to construct programs whose models reconstruct in our and other minds easily.

    Your point is also sublime. Thanks.

    All of this side steps the issue of domain knowledge. What is an EXPENSE_LIMIT? Is this terminology which is standard to accounting, to accounting programs, an unknown or forgotten computer science snippet or a construct named idiocyncraticly to this program/system? <p> This is also an issue to consider in the pursuit of clarity.

    Update: Struck out text, respelled computor.

      Yes! It side-steps domain knowledge. Lets expand on this point.

      Consider this code:

      if ($a->is_xxx_yyy && $b < PPP_QQQ) { ... }
      An experienced Perl coder would instantly, subconciously, grok the control-flow within it. Part of this understanding relies on convention, so could be subverted, but just look at the amount of information/expectation we have:
      • $a is an object (the -> operator)
      • is_xxx_yyy is a predicate (starts with word "is")
      • is_xxx_yyy has no side effects (because its a predicate)
      • If is_xxx_yyy is false, then $b is irrelevant (&& short-circuits)
      • PPP_QQQ is a constant (upper-case)
      • PPP_QQQ is numeric (the numeric comparison)
      • $b is numeric (ditto)
      • The rhs has a single boundary (the inequality).
      So we'd know that there are 3 paths through the control logic of the if statement, and be able to see how they interact. Bad coders could subvert my expectations (e.g. they could add side-effects to the predicate): but "hard cases make bad law".

      Compare this with an abstracted function call:

      if (xxx_yyy_ppp_qqq($a,$b))
      The perl-brain gleams no information from this. Understanding it relies entirely on the quality of the name of the identifier. And we all know how hard it is to create a really good identifier name.