1. 8

I believe a surer route to good programming is focusing on avoiding mistakes rather than focusing on doing things ‘right’. In this episode, I give four tips for adding a modicum of rigor to your programming. First, proof-read all changes before committing. Second, execute every line of code. Third, double-check you’re in the right file. Fourth, double-check your docs are for the right version.

For anyone interested in the topic, there’s a part II continuation video linked to on the same website.


  2. 3

    These are some good tips. I recently have added more of this sort of rigor to my development process, with basically the realization that I don’t want to known as they guy who turns over code that breaks in an obvious case.

    1. 1

      Yea, it’s mortifying to have to explain that to your team / boss / customers. The programming equivalent of a terrible typo in a mass email.

    2. 2

      I commited code that broke the build today because I doubly defined something. The worst thing is that I proof-read it. It built, but I didn’t want to run all tests because it was only a six-line diff and I didn’t want to wait for over an hour. It also passed review.

      Let’s say I’m having trouble focusing working from home with the heat.

      1. 1

        This highlights how friction can be an issue — if your tests take a full hour, it must be very trying to one’s patience. Is this something your team could theoretically speed up by throwing more hardware at?

        1. 1

          I’ve thought of this as well. The simple answer is no – the tests are already run in parallel. The more detailed answer is no – but we could at least run the tests on a different machine than the development machine so that I could check out another branch and do some actual work while the tests are running.

          In this particular instance, I could and should have run a specific testsuite which only takes about a minute but is a quick smoke test.

          1. 1

            Got it.

            The context for my question was based on a mistake I made in the past. Basically I was too cheap to pay for sufficient parallelization on our continuous integration server (CircleCI), despite my head engineer saying the tests could be run 5x+ faster. Considering the cost of an engineer’s time vs. a few extra docker container instances, it was a false economy.

            1. 1

              With that many tests, ideally during development you run only the unit tests for the files/modules you have edited, and possibly their transitive dependencies. Bonus points if your testing tool watches for file changes and then takes a snapshot of changed files and runs tests on that, instead of on your development directory, allowing you to continue making changes.

              Another possibility is to push your complete commits to side branches, and defer merging to your main branch to a bot that rebases them, tests them, and then merges them (assuming Git). Something like bors (combined with git-test), if you’re using Github.

              1. 1

                Unfortunately, there are no unit tests, and not everything is nicely modular. Every test is an integration test. The test suite consists of hundreds of thousands of integration tests.

                This sounds horrible, but there are practical reasons that this is the way things work (and they are not all ‘no time to rewrite everything’).

                Another possibility is to push your complete commits to side branches, and defer merging to your main branch to a bot that rebases them, tests them, and then merges them (assuming Git). Something like bors (combined with git-test), if you’re using Github.

                We’re not, but that is a terrific idea. I just wonder how well it plays with the way things are currently set-up.

        2. 1

          Both what to do and what not to do are important concerns. But for many people avoiding mistakes becomes the primary driver, and they fail to look up and get the whole picture because they’re busy avoiding mistakes. Excellence of design must sometimes be allowed to take precedence over mechanical mistake-avoidance.

          An even more sure route to good programming also takes into account why things go wrong, and crucially, why things go right when they do. It is critical to analyse second-order effects because frequently they are the only way to influence systems.

          1. 1

            I’m intrigued by your approach of analyzing why things go right. Perhaps due to temperament, this is something I’ve rarely done. I’d be curious to know more if you have any public write-ups (e.g. blog posts) you’re able to share.

            1. 2

              I have unfortunately never gotten around to writing down my take on it, but this article from Safety Differently is as good a start as any: https://safetydifferently.com/why-do-things-go-right/

              1. 1


          2. 1

            OP here: For an off-topic, behind-the-scenes mini freak-out I had, I couldn’t for the life of me decide if calling the post “how to make less” as opposed to “fewer” mistakes was itself a mistake. I went back and forth editing the title.

            Generally speaking, “fewer” would be the correct word, since the mistakes are countable. Yet somehow it sounded off to my native ears — stiff, cludgy. Perhaps the insertion of the adjective “dumb” in-between is the cause.

            What do you think?

            1. 3

              I think you’re right, the “dumb” turns it into a miniature garden path sentence - “less dumb” reads better than “fewer dumb”, but then it has to be re-parsed as “dumb mistakes”.

              I like the “less dumb” interpretation though - compare “how to make a smaller number of silly mistakes” with “how to make mistakes that are less silly but just as numerous”. Every dumb mistake wastes time you could have spent making a mistake that teaches you something.

              1. 1

                “Garden path sentences” is a great explanatory concept — thanks for bringing it to my world.

                Very much agree with the idea that if you’re gonna make a mistake, it might as well be a solid one :)