Intrapersonal vs. Interpersonal
It’s so very common to see the programmer who is early in their career tempted to treat their skills as existing in a vacuum—and that is not without its own merit. There is a reason why the developer existing as a renegade feels “more productive” than the dreary, droopy engineer who goes ticket by ticket. In short, the former, the intrapersonal engineer, has a faster iteration loop: they go through trial-and-error freely and rapidly, learning and improving at the pace of their fingertips and tooling. The latter, the interpersonal engineer, provides contributions to a team that must understand and interpret the engineer’s progress: trial-and-error is bottlenecked by the schedules of every stakeholder involved.
For obvious reasons, the interpersonal engineer is seen as superior, more mature, than the maverick, intrapersonal alternative. This is for historical and cultural reasons. Namely, most projects that are worth their salt are hard. They require diverse skillsets and expertise, well-documented practices that have been refined through repeated usage, and, worst of all, they require parallelism between skillsets in order to achieve deadlines.
But the issue I’ve been having with software as of late is that… programming isn’t hard. Hardware is hard. Yet hardware, I fear to say, has become a rarity in an ecosystem as optimized as computing—reduced mostly to niches that already have entrenched engineers occupying scarce positions within a scarce market. It’s in these spaces where principled engineering will remain strong, and maverick programmers are rightly frowned upon for the risks they introduce to team cohesion and to the integrity (and potentially: safety) of the product.
So, what then, of everything else? Programming for data entry and retrieval isn’t hard. Even an AI can do that.
In projects that are hardware agnostic, the only element that is necessary to coordinate between interlocutors is that of language. A project must align the language of its interface with that of its target audience. But language, like programming, is cheap. Even an AI can do that.
Thus, it’s worth repeating: outside of hardware, what value is there in having a team at all?
My answer is that being a part of a team is simply life-affirming, and I would like to argue for a general attitude shift that supports this despite the direction that cold capitalism would lead us to believe. Namely, I would like a future where programming is treated as a collaborative art-form.
This is possible when we recognize that all programming reduces to the names we give abstractions. The issue that we often run into is that these names have three conflated usages: names that communicate the internal structure of the abstraction being used, names that communicate how the abstraction relates to other abstractions, and names that communicate the abstraction to other people. Mastery of the first two usages is simply contingent on the quality of one’s tools, such as the inclusion of formal methods and rigorous typecheckers, and I posit that the key difference between intrapersonal and interpersonal development is the inclusion of this last usage: where names are given to abstractions for the purpose of communication with other people.
Formal methods have fully and completely solved all matters of naming when it comes to internal abstractions and their relations with other abstractions. Both Lean4 and Veil are projects that demonstrate this fact in totality (I plan to write more about my adoration of formal methods in future posts). Thus, with this tooling in place for the maverick programmer to freely construct and solve problems in isolation, all that remains is the question of how these abstractions should be exposed, exchanged, and exposited with others. In my view, this amounts to a simple matter of storytelling.
So let’s say a problem has been solved intrapersonally regarding the election of
a leader within an assembly of nodes arranged in a Ring (see the example in
Veil
here).
The issue, as it sits on one’s own computer, is that the solution is merely
syntax: the structure of the abstraction in isolation. But the triviality of its
syntax is a testament to its universality: all that remains is how a Veil module
such as Ring (as in this case) can be transitioned from syntax into a story.
For example, say you have a cluster of nodes that need to distinguish a source of truth between them in order to resolve conflicts between replicated data. Typically, a team would give cute nicknames to such nodes in the cluster: Alice, Bob, Claire, and Dave. Once you realize that the link between theory and practice is only a matter of associating a few requirements on this set of nodes, namely, by giving them both a total order and a ring topology, then suddenly the boring intrapersonal syntax lights up as a full-fledged election for a leader among real tangible machines. The syntax has become a story.
So, the conclusion I’d like to make is that our tooling has provided us a new way to compartmentalize programming between those elements that can be done efficiently as intrapersonal development from those that bridges us into the broader world of collaboration. The shared names are what most issues of interpersonal development boil down to when you do not need to reconcile with hardware, so long as the underlying choice of abstraction is correct (which is a separate issue worth an independent post).