Why do I want this book?

I think there is a substantial gap in how we learn programming. In the beginning, we stumble through the basics, like our first programs, data structures, and basic tooling like version control. In the middle, we briefly get a little exposure to the idea that code is designed, often in the form of some boiled-down object-oriented ideology. (Fields in your classes should be private! Why? Well public fields are just immoral of course.) In the end, we branch out into a breadth of introduction to lots of specialized topics, like operating systems, algorithms, web development, programming languages, artificial intelligence, and so on. And then, the real education begins, when we go out and get experience writing (and maintaining) real programs.

In case it’s not obvious, I think that middle bit needs some work. Part of the problem is that it’s very hard to teach design without experience. Part of the problem is that object-oriented ideology has too strong of a grip. (What are you going to go on to write? C++, Java, Python, Javascript. It’s not that it doesn’t make sense to talk about OO, but it’s terribly incomplete as a way to think.) And what we do teach about design is often done badly: unjustified rote mimicking of rules handed down from on high, or “good designs” that are actually just workarounds for the bad designs we’re stuck with. There’s also some things we should talk about when it comes to design that, inexplicably, we just don’t. Maybe it comes back to the experience thing, I don’t know.

Or maybe we just don’t want to portray our field as being a giant collection of hacks for working around decades-old poor decisions that we’re now permanently stuck with.

The best advice we give programmers is to go out and learn several different programming languages. Languages frequently codify a particular approach to thinking, often called a “paradigm” (though I’m not sure I like how people talk about “programming paradigms”). If we really knew the perfect way to design programs, it’d eventually manifest itself in a perfect programming language. We obviously don’t have such a thing. But we do see value in learning multiple different languages. We can think better about design, even if we don’t have a language to perfectly express these thoughts with.

What is this book about?

I want to write a book about code design. It’s not a book for beginners, though I hope they’ll still find it valuable. It’s not necessarily a book for “software architects,” who are (it seems?) sometimes too far removed from the actual programming to care. I want this book to be an excellent tool for experienced programmers who want to get better at programming – programming, not software engineering process, not management, not specialized subject material (OS, PL, AI, etc), not individual tools or languages, just general programming. Specifically when it comes to design: APIs, interfaces, libraries, languages, any time we have to create something and then get stuck with maintaining that backwards compatibility forever.

I’ve taken a couple of shots at “object-orientation” but it’s not really my intention to disparage it. The issue I take is that there’s an ideology that comes with OO that I think doesn’t belong. It’s just one particular way of looking at design. A great many things are best structured in ways that sometimes map poorly to a purely object-oriented world-view (or just to our current object-oriented languages). Thinking about them as they are, instead of how some our languages force us to conceptualize them, can be helpful. Even if we still write OO programs, we should keep our thinking straight between the solution and the mapping of that solution to within the constraints of the language.

Partly, this blog is a tool to figure out exactly what will be in this book as I go. But I can give my current thoughts about things I plan to include:

  • Fundamental, but high-level, concepts in programming. One of the things that can sometimes make high-level mathematics inscrutable is that to understand a high-level abstraction, you need to be able to come up with lots of different little concrete examples. There is, I think, a similar problem for programming, except to be able to come up with those concrete examples, you need a few years of experience. This makes it hard to ever teach high-level abstractions. (See, for example, all of the flailing about on the internet about monads.) We should nevertheless have good resources for experienced programmers (3-5 years perhaps) to come back and learn these things. And it seems there’s plenty here we could be teaching that doesn’t need extensive experience, either. (I haven’t the slightest idea why it took me until almost graduate school to hear about “the expression problem.”)
  • What we can learn from other “programming paradigms”, distilled. One of the best ways in which we try to instruct programmers is by encouraging them to learn other programming languages, with different “paradigms” for solving problems. Some amount of this simply has to be done themselves: it’s hard to define “blue” to someone who’s never seen it. Experience is the foundation of everything. But we should also provide a decent road-map: show what can be learned from different languages, and what’s interesting (and perhaps, too, what’s actually rather mundane, but could easily be mistaken for profound).
  • Careful discussion of design models. Many programmers can say what MVC is, and many can also do more than just cargo-cult what they’ve seen before. But remarkably few (though granted, I have high expectations…) can explain why. Most disagreements about how to do MVC (fat controller? fat model?) devolve into talking past each other. We should do a better job of looking at many common models for constructing programs, and look at why these models were developed the way they were.
  • Case studies on the designs of various systems. (Libraries, APIs, OS?, PL?) We often send programmers into the world having taught them little about how to actually design. Many programming tasks, especially small ones, are such that mis-designs are simply things you can fix. But exposed interfaces can’t be changed without breaking external users. We should do a better job of looking at good and bad designs of various libraries, especially standard libraries, where programmers might often look for examples of how to do things right (and often get lead astray).

I am also considering including some discussion of designing secure software. Sometimes “security” is a specialized topic, but I think it has some interesting overlap with design more generally.

But this plan is not set in stone. Part of the reason I’m here promising to write essays over the next 1–2 years is to give myself time to really think about what should be here. And as a bonus, to allow people to yell at me early on, if I starting going in the wrong direction.

How will this book happen?

Are you interested in seeing this book? If so, please support my Patreon. Before I commit to actually writing the book proper, I want to know if there’s sufficient interest. There will be a new essay on this blog every Tuesday for the foreseeable future.