Bullets Over Wrong Ways: Components, Functional Programming, and Essential Difficulties

In comments to my previous post, Wesner Moise says:

  • given today’s components, “why build vi?”;
  • the difficulty arising from software state “is a solved problem in functional programming”; and
  • suggests that the advances in graphics and networking that I’d acknowledged amount to a silver bullet.

I’m afraid he’s missing the central point regarding “essential” vs. “accidental” characteristics.

“Why build vi?”

The point of vi is not that Bill Joy rapidly wrote the first programming editor, it’s that he rapidly wrote a programming editor to meet particular and unforeseen requirements. Several editors (I think even emacs) already existed when he wrote vi, but Joy needed an editor that ran over a 300 baud connection.

We’re always building vi. Software development is never about the requirement you get in the elevator (“I need a text editor,” “I need an online store,” “I need to share data”), it’s always about the specific needs of the end user. Why build vi? Because the editor needs to work in the memory of a cellphone. Or over a satellite phone link. Or via an SSH connection. Or because we don’t want to retrain the users and they want an insert and a command mode. Or because we want to have piped program output insertable into the middle of a text file.

Brooks makes this as plain as possible in his essay:

I believe the hard part of building software to be the specification, design, and testing of this conceptual construct, not the labor of representing it and testing the fidelity of the representation. We still make syntax errors, to be sure; but they are fuzz compared with the conceptual errors in most systems.

The essential problem is not the representation we develop, it’s developing the concept of the system. The fault lies not in the source code, but in ourselves.

Functional programming solves the problem of complex state

Nonsense. Functional approaches have strengths, as I’ve discussed. However, they fall far short of solving the problems of complex state. The conceptual strengths of existing functional approaches diminish as the system grows: it is not an accident that object-orientation won out as the preferred method of conceptualizing larger systems. I am not saying that OOP is a panacea (not at all) or that state-carrying objects are a better approach to construction, but OOA&D is clearly more appealing and more successful in the broad marketplace of ideas than other approaches.

I personally believe that functional approaches may very fruitfully evolve in the coming years in both construction (where I think it’s clear that they will be important in the evolution towards manycore) and analysis and design (perhaps hybridized with certain aspects of OOA&D). But personal beliefs aren’t silver bullets.

Some silver bullets

Wesner again misses the forest for the trees when he clams I’ve acknowledged silver bullets for “development for an end computer (graphics programming) and development for a network of computers (network programming), there is a no order of magnitude improvement for any other form of computer.”

For one thing, by “graphics programming” what I meant was not GUIs, but 2D and 3D visualization. I meant things like the ability to present, light, and move through space 3D objects.

More generally, the point is, again, that libraries and frameworks advance but the conceptual challenges remain the same. Design-time form building, if anything, argues for Brooks, not against him: “friends don’t let programmers design interfaces” and all that.

Here’s an example of the fundamental issue: Eric Sink’s woodworking application. The whole issue of “silver bullets” boils down to whether you think the problem is creating a 3D view or writing an application that linearizes the steps in a woodworking project. Is coding the views 10 times simpler than it would be if he were using DirectX? Just about. Is DirectX 10 times simpler than writing your own projections? Yep. So for 3D views, you have substantial advances: multiple generations, programming becoming faster not just by integral factors, but by orders of magnitude. Yes, I think that’s fair.

But… what about the “steps” part of things? How much more capable is this program at creating a list of materials than was the copy of Autocad I used twenty years ago? A little? A lot? I dunno’. But I guarantee you that there is not an order of magnitude difference between the time Eric spent representing those domain rules in whatever-language-he-used and the time it would have taken to express the same design rules in OCaml or other functional language and the time it would have taken to express those rules in AutoLisp (assuming the Eric was fluent in all of them).

Creating a representation of a conceptual system is the essential task of programming. Developing a conceptual system that can express something useful is the essential task of software development.

Once upon a time, I used to make a big deal about that distinction– at Computer Language, I forbade the use the term “programming” or “programmer” to describe our subject matter. When I left publishing, I purposefully embraced the opposite swing of the pendulum: I called myself a “programmer” and intentionally embraced in my writing those aspects of our job.