Its Not About Discipline

I have often heard programmers describe the discipline that is required to write robust software. My point of view is that if discipline is required, the framework in which you are working is wrong. Now, I'm not saying that there's anything wrong with being a disciplined person - far from it. What I am suggesting is, discipline implies repetition and repetition of any sort is a BadThing.

This same argument applies to CopyAndPasteProgramming; it leads to CopyPasteThinking. Humans don't like repetition. They get bored. They stop paying attention. They miss things. They fail to think.

Far better is to arrange things so that no discipline is required. Humans can be relied upon to take the path of least resistance. Discipline is what forces us out of the path of least resistance. But if it's possible, why not just make the path of least resistance the correct one?

This argument may sound trivial, but it runs pretty deep. When working with other people, one has to ensure that the costs of doing "the right thing" (from one's own point of view) are less than the costs of any other obvious approach. The same principle applies in poker. You have to make the other guy want to believe that he can beat you when he can't, or vice versa.

Here is a concrete example. Suppose you were designing a logging system with multiple fixed-format log entries. One way of designing the logging API might be this:

    interface Logger {
        public int registerEntryType(string[] argNames); // returns a logTypeId
        public void log(int format, string[] args);      // takes a logTypeId
    }
This design has the advantage of being very easy to do from the designer's point of view. But it's wide open to abuse. What if the user doesn't register the log type first? What if he passes the wrong number of arguments in args? It takes discipline from the end-user for this design to be used correctly. Consider this alternative design:

    interface LogType {
    }

interface LogEntry { public void setArg(string name, string value); }

interface Logger { public LogType registerEntryType(string[] argNames); public LogEntry createEntry(LogType type); }
This is a lot harder to implement. However, there is very little scope for the end-user to go wrong in using it. Most importantly, the interface is self-documenting; there is only one obvious way of using it. A little bit of extra work up-front pays off handsomely in the long run.

-- DavidKeithTurner


Strong agreement here. One of my sideline tasks at work has been to develop coding standards, but we always get sidetracked on nit-picks by developers who are adamant about some obscure style point. So I have been trying to find/build a C++ code formatter that would allow specification of every format point, and then make it automatically run on module check in, so that all code in the system is in the "standard" format, and every developer, when they check a module out, can get it in their favorite format. That way, nobody can get out of standard, and nobody has to change their coding habits, but we get a One True Format for comparisons. -- PeteHardie

Kind of like indent(1) for CeePlusPlus... there are a bunch of people trying to do similar things. An example: http://www.uvm.edu/~ashawley/c/indent/


Discipline does not imply repetition, but repetition can be a GoodThing

Experience implies repetition; "I have done this before, therefore I am experienced." Increased experience implies increased repetition; "I have done this many times before, therefore I am highly experienced." Experience is valued because it is hoped that efficiency will result.

Discipline, however, does not imply repetition, it merely implies following a prescribed set of steps. Discipline can be used in lieu of experience if the prescribed set of steps are those that would be done by an experienced individual.

Good approaches to follow can be found through experience and passed on through discipline.

The alternative to repetition is to treat everything as unique. In this case, a developer with 25 years of experience is no more likely to be successful than a developer writing his first line of code.

My point is that if the steps have to be prescribed, you have reduced the role of the human being to that of the automaton. No one is denying that experience is valuable, and that idioms and patterns are also valuable. However, repetitive tasks should be avoided at all costs. (See the first story on MyBestProgrammingMoment.) There is a difference between the repetition of prescribed [complex] instructions and the repetition (or at least pattern recognition) of experience. Also, experience can get you into trouble when new idioms emerge: witness the number of C++ programmers who free() objects allocated with new.

I disagree strongly with you on the point that treating everything as unique renders 25 years of experience useless. It doesn't. You'll still recognize patterns you've seen before, and possibly apply solutions you've used before. However, you shouldn't be doing it by rote. It should be a question of, "I have x, y and z in my toolbox. Which is most appropriate for the task at hand?".

The point of experience is to do things in a rote manner. This frees up time and effort for the truly unique things one needs to accomplish. If one has a problem that x, y, or z could solve, just pick one and go on to the next issue. Piddling around trying to determine whether x is slightly better than y or z if all have served adequately in the past is wasted effort. This is the benefit experience brings, the ability to recognize a pattern and provide an adequate solution with a minimal amount of time and effort.

[Discipline may imply repeatedly applying a set of principles, but that is not the same thing as repeatedly creating the same code. Applying best practices, over and over again, is good. Writing the same code, over and over again, is not. In software engineering, discipline is important because our natural tendencies are often at odds with our best practices.]

That's exactly why it's a good idea to manipulate things so that "best practices" align with "natural tendencies". My natural tendency is to grab the stuff I want to use and use it, without reading the documentation too carefully. Therefore, it's a good idea to make the libraries work well with sort of use. In particular, they shouldn't ask me to do more than the bare minimum required to get what I want. That means that APIs which involve "close" or "release" or "dispose" functions fail this design criterion. I contend that it's always possible to design around requirements of this nature.


Quoting King Crimson, "Discipline is never an end in itself, only a means to an end."


"It is a profoundly erroneous truism, repeated by all copy books and by eminent people when they are making speeches, that we should cultivate the habit of thinking of what we are doing. The precise opposite is the case. Civilization advances by extending the number of important operations which we can perform without thinking about them."
-- AlfredNorthWhitehead

But Alfred North Whitehead was not saying that we advance by thinking less and less, ending in a state of complete thoughtlessness. Through our thought and through our discipline, we reduce the amount of thought and discipline required for certain operations, so that we can apply our thought and discipline to new problems, not so we can become slobs.


EditText of this page (last edited August 29, 2011) or FindPage with title or text search