The more I think about Worse is Better, the more my logical circuits start to smoke. And I wonder why I can't wrap my automated deduction heuristics around it.
Then I think "Of course! It's a logical contradiction."
Duh.
But more seriously---isn't Lisp worse---and therefore better?
I mean, Lisp seems to embody the worse-is-better mentality more than most languages I know. Perl might actually be the worst---and therefore the best. But that's beside the point.
But Lisp is exactly the language used as the example of better-is-better (also known as "The Right Thing").
Ok. You might be thinking "this guy's got a mismatched parenthesis in his head". But, you've read this far, so I figure you'll hear me out.
Ok. What's more worse-is-better:
Am I missing something here? I mean, how can you get more The Right Thing than the standard waterfall design?
And how can you get more worse-is-better than coding up a simple language layer---then covering up its worsiness with a new language layer?
Reasons why Lisp is worse-is-better:
Right. So I do get the whole worse-is-better thing. For instance, no standard socket library exists in Common Lisp because there was no The Right Thing for that at the time of standardization. I get it. I get it.
So, is it really about worse now is better than better later? Wow. That made my head spin.
Let's look at it a different way:
Richard Gabriel's formulation is paraphrased (and simplified):
I must be missing something. Whenever I look at these two lists, I think: Oh, The Right Thing, that's all those static languages, where the compiler tells you what to do. You have to do all sorts of designs up front because it's hard to experiment.
Worse-is-Better---that's for dynamic languages (like Lisp) where you can write simple programs that don't require a lot of up-front design. You can just save everything in a List---no need to create a class, define its interface, etc.
But Lisp is explicitly put into The Right Thing category!
Richard Gabriel:
The worse-is-better philosophy means that implementation simplicity has highest priority, which means Unix and C are easy to port on such machines.
I agree that Unix and C are relatively easy to port. But I can't figure out how a bootstrapped language (like Lisp) is hard to port. In theory, there are only a handful of operations that need to be implemented before the whole system can build itself.
And it continues:
There is a final benefit to worse-is-better. Because a New Jersey language and system are not really powerful enough to build complex monolithic software, large systems must be designed to reuse components. Therefore, a tradition of integration springs up.
Ok, I must be crazy: is he suggesting that any system where huge, monolithic pieces of software are created is The Right Thing? Does that mean Windows? Or is Windows just not in either of these two camps?
A "tradition of integration springs up" in Worse-is-Better---and what could be more integrated than "everything's a list"?
Some possible explanations for my confusion:
Maybe I don't understand the ideas. But I think I do. Maybe software has changed. It could be that Lisp, in prior incarnations, was used differently. And software has changed. Perhaps also I'm looking at it unfairly: all of the design work that went into Common Lisp makes writing simple programs easy---but that simplicity comes from having a simple interface---definitely a The Right Thing idea.
My whole feeling on this is based on one simple idea: that in Lisp, you can do incremental development in a way you can't do in a language like Java. In Lisp, I very often write a language layer in less than 100 lines of code, that is worse is better. It doesn't handle nearly every case. It does some things wrong. Basically, the only thing it's got is simplicity.
And then I write another layer on top that fixes some of the problems. And then another layer. And eventually, I have a system that does The Right Thing---or enough of The Right Thing for my purposes.

(defun open-file (filename) . . .)
(defun close-file (stream) . . .)
Simple implementation, but it introduces some interface complexity: as a programmer, you have to remember to close the file when you're done with it. After using it a while you realize what you should write next . . .
(defmacro unprotected-with-open-file (var filename &body body)
`(let ((,var (open-file ,filename)))
,@body
(close-file ,var)))
Now you don't have to remember---the language will do it for you. But what if the program throws an exception? Your file won't get closed---unless:
(defmacro protected-with-open-file (var filename &body body) . . .)
You get the picture? I suspect that these ideas---and the associations with programming languages---need to be revisited.
Comments
Integrated?
What is meant by a culture of integration is not that everything is universally expressed, as in Lisp. What is meant is that complex pieces of software expose consistent, (supposedly) well documented interfaces. The physical manifestation of the interface can be *anything*, so long as it is documented and adhered to by the component you're using. Ideally, the interface is so well documented that you don't even need a compiler for the language used to write the component in the first place. You can use Lisp to write code, but maybe you link against a library I wrote in Forth, or perhaps APL, or dare I say it, COBOL.
This simple observation gives rise to the ENTIRE software industry as it's espoused today. Because everything is abstracted behind Application Binary Interfaces (ABIs; usually enforced by the OS) and Application Programmer Interfaces (APIs; enforced by the component authors and compilers), you're free to "ship" a software product without including its source code, which means you can charge MONEY for doing it. There is an incentive to sell software, rather than sell support for it.
With Lisp, Forth, Smalltalk, et. al., all you have is source -- the concept of "object code" simply does not exist. Hence, without intermediate binary representations of software components, there can be no means of distributing your work without also distributing its source code. The profit motive for software development disappears, and thus so too does the public support for those languages. Expressivity and productivity be damned. Only those who embrace the idea of offering software-related services work with these languages; those who offer software-as-a-product won't be caught dead using them, for it compromises their entire business model.
Great explanation
I like your explanation for the incentive to use binary distribution of programs. It's one I haven't heard before. Maybe Lisp needs a way to close off the distribution. It's a good thing to think about when considering the roadblocks to more massive adoption of Lisp.
Thanks.
You can distribute without
You can distribute without source, just dump an image. Some implementations will even produce native executables for you.
Post new comment