I’ve been reading James C. Scott’s Seeing Like a State and as Scott chronicles the myriad ways that governments totally screw things up for their constituents through (often) well-meaning schemes of modernization and improvement, I’ve been thinking a lot about how this concept applies to the work I do in software engineering and product management. (Note: if you want to read a more general review of the book, go check out Scott Alexander’s review from 2017.)
The fundamental thesis of Seeing Like a State is that governments, in order to be able to be governments, necessarily have to abstract from the truth on the ground — a census can capture certain data points about the population, but necessarily cannot reflect all of the wonderful human variety that makes us who we are and that we observe and rely on in ourselves and in our neighbors. Like in Borges’s story fragment On Exactitude in Science we know that a map is only useful to the extent that it abstracts (strategically) from the true detail of our world — a map that actually includes all of the detail that might be relevant to any living being will necessarily be as large as the territory itself!
Where this is a problem is when so-called “High Modernist” governments believe that they can effectively use their birds-eye (and necessarily abstracted) view of the world to impose “improvements” on their constituents. Scott points out that these improvement schemes consistently fail because the governments fail to recognize that the differences they have abstracted over are actually incredibly meaningful to the human beings actually operating on the ground. Scott gives lots of examples from agriculture where government bureaucrats insist on the use of certain farming methods that have been “scientifically proven” to work in the lab (or in another country).
Unfortunately, when put into place in a different context, the methods fail abysmally and, though well intentioned, cause great suffering among the populations they were supposed to help. In general, the farmers on the ground tend to know better than the bureaucrats in the capital what will or won’t work well in their particular farm — they actually tend to have lots of expert knowledge about their particular soil, how it holds or releases moisture in different seasons of the year and how well different crops may or may not perform (and they recognize that this might vary substantially within their own property and from their neighbor’s land). When bureaucrats impose rules from the capital, they elide over these “minute” details that are actually critically important to maximizing the productivity of the land.
As I’ve been reading these accounts, I keep thinking that what the government should do is not force the farmers to “modernize”, but rather simply … ask the farmers what they need. If the farmers need tractors, deliver tractors! If they need more consistent water for their crops, the government can help installing water pipelines and irrigation systems. If they need seeds, the government can deliver seeds. Where the government consistently fails in these schemes is in assuming that the farmers are ignorant and that they do not know what is best for themselves and their families.
While it’s easy to mock these schemes as clearly destined for failure, I often see the same thing happening in software! Especially for tools- or services-oriented internal teams (like the Analytics and Data Teams that I tend to work with) it’s very easy to assume the hubris of the misguided bureaucrats and believe that all your users need is your particular solution to fix their problem (that they might not even be aware of). When this happens, the best case scenario is that the software gets built and goes unused — in the worst case scenario the software builders break a solution that used to work and replace it with a less-flexible system that actually increases the work load of the users it was intended to help. Here’s how I’ve seen this in the real world:
- The software engineer observers a workflow that seems cumbersome and error-prone. Often involving complicated spreadsheets.
- The software engineer thinks to himself: I know, I can code this process up in R or Python, get the benefits of version control and it will save these excel jockeys a boatload of time
- Software engineer starts coding. Realizes this excel spreadsheet is more complicate than they thought. Keeps coding, eventually gets to feature parity.
- The software engineer attempts to role out their shiny new tool, only to learn that 1) the excel model they were attempting to re-create has already changed substantially since they started this project and 2) the users don’t want to use the new tool because they crucially rely on the flexibility of Excel to do their jobs
I’ve seen this happen a number of times (and have been guilty of it myself!) — while this happens very frequently with data scientists and analytics engineers who look down on excel workflows, I know it also happens in other realms of software engineering as well.
Where this process goes wrong is that the all-too-helpful software engineer failed to ask their users what they actually needed help with — they jumped from their assessment of the problem to a proposed solution that missed out on crucial details of how the users actually do their jobs and the features that they need to continue doing that job well.
What we as software engineers and product people must always remember is that you have to actually talk to your users. In the example above, the software engineer might have learned that the most pressing problem was actually a version-control and file-naming problem — in which case the software engineer could have focused on that problem in particular and saved the user (and the rest of the organization a lot of headaches) while also wasting less time (==money) on the project.
That user probably does recognize that their workflow isn’t ideal, but in order to figure out how to help them, you actually have to talk to them to understand their true pain points. As internal tool-builders, we are often at greater risk of building tools that our users don’t want or need because there are no market forces that drive our product adoption. With external user-facing features, our business will observe if users like them or not (or, if our business isn’t paying attention to these things, probably won’t be around much longer anyway). However, with internal tools the danger of being the bureaucrat imposing changes from a too-abstracted view of the wold is much more present, and we should remain vigilant that we aren’t building useless tools or, even worse, imposing our broken new tools on users just trying to get their jobs done.