One of the joys and challenges of software is that every problem is different. There is no silver bullet, and what works for one situation might be terrible in another. Software engineers and architects must be continually learning which tools are appropriate.
A corollary of this idea is that every decision is a tradeoff. When designing software, the goal is never to make a “perfect” system that does everything; there is no such thing. A system that is good at some things will inevitably have drawbacks. Instead, we need to focus on the needs of the system being built. The goal of any project should be to build the most powerful system for the smallest cost, where “powerful” and “cost” are defined in terms of the needs being met by the system. We need to embrace this reality and learn to predict the consequences of decisions as much as possible, so we can make the best possible tradeoffs. Nothing is free, but a well-designed system will get the maximum benefit from each bit of complexity added.
The integrity of a system is vital. Users rely on the system to work, and developers must be able to rely on assumptions to be productive. Systems have local integrity, when implementations are correct, and they have conceptual integrity, which is harder to measure but at least as important. Good designers often “lock down” an API, sacrificing unneeded “flexibility” in order to make hard guarantees. For example, in pure functional programming, a function cannot have side effects; this is a restriction when writing functions (though often not an onerous one), but a great benefit when calling functions.
Communication is essential in the software world; it is usually the most inhibiting and expensive part of software development. Communication happens between clients and engineers, among an engineering team, between API writers and users, and indirectly between the programmer and end user. Weakness or failure at any of these points may be catastrophic for a project. Therefore it is critical to minimize risk by reducing the need for communication and increasing the quality of it. We do this through good engineering processes, but also by developing conceptual integrity. Consistent and intuitive UIs and APIs resemble clean glass; the user forgets about the interface and sees beyond it.
My favorite kind of work involves:
- People who care about creating quality software
- People who are committed to teamwork and are willing to be flexible
- Solving challenging problems
- Using software to create innovative systems that apply technology where it is most effective
- Mythical Man-Month by Fred Brooks: Decades of software project management experience condensed into a small book.
- Martin Odersky and Typesafe: Dr. Odersky is a brilliant computer scientist who built javac and created my favorite programming language, Scala.
- Patterns of Software by Richard Gabriel: Explores Christopher Alexander’s work on architecture and design as it applies to software.