| Something that shocked me was working with junior programmers for the first time. For decades, I had either worked solo or with other experienced developers. It was an eye-opening experience. My style is influenced by Haskell and Rust, even when I program in, say, C# or PowerShell. A simple example: I will extract the read-only logic into a pure function and minimise the size of the mutable procedure. This makes it trivial to test the logic in isolation without triggering any side effects. Similarly, the logic can have convoluted control flow but the imperative code can then wrap that with a single try-catch block, transaction, or retry loop. For me this was such second nature that I didn’t even realise I was doing it until I saw the imperative spaghetti written by the juniors. I tried to explain with pair programming sessions what the benefits are of my approach. Without fail, they would just “hack something” into the existing spaghetti, adding yet another mutable global variable to track some new state. In every case they said they were in a hurry and that they would “fix it later”. I replied: “there is no later.” |
This. We need to stop using time pressure as an excuse to do a bad job. Moving things out to a separate function might add 10 min but save 100x when everything comes crashing down.
Of course you shouldn’t overengineer but so much can be gained from spending a little time just thinking about how this should work.