The Four Duties of Coding

"Concision," a noun form of the adjective "concise" makes for a handy one-word summary of what we are seeking in the artifacts we produce from our work as software developers. Lets look at a definition of concise:

giving a lot of information clearly and in a few words; brief but comprehensive.
(from Mac OS X Leopard Dictionary.app)

That sounds great, but what does it really mean, in real-world application to our work?

The "four C's" of coding are all aimed at making your code concise. They are, in priority order:

  1. Correct
  2. Complete
  3. Clear
  4. Compact

The gold standard for code is to meet all four of these simultaneously, but we would not be doing engineering if there were not trade-offs, at least at intermediate points along the way in development if not in the final product.

The First Duty is to write code that is Correct. That can mean meeting a specification for semantics or for performance or for robustness in the face of bad inputs. Of course, the way to achieve Correct code could include a mix of refining the specification where it is ambiguous, negotiating requirements to make them more amenable to implementation, and of course the particulars of the approach and implementation. These same four C's could equally be applied to the specification as to the code that is produced in response to it.

The Second Duty is to write code that is Complete. In a way, this is an extension of the dictum to write Correct code, since if the code is incomplete, it cannot be correct, but the distinction is we should strive to write smaller bits of correct code with higher priority, and fill in and integrate it into a larger whole to achieve completeness as a secondary objective. Well-constructed code should be composable into a larger whole to achieve a well-constructed whole.

The Third Duty is to write code that is Clear. Code is written by one human to tell other humans across space and time what it is intended that a computer should do. Code should be written in a way that respects its nature as a write-once, read-many (and possibly modify-many) artifact. As long as Correctness and Completeness have been achieved, one should strive for code that is as clear as possible within those constraints.

The Fourth Duty is to write code that is Compact. If there are multiple representations that satisfy the first three Duties with equal or nearly equal success, then selecting for the representation that is more Compact will help keep incidental complexity as low as possible. Just as Complete can be thought of as subsumed within Correct, Compact can be thought of as subsumed within Clear, but is called out separately precisely to assert that its priority is strictly lower than overall Clearness. Do not optimize for compactness at the expense of clarity.

1 comment:

Gregor Purdy said...

A couple of folks have asked me where performance fits into this framework. In my view, performance is a
Correctness issue. That is, the effort to be spent on it can scale as appropriate based on what one is trying
to accomplish. For example, if you are doing something fairly simple with small data, even an N^3 algorithm
could be correct from a performance perspective. An N^3 algorithm that is easy to understand (and code
correctly) is superior to a more efficient algorithm that is harder to understand (and code correctly), except
in the case where using the N^3 algorithm gets you into trouble with respect to performance expected vs.