Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!swrinde!zaphod.mps.ohio-state.edu!wuarchive!uunet!decwrl!pa.dec.com!src.dec.com!meehan From: meehan@src.dec.com (Jim Meehan) Newsgroups: comp.lang.lisp Subject: Greatly exaggerated reports of Lisp's demise Message-ID: <1991Feb12.122415.23035@src.dec.com> Date: 12 Feb 91 20:24:15 GMT Sender: news@src.dec.com (News) Organization: DEC Systems Research Center Lines: 94 Originator: meehan@jumbo.pa.dec.com I'm amazed at the recent spate of Lisp-bashing on comp.lang.lisp, and how few replies there have been either to defend Common Lisp or to explain misunderstandings in the complaints. CL is not without its faults, but it ain't COBOL, either ;-) At the company where I used to work, we used UCI LISP for a year, T for a couple of years, and Common Lisp for the past six years. CL hasn't died. On the contrary, it survived on a large scale where lots of other dialects did not, including UCI LISP, about which I can speak authoritatively, and maybe Franz Lisp, about which I cannot. Once T got call/cc, it became a syntactic variant of Scheme, so from my perspective, there were only two Lisp dialects of interest: Common Lisp, which was the dialect of choice for an industrial-strength, commercially supported Lisp, and Scheme, which was small and elegant but not yet adequate for large-scale commercial software. (Je ne parle pas ML.) Erann Gat asked why the CL committee decided "not to include call-with-current-continuation." I wasn't on the committee, but my impression is that 1984 Common Lisp predates call/cc, or at least it was thought to be difficult or expensive to implement (or that most CL programmers would abuse it :-), but it would be interesting to hear directly from them. Of course, what's difficult one year may be less difficult the next; witness ephemeral GC on stock hardware. I don't know why call/cc didn't make it into CLtL II. Barry Margolin says "it wasn't demmed necessary." In our applications (30% natural language processing, 70% systems programming), I'm not sure we would ever have used call/cc, but we lived and breathed closures, so I think the commitee made the right choice. But it would not trouble me to see call/cc added. It does trouble me to see the new LOOP macro added. It's yet another embedded sublanguage (FORMAT is another one, perhaps "the" other one). But maybe the obvious thing for the committee to do is to formalize the notion of libraries: collections of functions, macros, and global variables that serve particular needs, so that if you don't want them, you don't pay for them. As an AI programmer, I'd have relegated all those math functions (branch cuts, etc.) to some distant shore, too. The object system is crucial; the pretty-printer is not. On the other hand, several commercially available implementations provide a system-building option for excluding the pieces of CL that you don't use or want. Of course, if you write code that does (funcall (intern (format nil ...))) or (eval ...) or (compile ...) at runtime, all bets are off, but then you're not writing commercial code :-). Of course, having the wealth of choices for writing the same code is not always a good thing. We had an in-house "Common Lisp style sheet" that included, among other advice, a list of "forbidden forms," whose use you would have to justify to the company's Programming Czar, who almost never let you get away with anything. The Forbidden List included DO*, RPLACA, RPLACD, PROGV, any C{A,D}R function with more than two letters between the C and the R (and those only for plists), and others. There was also a Restricted-Use List, including APPEND, PROGN, BLOCK, etc., where there were specific cases where they could be used, but not elsewhere. The programmers liked this. It promoted useful discussion, especially among Lisp newcomers, it enhanced readability, and it spared them age-old hassles. On the issue of REQUIRE, we viewed this as a simple mechanism appropriate for simple programs. With large-scale programming, you need a whole suite of program-management tools, so I don't think that the committee was being "a little unfriendly" as Vance Maverick notes, but simply realistic. We designed and built our own, and stopped using REQUIRE completely. Defsystem was just the beginning; the majority of the code was for tracking the various dependencies within and between "systems": read-time, compile-time, load-time (both compiled and interpreted), eval-time, and run-time dependencies. I don't know how many other shops built similar elaborate environmental tools, but I'm not surprised there's nothing in the CL standard, because there probably isn't much general agreement based on a lot of real-world experience in this area. Maybe some day ... On the issue of finding out what a class' instances are, or what slots a structure has, I'll take the hard line and say there's good reason NOT to provide that information. As a couple of people have pointed out, you can build classes that do keep track of their instances, but then you have to worry about GC. In other words, you normally don't want to pay for this. On a slightly more abstract level, consider that it is often desirable to make instances and structures as lightweight as possible. For example, you'd hardly want to keep track of all the numbers in your program; you assume that even if they're not "immediate" data, they won't cost you much, and they'll go away after you've stopped using them. All objects should share this philosophy, especially when performance is an issue. If you need to fiddle with the underlying representation, you're doing something strange, so it's no wonder that constructing slot-names at run-time is awkward; it should be. (I *told* you this was the hard line.) Jim Meehan