A couple of years ago I was managing a very distributed team – or really set of teams: Shanghai, Minneapolis, Seattle, Santa Clara, and Boston. Everyone worked for the same company, but culturally the teams were hugely divergent.
In one region, the developers in the team preferred things to be as loosely defined as possible. Their ideal state was “tell me how you’re going to rate me” and then you got of their way as they min-max’d based on whatever measurement rules you just set in place. When they were in charge of a specific element of the solution, there was a great deal of confidence it’d get done and effectively. But when they needed to be a bit more of active coordinator with a growing solution, they struggled quite a bit more – communication overhead really took a steep hit.
The opposite end of the spectrum was a region where the developers preferred for everything to be fully specified. Every detail defined, every option laid out and determined, how things work, and how things fail. Lots of detailed definition, to a level that extremely exhaustive – and would frankly annoy nearly all the developers from the first region.
I would love to make a hasty generalization and tell you that this was a “web developer” on one side and an ex-firmware developer on the other, but these folks were *all* firmware-level developers, stepping into a new team we had merged from a variety of pieces and places. Everyone was dealing with new development patterns, a new language – quite different from what they were used to historically, and a different business reality with goals and intentions that were in a high degree of flux.
What is surprising to me is that while I started out sympathizing with the first region’s culture far more, the influence of the spectrum – and the far side that preferred the specificity is what has stuck with me. I had previously left a lot more unspecified and open to interpretation – and not surprisingly that bit back upon occasion. Now with programming, regardless of the language, I want the tools to help me support that far more detailed, specified version of what I expect.
Last fall I diverted heavily into a C++ project, where we explicitly pulled in and used an optional extension through a library: type_safe. Back in December, Visual Studio went and exposed a fatal compiler error bug in the Microsoft compiler update that just exploded when attempting to use this library, much to my annoyance. But even with the type system of C++ and this library working with me, I can’t even *imagine* trying to write stable C++ code without doing a ton of tests to validate what’s happening and how it’s working – and failing.
I’m still tempted to delve into Rust, as I keep hearing and seeing references to it as a language with very similar safety/structural goals to swift (quite possibly with stronger guarantees – I don’t have a great way to judge the specifics there though). Bryan Cantrill keeps pimping it in the background of his conversations at Oxide Computing’s On The Metal podcast. If you’re into some fascinating history/interviews about the software-hardawre interface, it’s amazing!
The end result is that I’ll start out sketching in ideas, but want my tools and languages to help me drive to a point where I’m far more “fully specified” as I go through the development process and iterate on the code. In my ideal world, which I don’t really expect, the language and software tooling helps me have confidence in the correctness and functionality of the code I’ve written, while allowing me the expressiveness to explore ideas as quickly as possible.
Just like the cultures and regions I navigated with that global team, it is a matter of sliding around on the spectrum of possibilities to optimize for the software challenge at hand.