Yet Another Example of the Porousness of Certain Borders


As a programmer, I find that one task that keeps coming up in my professional life is that of properly setting up abstraction boundaries. In writing up code to carry out some complex task, the imperative of accumulated folk wisdom is to strive to divide that complicated job into some sort of relatively simple interaction between relatively simple parts. The philosophy is the same one animating mechanical engineers to minimize the number of moving parts in their designs: everything that ought to move could, in some scenario, fail to move, and then where would you be? Intellectually, though, this subdivision has other implications for programming: the mental layering involved in this black-boxing is generally (although not universally, and I've heard some good arguments against) held to be a good thing. The point is that from any perspective outside one of these components, the internal structure of the component itself should be irrelevant. Whatever hidden gyrations it goes through to carry out its business with you are its own business, nor should it care about your own gyrations. The interface is a contract, but it is also a wall, and if the prisoner on the other side tapping out messages in morse were to be replaced by some other inmate who taps out the same messages, no other features of their life, their past, their tortured thoughts, should concern you.

The fear at the back of your mind, though, isn't that one of your components is taking advantage of its abstraction barrier to torture small children without your knowledge. No, once you accept that walls are good things, the question is really whether you've put the wall in the right place. Should it be ten feet further over, or maybe rotated by thirty degrees? Does the caching code belong with the protocol handler or the renderer? If we put the retry logic in the controller, we save on the double round-trip for failures, but that means that the controller is making certain assumptions about the batching logic. People fight holy wars over this stuff, and few things can be more frustrating to a programmer than needing to hack on a codebase whose abstraction boundaries weren't set up cleanly: there's never a good way to do what you want and you wind up making small changes to a hundred places, rather than one medium change to one place.

This sense of disquiet carries over from programming into life -- I get this sense in my gut every now and then looking at something from the news, wondering whether the particular problem or plight that sounds like the result of historical forces or some callous decisions are really just the well-disguised results of ill-established categories. I got thinking about this reading James Traub's New York Review of Books article about Sierra Leone, entitled "The Worst Place on Earth." Towards the end of his profoundly depressing article, he observes that one of the reasons for the collapse of the UN's peacekeeping efforts in so many places is that

For one thing, peackeeping wasn't designed to stop warlords like Foday Sankoh -- or anyone else for that matter. It was designed to help carry out agreements among states . . . But countries don't go to war with one another as often as they used to. We live in an era of collapsing states: and now governments declare war on factions, often ethnic, as in Kosovo; or factions try to murder their way to power, as in Liberia and Sierra Leone; or in the absence of any state at all, warlords fight each other for supremacy, as in Somalia.

This, I think, is a really good point. The philosophical underpinnings of the UN are of agreements among autonomous nation-states, and in some sense it is possible to see the UN's failures exactly where these assumptions break down. During the Cold War, anywhere that the US and USSR were closely involved the UN generally had to step back from: the intensity of the interests of the superpowers tended to make smaller domino-countries blur around the edges and lose their individual voices. A lot of the ills of modernization, I think, can be chalked up to the inadqeuacy of nation-centric theories of development in an economic environment dominated by multi-national corporations. And then there's Traub's point itself, that the UN is profoundly ill-equipped to deal with what seem to it like nations waging war on themselves. In fact, the bias towards nations accounts for one of the strange oddities of power-sharing arrangments and internal struggles for capitals: the power to speak with the institutional voice of a nation is an intangible prize but a valuable one. Diplomatic recognition, like code books and personal seals, is one of those interesting informational spoils of war. In programmer terms, the question is whether the nation interface is the right level of abstraction to deal with, well, whatever it deals with.

Here at home in our own anti-abstract nation, political parties have been making me scratch my head in the same way. Parties are granted some pretty strong priveleges by the government: the whole primary-general system is designed around a system of parties, and a party's performance in one election determines a great deal about what resources the government will allocate to it in the next. What makes this highly unnatural is that the parties themselves are not the units about which the electoral process makes its decisions: we vote for candidates and the elected officials govern, but it's the parties who structure the selection process. Proportional parliamentary representation appeals to me for other reasons (which I won't get into here), but it also possesses an intellectual clarity our current system lacks, in that the structure of the process matches the options available to the voter. Or, in the other direction, why not eliminate the parties as formally-recognized units, and stop having our primary system coddle to their interests? The bizzare gyrations the Reform "party" has gone through, to me, indicate the intellectual paupery of the whole party concept. The parties as voting blocs would probably still survive, and most elections would pit a Republican and a Democrat, but the face of soft money would be much changed, and some of the distorting effects of our de facto two-pary system would be ameliorated. Again, whether or not you think the barrier should be moved, the point is that we have put up a barrier here and that this choice of place must be understood to be a somewhat arbitrary one.

Another fought-over boundary is the division of corporate boundaries along a vertical supply chain. I've seen a whole bunch of articles about e-commerce that dwell on the nature of the e-tailer and its relationship to the physical fulfillment process. The e-business is free of the messy business of actually stocking and shipping items that plague real-tailers! The e-business can only be built upon the massive distribution infrastructure built up by UPS and FedEx and a nationwide supply of warehousing know-how! The e-business must exercise precise control over its fulfillment and massage the process to custom-match its customers' demands! The e-business should be a true virtual business and should outsource everything that weighs more than an electron! People talk about these questions as though they were deep and fundamnetal issues affecting an e-business, but this is the wrong frame: these are issues that pertain to an ecology of companies, not to any company alone. When I go to a web site and order something and it shows up at my doorstep, certain things need to take place. There are computer-related tasks: the interface presented to me, the billing and communication with me. There are industrial tasks: someone actually needs to manufacture the World's Best Salad Spinner. And there are distribution tasks: someone needs to bring it to my door and await my signature. The division of these tasks among corporations, from my perspective as a consumer, is entirely irrelevant. Decisions can be made different, with different consequences, but I don't think that any given model is necessarily right or wrong. If an e-business controls its warehousing, then it has the ability to respond to issues on a small scale and to optimize its process for the particular patterns of its business; if it leaves the distrubtion to someone else, it sloughs off a lot of headache and cuts its operating capital requirements. But to the extent that the system has to stock and deliver items and to take orders, the abstraction boundary embodied by the extent of a coporation is an unnatural imposition, an artifact of something not intrinsic to the problem. Talk about "core competencies" all you want; there may not be much of a difference between two companies and two divisions of the same company when it comes to how they do at satisfying their customers. Where things get ugly is in how they deal with their competitors -- but again, the barrier between two competitng companies is another one of those abstraction boundaries that might not, perhaps be sited in the "logical" place.

In that last argument there's one other scientifically-inspired habit of thought peeking out: the conservation argument implicit in the switch from talking about companies-that-do-things to things-that-get-done-by-companies. The point was that the set of tasks was the same, whether we grouped them but what sort of tasks they were or by what companies carry them out. To a mathematician, it was a rearranging of the terms in a sum; to a physicist, an application of Gauss' Law; an algorithmist might recognize the insight behind amortized analysis. To the programmer, this back-and-forth flip is second nature -- every day we need to switch from thinking about components and their interactions to thinking about the flow of a computation as it jumps from one component to another. Source files and class definitions reveal the former mode of thought; program traces and debugger sessions exhibit the latter.

There. I knew there had to be a reason why I got into this business.