One of the major tenants of David Allen’s Getting Things Done methodology is the concept of an external trusted system — a system for storing information outside your brain so that it can be retrieved as needed and/or brought to your attention when appropriate. Our brains are often fickle, and we are apt to forget things. Further, by trying to remember them, we spend mental energy trying not to forget them so that, even if we do remember, our productivity is decreased by the stress of trying not to forget. Getting notes, appointments, tasks, and pretty much anything else we need to remember out of our heads and into a reliable external storage and retrieval system enables us to free up our minds to focus on what we really want to accomplish.
I’ve been realizing lately that robust static type and module systems fill a similar role when programming. I have better things to do with my brain cycles than remember the details of functions, what they require, and where they are used.
A module and interface system like OCaml’s makes it easy to refer to the function header — its summary — when I need t recall its usage. Documentation extractors do provide some of this benefit, and languages like Java provide similar benefits with their amenability to static analysis and good support enabling auto-completion and other IDE lookup features. In a static language, however, the type system explicitly delineates the permissible inputs and possible outputs for a function without requiring the programmer to list them manually. Therefore, the documentation just needs to describe behavior and any special requirements beyond those expressible in the type system (and the more expressive the type system, the fewer these requirements are likely to be). Therefore, the information necessary to call a function is retrievable when needed.
The type system also enables the remind-when-appropriate aspect of an external trusted system. If I get something wrong when calling a function, there’s a decent chance the compiler will remind me when I compile the code. If I change a function, I don’t have to worry about remembering where all it was used; the type system will catch a large set of errors next compile cycle.
In the brain-cycle-saving department, a good type system also allows me to protect myself from myself. It gives me the tools when I am designing a module to make it so that it cannot be easily misused.
So type systems, like other external trusted systems, allow me to offload memory and recall tasks from my brain, or my code browser, to the language and compiler. I’m then free to focus on the real problem I’m trying to solve without wasting brain cycles remembering or chasing down function requirements and behavior buried in function implementations.