Dogma rules and programming
By Bjørn Borud
Perhaps there should be something along the lines of a “Dogme 95” for programming. Perhaps there is. I must admit that before writing this I didn’t check. And there is a reason for that (as you will see later).
You may be familiar with the “Dogme 95” manifesto written by Lars von Trier and Thomas Vinterberg. To quote the Wikipedia article:
The goal of the Dogme collective is to “purify” filmmaking by refusing expensive and spectacular special effects, post-production modifications and other technical gimmicks. The filmmakers concentrate on the story and the actors' performances. They claim this approach may better engage the audience, as they are not “alienated or distracted by overproduction”.
Now, I’m not a high minded artist. I’m just a programmer … and a few other things. But having a set of rules to keep one’s impulse to commit acts of extravagance in check have turned out to be useful. Not that these rules have ever been committed to any shareable medium before. And I am sure that the list looks a bit different from day to day. Depending on what I’m struggling with the most on any given day.
However, I’ve had conversations with people about writing something like this. Øyvind Bakksjø made a lovely slide deck (an oxymoron, I know) about how to program in Java which contains a lot of wisdom. I won’t be sharing it as I consider it his work, but I have long wanted him to turn it into a book. And possibly see if it can be adapted to other languages or genericized somewhat. Much of it is about rather mundane stuff, but it is mundane stuff that is really important. Some of which is included below.
This is not a well thought out manifesto of any sort. Think of it as a work in progress that starts with me investigating why I write software the way I do. I’m an old, opinionated fart, who has written code in 4 (soon 5) different decades. However, behind some of those experiences lies painful experience and many, many mistakes.
Oh, and if you watch any of von Triers movies, you do so at your own risk.
The Rules (so far)
WARNING: This is both too long and not sufficiently structured. Think of it as a work in progress. If you have thoughts on this, please share them with me. Preferably over a nice dinner.
1. Have empathy
When you write software you should always have other people in mind. Other developers, the users of the software etc. Put yourself in their place. Some things you can do to be nice to other people are
-
A piece of software you write is important and dear to you. To someone else it it may be just a hurdle that has to be passed with as little fuss as possible.
-
Make sure it is easy to build and install your software. Don’t turn installation into a scavenger hunt.
-
Prefer mainstream build tools and conventions. Don’t be overly clever.
-
If your install instructions are more than a paragraph of text you have done something wrong. If it takes more than a couple of minutes to get something running that you can test, you are not there yet.
-
Make documentation useful. Make it short and to the point. Include commands and code that can be cut and pasted.
-
Don’t skip header files or imports from your code samples. This is not a nice thing to do, and while code samples become shorter if you skip these, they become a lot less useful because users unfamiliar with the codebase will have to figure out the imports.
-
Adhere to widely adopted conventions as much as possible. Yes, there may be better ways to do things, but nobody wants to learn clever/obscure ways of doing things
-
Nobody cares if it works for you (Thanks to Sterling Hughes for putting that on a slide 20 years ago. I refer to it as “the most important slide in software engineering”.)
2. Strive for runtime minimalism
Don’t do more where less will do. Code that doesn’t exist also doesn’t have bugs. Try to write code that requires as few moving parts as possible and as little effort to understand as possible.
-
Most programs can be distributed as a single binary that has all its runtime dependencies on board. If your language doesn’t support this, learn a language that does. And while that may be harsh it is both good and well-intentioned advice.
-
Prefer sensible defaults over configuration. And when you do offer configuration, give the user some options: command line options, environment variables, files etc.
-
Be consistent. This is a form of cognitive minimalism. If you always do the same things the same way, your code becomes easier to read and people know what to expect.
-
Prefer to embed functionality rather than have external dependencies. Operational complexity increases exponentially with the number of moving parts. For example: if your database needs are modest: embed it into the application. You can always add support for having an external database later.
3. Strive for simplicity
Don’t complicate things unnecessarily. Complexity might look impressive, but it comes at a cost. Always look for simpler solutions with fewer edge cases.
-
Don’t make large type hierarchies. Make few and clear types. If you really do need lots of types, hide them from view and keep them out of APIs as much as possible. While having lots of types improves safety, it also lowers developer ergonomics considerably. Find the balance.
-
If you program in an object oriented language try to avoid inheritance. Use generics very sparingly.
-
Don’t use large frameworks when they are not strictly needed. Some frameworks are like cancers that you cannot get rid of without significant rewrite. Frameworks go out of fashion.
-
Don’t use fancy algorithms that are hard to understand and/or debug when a simpler algorithm will serve the purpose just as well.
4. Correct, understandable, fast
…these are the priorities for software development, in that order.
If something isn’t correct, it doesn’t matter if it is understandable or fast. If nobody can understand your code it will die because nobody will want to touch it, and rightly so. Finally, there is no good reason for a professional to write slow code if faster code is within easy reach.
-
Your tests should be the negative mold of your code. Treat it almost like a functional spec. If you do it right you should be able to re-create the code under test from the tests and the function/method documentation.
-
When starting something new, don’t spend time on writing complete tests until the code has solidified a bit. It’ll act as friction when you want to redesign things.
-
Look at the relationship between your function/method documentation and the tests; the documentation lists expectations and makes promises, the unit tests are there to make sure you keep them. If your documentation or your tests are lacking in this respect you have to fix the documentation, the tests or both.
-
Write code so other people can understand it. Use conventions, code standards and the tools that enforce them. Sure, you may not agree with them, but consistency is better than everyone getting their way. It takes you less time than you think to adopt a code standard and conventions.
-
Be careful with terse syntax offered in some languages. Readability and size of code has nothing to do with number of lines, but the mental effort required to read it. Sometimes a few extra lines of code saves time when maintaining the code later.
-
Speed is much more important than you think. But speed doesn’t start with optimizing code, it starts with thinking about design. What will the code do? What will be the hottest execution paths? How does the data flow through the system? How do you deal with scale?
The quote premature optimization is the root of all evil has done more damage than good because people use it as an excuse to not think about performance. (People also tend to not understand the context of that quote).
5. First, try to solve it yourself. Then look what others do.
Of course, this doesn’t apply to all problems - it mostly applies to the kinds of problems that define how you approach the design and implementation of some major piece of software. For the more mundane just head over to Stack Overflow.
With everything so easily available it is tempting to start by looking at how other people solve problems. Don’t. Try to work it out yourself first using pen, paper and a calculator. Then look at books and papers. Then look at what other people do (code). You will both understand the problem better, and perhaps, the solutions of other people.
Once in a blue moon you might even produce something original. The world depends on people who can do this in order to advance the art.
Postscript
As you may have observed in the introduction to this posting: I made no initial research to see if anyone has written a similar set of dogma rules. This was intentional since I first wanted to see what I would come up with. I am going to have a look later this week if someone else has written something I can make sense of on this topic. But I wouldn’t hold my breath waiting for a followup to this posting, because I’m a very occasional blogger.