Random opinions on software

§    Are two groups working on the same problem?

I would like to debunk preemptively one statement that I often hear go unchallenged in meetings: "We have to pick one way of solving this problem. We cannot afford to divide our efforts with two different approaches." This is often a unsupported assertion that there is only one problem to be solved. If two groups are approaching a problem in substantially different ways, then perhaps they do not see the problem the same way. If they do not see the same problem, then they are not working on the same problem. Compelling one group to drop their approach will not unify efforts. You can only forbid one group of minds from thinking very hard. Instead of arguing about which approach is better, one should uncover the different issues that need to be addressed. Make sure that both groups understand each other, but do not force them to agree and approve. Assume that no one wants to waste time on a bad idea. Consider the possibility of hedging your bets. Competition is supposed to be good for quality. Identify the different priorities of each group and see how they proceed. There's a chance that you'll decide both solutions are needed. Anyway, you'll be ensuring that progress is highly visible, with short iterations, right?

-- 2007

§    Sleep deprivation

I once heard Kent Beck say "Fatigue is the drug of choice in the software industry." Fatigue is a drug that helps people avoid seeing the consequences of what they do. They find it easier to focus on details because they are bothered by the assumptions or implications of their work.

Sleep is evidently necessary to form long, deep connections between neurons. During the day, we create many shallow temporary connections. During sleep, our brains look for larger patterns and reorganize our experience into more coherent forms. Without these simplifications, our experience becomes a confusion of unrelated details. Why would someone want to avoid organizing their perception of the world? Maybe they are afraid of the conclusions. Maybe they don't want to know that they are wasting their time on the wrong problem or following a doomed strategy.

-- 2002

§    Integrated software need not be interdependent

Too often software becomes monolithic, with all components requiring the pre-existence of other components. One excuse could be that integration is more important than maintainability. Maybe we can have both. Perhaps our interfaces are too large, or our components do not separate functionality cleanly.

The most successful story of software integration must be the Internet, where independent development is unavoidable. How was it done? By the simplest of all possible interfaces. All information passes through two-way socket connections with simple protocols defined in public RFC documents. Thus we have FTP, telnet, email (SMTP), SNMP, HTTP, NFS, chat, and even networked games. None depend on specific languages or operating systems. Any piece can be rewritten without affecting the rest. The simplicity of the interface allows easy testing. The thin channel encourages a good separation of functionality.

§    Scientific software should be portable

"I use only one operating system. Why do I need portable software?"

Do you never plan never to upgrade? Software that runs on only one platform is tied to the operating system. Operating systems evolve and will eventually require you to change your API's anyway. Scientific software preserves knowledge and should last longer than one release of an operating system.

§    Definition of a component

First of all, a "component" is a buzzword. A precise definition is probably impossible. Here are some alternatives.

--- 2000

§    Avoid overloaded operators

Overloaded operators just make code harder to read. Complex arithmetic is one obvious exception that should look just like ordinary arithmetic. Most operators have poor analogies with arithmetic. The usual order of operator precedence no longer makes sense. In combination with conversion operators, a single overloaded operation can take minutes to decipher. (What does x+y mean if x and y are not of the same type?) Overloaded brackets and parentheses make objects look like ordinary arrays and global functions, and a casual reader may think they are. Overloaded operators also tend to generate unnecessary copies of their arguments. Instead use methods with names that explain the operation. Verbosity adds little effort to typing but saves much trouble for reading.


§    Avoid Templates

Templates make great sense for containers, but they are often used when a polymorphism would be preferable.

Templates amount to cut and paste duplication of code, albeit by automatic means. Instantiation exposes the fact that you are using the compiler as a wizard to write code.

Decide what properties the class should have (sortable, iterator, indexed, etc) and put appropriate functionality in an abstract base class (interface). Algorithms can manipulate this functionality through the base type. Use the derived type elsewhere.

If you are using a template so that you can use primitive types and classes interchangeably, then your main motivation is probably performance. As usual, sacrifice good style only when poor performance makes it unavoidable.


Return to parent directory.