This essay borders on the profound. Ellen Ullman shows why a new generation of programmers cannot understand the original code, and why members of the older generation will not ride in on white horses to fix it. The original code no longer communicates to those who wrote it, let alone to those who have patched it. Her words are chilling:
"A world floating atop a sea of programs we've come to rely on but no longer truly understand or control. Code and forget; code and forget: programming as a collective exercise in incremental forgetting."
We're trapped: college graduates, MBA's, input-output whizzes on spreadsheets that are not compliant, paper-pushers, deal-doers -- all of us. We live in terms of a vast array of digital complexity that no one knows and no one can fix, now that its inherently flawed design is widely perceived. This digital complexity has been used by entrepreneurs to cut costs to the bone. What has happened is encapsulated in Wal-Mart's slogan: "We sell for less." Layers upon layers of ever more complex code has re-shaped the institutional complexity that sustains our lives and our way of life. This high tech complexity -- digital and institutional -- has less than 20 months to go.
James Carville, meet Adam Smith: "It's the division of labor, stupid."
This is from SALON (May 12).
* * * * * * * * * *
I used to pass by a large computer system with the feeling that it represented the summed-up knowledge of human beings. It reassured me to think of all those programs as a kind of library in which our understanding of the world was recorded in intricate and exquisite detail. I managed to hold onto this comforting belief even in the face of 20 years in the programming business, where I learned from the beginning what a hard time we programmers have in maintaining our own code, let alone understanding programs written and modified over years by untold numbers of other programmers.
Programmers come and go; the core group that once understood the issues has written its code and moved on; new programmers have come, left their bit of understanding in the code and moved on in turn. Eventually, no one individual or group knows the full range of the problem behind the program, the solutions we chose, the ones we rejected and why.
Over time, the only representation of the original knowledge becomes the code itself, which by now is something we can run but not exactly understand. It has become a process, something we can operate but no longer rethink deeply. Even if you have the source code in front of you, there are limits to what a human reader can absorb from thousands of lines of text designed primarily to function, not to convey meaning. When knowledge passes into code, it changes state; like water turned to ice, it becomes a new thing, with new properties. We use it; but in a human sense we no longer know it.
The Year 2000 problem is an example on a vast scale of knowledge disappearing into code. And the soon-to-fail national air-traffic control system is but one stark instance of how computerized expertise can be lost. In March, the New York Times reported that IBM had told the Federal Aviation Administration that, come the millennium, the existing system would stop functioning reliably. IBM's advice was to completely replace the system because, they said, there was "no one left who understands the inner workings of the host computer."
No one left who understands. Air-traffic control systems, bookkeeping, drafting, circuit design, spelling, differential equations, assembly lines, ordering systems, network object communications, rocket launchers, atom-bomb silos, electric generators, operating systems, fuel injectors, CAT scans, air conditioners -- an exploding list of subjects, objects and processes rushing into code, which eventually will be left running without anyone left who understands them. A world full of things like mainframe computers, which we can use or throw away, with little choice in between. A world floating atop a sea of programs we've come to rely on but no longer truly understand or control. Code and forget; code and forget: programming as a collective exercise in incremental forgetting.
Every visual programming tool, every wizard, says to the programmer: No need for you to know this. What reassures the programmer -- what lulls an otherwise intelligent, knowledge-seeking individual into giving up the desire to know -- is the suggestion that the wizard is only taking care of things that are repetitive or boring. These are only tedious and mundane tasks, says the wizard, from which I will free you for better things. Why reinvent the wheel? Why should anyone ever again write code to put up a window or a menu. Use me and you will be more productive.
Productivity has always been the justification for the prepackaging of programming knowledge. But it is worth asking about the sort of productivity gains that come from the simplifications of click-and-drag. . . .
And as prebuilt components accomplish larger and larger tasks, it is no longer only a question of putting up a window or a text box, but of an entire technical viewpoint encapsulated in a tool or component. No matter if, like Microsoft's definition of a software object, that viewpoint is haphazardly designed, verbose, buggy. The tool makes it look clean; the wizard hides bad engineering as well as complexity.
In the pretty, visual programming world, both the vendor and programmer can get lazy. The vendor doesn't have to work as hard at producing and committing itself to well-designed programming interfaces. And the programmer can stop thinking about the fundamentals of the system. We programmers can lay back and inherit the vendor's assumptions. We accept the structure of the universe implicit in the tool. We become dependent on the vendor. We let knowledge about difficulty and complexity come to reside not in us, but in the program we use to write programs.
No wizard can possibly banish all the difficulties, of course. Programming is still a tinkery art. The technical environment has become very complex -- we expect bits of programs running anywhere to communicate with bits of programs running anywhere else -- and it is impossible for any one individual to have deep and detailed knowledge about every niche. So a certain degree of specialization has always been needed. A certain amount of complexity-hiding is useful and inevitable.
Yet, when we allow complexity to be hidden and handled for us, we should at least notice what we're giving up. We risk becoming users of components, handlers of black boxes that don't open or don't seem worth opening. We risk becoming like auto mechanics: people who can't really fix things, who can only swap components.
It's possible to let technology absorb what we know and then re-express it in intricate mechanisms -- parts and circuit boards and software objects -- mechanisms we can use but do not understand in crucial ways. This not-knowing is fine while everything works as we expected. But when something breaks or goes wrong or needs fundamental change, what will we do but stand a bit helpless in the face of our own creations?