I have a theory that the best software developers are also really good at some discipline that involves putting things together that is tangible. By ‘tangible’, I mean that software engineering generally involves resources that you can’t actually hold, like time or code or computation. It’s much harder to understand consequences when all your problems are abstract.
So take, for example, cooking. If you wanted to prepare the following meal for your family:
- Pasta with home-made tomato sauce
- Chicken, marinated for over 30 minutes
- A simple salad
and the goal was to have dinner ready at 7, with each of the 3 parts done at the same time, so that the hot dishes were hot and the kids got to bed on time, you need a pretty complex project plan. It doesn’t have a lot of elements, but it does have a lot of parallelism and mode switches, plus some dependencies.
It ends up looking like this:

As you can see, you end up with a somewhat tricky job to do single-handed in order for everyone to end up with a hot meal at the appointed time. If you do it a lot, it gets easy, but if you are new to it, or get out-of-practice, estimating the times and hitting all your start times is a bit tough.
The other risk here is that you can get stuck trying to do two things at once, which will result in a schedule slip.
What is interesting about this is that when you put it down on paper, you see that there is a clear constraint in how short a time you can possibly compress this to, and also one in lots of ways it can run longer than that. After a long day of work, you want to minimize prep time, but if you mis-estimate, you will end up eating something cold.
If fact, my project plan that I drew up above has a problem. It has me making salad and running the sauce through the food processor at the same time. It makes a lot more sense to do the salad a bit earlier, but there you are doing a trade-off between slightly wilted salad vs a hot sauce. Here, a helper might be useful.
I feel that eating cold chicken is a lot more tangible than delivering a part of your software a bit too early or a bit too late. Eating under-cooked chicken is certainly a good analogy for buggy software that has bugs because it had a bad build order and had a critical part (getting rid of salmonella (ha! literal bugs)) at the very end, rushed.
I think that excellent engineers, especially those that are good at designing projects, should practice their skill on tangible tasks in a non-engineering discipline, rather than exclusively on programming. It gives you a much better sense of the shape and size of tasks when they are physical.
By the way, the Pasta Sauce I make is from Diane Seed’s great little cookbook: The Top 100 Pasta Sauces, which my college roommate introduced me to and which has a great standard tomato sauce. I use a food processor rather than a food mill because the food mill, while traditional, doesn’t yield as much sauce, in the end.