Postel’s Principle as Moral Aphorism

[All the usual disclaimers. Wanders dangerously close to moral relativism.]

I.

Postel’s Principle (also known as the Robustness Principle) is an obscure little guideline somewhat popular among computer programmers, in particularly those working on network protocols. The original goes like this:

Be conservative in what you do, be liberal in what you accept from others.

My parents were both computer programmers, as am I, and my first job as a programmer was working on network protocols, so it shouldn’t be too surprising that I ran across this principle a long, long time ago. I suspect I heard it while still a teenager, before finishing high school, but I honestly don’t remember. Suffice to say that it’s been kicking around my brain for a long time.

As a rule of thumb in computer programming, Postel’s Principle has some basic advantages. You should be conservative in what you do because producing output that isn’t strictly compliant with the specification risks other programs being unable to read your data. Conversely, you should be liberal in what you accept because other programs might occasionally produce non-compliant data, and ideally your program should be robust and keep working in the face of data that isn’t quite 100% right.

While in recent years the long-term effects of Postel’s Principle on software ecosystems have led to some pushback, I’m more interested in the fact that Postel’s Principle seems to apply as well just as well as a moral aphorism as it does in programming. Context matters a lot when reading, so here’s a list of other aphorisms and popular moral phrases to get your brain in the right frame:

  • What would Jesus do?
  • Actions speak louder than words.
  • If you can’t say something nice, don’t say anything at all.
  • Give a man a fish and you feed him for a day; teach a man to fish and you feed him for a lifetime.
  • Be conservative in what you do, and liberal in what you expect from others.

II.

I am, by nature, a fairly conservative person. I’m also, whether by nature or past experience, somewhat socially subordinate; I’m usually much happier in a secondary position than in any role of real authority, and my self-image tends to be fairly fragile. The manosphere would happily write me off as a “beta male”, and I’m sure Jordan Peterson would have something weird to say about lobsters and serotonin.

This combination of personality traits makes Postel’s Principle a natural fit for defining my own behaviour. Rather than trying to seriously enforce my own worldview or argue aggressively for my own preferences, I endeavour not to make waves. The more people who like me, the more secure my situation, and the surest way to get people to like me is to follow Postel’s Principle: be conservative in my own actions (or else I might do something they disapprove of or dislike), and be liberal in what I accept from others (being judgemental is a sure way to lose friends).

[People who know me IRL will point out that in fact I am pretty judgemental a lot of the time. But I try and restrict my judginess (judgmentality? judgementalism?) to matters of objective efficiency, where empirical reality will back me up, and avoid any kind of value-based judgement. E.g. I will judge you for being an ineffective, inconsistent feminist, but never for holding or not holding feminist values.]

Unfortunately, of course, the world is a mind-boggling huge place with an annoyingly large number of people, each of whom has their own slightly different set of moral intuitions. There is clearly no set of behaviours I could perform that will satisfy all of them, so I focus on applying Postel’s Principle to the much smaller set of people who are in my “social bubble” (in the pre-COVID sense). If I’m not likely to interact with you soon, or on a regular basis, then I’m relatively free to ignore your opinion.

Talking about the “set” of people on whom to apply Postel’s Principle provides a nice segue into the formal definitions that are implicit in the English aphorism. For my own behaviour, it makes sense to think of it like the intersection operation in set theory, or the universal quantifier in predicate logic: something is only morally permissible for me if it is permissible for all of the people I am likely to interact with regularly. Conversely, of course, the values I must accept without judgment are the union of the values of the people I know; it is morally permissible if it is permissible for any of the people I am likely to interact with regularly.

III.

Since the set of actions that are considered morally permissible for me are defined effectively by my social circle, it becomes of some importance to intentionally manage my social circle. It would be untenable to make such different friends and colleagues that the intersection of their acceptable actions shrinks to nothing. In that situation I would be forced to make a choice (since inaction is of course its own kind of action) and jettison one group of friends in order to open up behavioural manoeuvring space again.

Unfortunately, it sometimes happens that people change their moral stances, especially when under pressure from other people who I may not be interacting with directly. Even if I have a stable social circle and behavioural manoeuvring space today, tomorrow one of my friends could decide they’re suddenly a radical Islamist and force me with a choice. While in some sense “difficult”, many of these choices end up being rather easy; I have no interest in radical Islam, and so ultimately how close I was to this friend relative to the rest of my social circle matters only in the very extreme case where they were literally my only acquaintance worth speaking of.

Again unfortunately, it sometimes happens that large groups of people change their moral stances all at once. Memes spread incredibly fast, and a small undercurrent of change can rapidly become a torrent when one person in a position of power or status chooses a side. This sort of situation also forces me with a choice, and often a much more difficult one. Apart from the necessity of weighing and balancing friend groups against each other, there’s also a predictive aspect. If I expect a given moral meme to become dominant over the next decade, it seems prudent to be “on the right side of history” regardless of the present impact on my social circle.

Being forced to choose between two social groups with incompatible moral stances is, unsurprisingly, stressful. Social alienation is a painful process, as can attest any Amish person who has been shunned. However what may be worse than any clean break is the moment just before, trying to walk the knife edge of barely-overlapping morals in the desperate hope that the centre can hold.

IV. (PostScript)

I wrote this focused mostly on myself. Having finished, I cannot help but wonder how much an approximation of Postel’s Principle guides the moral principles of most people, whether they would acknowledge it or not. Even people who claim to derive their morality from first principles often end up with something surprisingly close to their local social consensus.

Theoretical Fun

The company I work for, like many other tech companies, has a thing where you get to spend a certain amount of your time working on projects of your own choosing. The most well known-example of this is Google’s now-defunct 80/20 rule but there are plenty of others.

This past week I had an opportunity to do some of this, and ended up brushing off my very theoretical computer science roots and digging into some graph theory in order to solve a very practical problem. Of all the things I get to do in software, this is far and away my favourite, and I had a blast working out the possible solutions.

In my career so far I’ve been lucky enough to have several opportunities to solve problems of this nature and then build out the solutions, and even publish some of them to talk about. It is extremely rewarding work. There are of course a few I can’t talk about as they are still internal, but here’s a sort of “hall of fame”: two other problems that I had a ton of fun solving at a computer-science-theoretical level and also resulted in really awesome (and sometimes popular!) practical solutions.

Wheel-of-Fortune Memory Allocator

https://github.com/eapache/wof_alloc

Arguably the overarching project here was Wireshark‘s wmem framework which I also designed and built, but while wmem was a lot of fun to work on it wasn’t particularly novel; it was just another memory pool library with a few minor tweaks to suit Wireshark’s use case and migration path. However, Wireshark’s unique memory allocation pattern demanded a custom allocator algorithm which I eventually extracted into this library.

As far as I can remember this was the first practical problem of this nature that I got to take the entire way: from identifying the problem, designing the solution, to building and shipping it, and I am forever grateful to the Wireshark core team for trusting a (at the time) university student to go and rewrite the deepest foundational layer of the project. At just under 1000 lines of pure C this allocator has been shipping in released versions of the project for 5 years now effectively unchanged, and the standalone version gets a fair number of hits on GitHub.

Sarama Async Producer

https://github.com/Shopify/sarama/wiki/Producer-implementation

A little while later, my first major project at my current job was to write a golang client for the Apache Kafka platform. Like wmem, a lot of it was pretty standard work (in this case implementing message formats and managing TCP connections). However, the design of the producer implementation was another one of these instances of theoretical fun. The requirements on a performant Kafka producer are complex and varied, balancing messages and batching across topics and partitions and brokers, while also maintaining message order in the face of partial failures and retries. I can’t tell you how many evenings I spent wandering around in a fog, stopping occasionally only to make tweaks to weird hypothetical flow diagrams on my whiteboard.

To a certain extent this project was less practical than the allocator; the reference java implementation was open-source and would have been fairly straight-forward to copy, but I did it myself for two main reasons:

  • I was working in Go, which provided me with very different concurrency primitives and indicated a very different design.
  • I was young, and not as aggressively pragmatic at the time.

To a certain extent it was also less successful; it has continued to evolve over the last four years and there are still parts of the design that I’m not entirely happy with. That said, it’s also far and away the most complex single algorithm I’ve ever built, and judging by Sarama’s popularity, it’s doing its job just fine in practice. I even managed to get a conference talk out of it.

GraphQL Warden

https://github.com/rmosolgo/graphql-ruby/issues/1333

If you recall my recent post on what I’ve been working on recently for my “real” job, it won’t surprise you that my most recent project is tangentially related to that. This one hasn’t been built yet (and my own pragmatism means it may never get built) but even from a design perspective I had a lot of fun with the process here. I definitely got way too excited when I realized that I could represent the two halves of the process as symmetric reachability problems in a graph-theoretical isomorphism of the schema.

And just maybe, the next time I get a chance to spend some “me time” at work, I’ll write an actual implementation of it!