Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!linus!philabs!cmcl2!harvard!topaz!hedrick From: hedrick@topaz.RUTGERS.EDU (Charles Hedrick) Newsgroups: net.lang.lisp Subject: Re: Against the Tide of Common LISP Message-ID: <5194@topaz.RUTGERS.EDU> Date: Sat, 21-Jun-86 17:09:27 EDT Article-I.D.: topaz.5194 Posted: Sat Jun 21 17:09:27 1986 Date-Received: Mon, 23-Jun-86 03:15:14 EDT References: <1311@well.UUCP> <3827@utah-cs.UUCP> Organization: Rutgers Univ., New Brunswick, N.J. Lines: 77 In general, I agree with Shebs' response. A couple more things: It was realized when CL was designed that it was larger and would take more time to implement correctly than Lisp 1.6. The designers took the view that this was a one-time price, and that it was better for each manufacturer to spend a few more man-hours once if it would save their users from then on. This is probably right. There is nothing in CL that makes a fast interpreter impossible. There is plenty that makes it difficult. The DEC-20 implementation has an interpreter that is reasonably fast. The major speed problem is caused by lexical bindings. Simple implementations are low because they have to put all of the bindings on lists, thus replacing push by CONS and pop by a GC. The DEC-20 implementation prevents this by putting the data on the stack where possible, and copying into the heap in the rare case of someone asking for an actual closure object. There are similar tricks for the other difficulties. The resulting interpreter is not as fast as an interpreter for Lisp 1.6, but the difference is not enough to cause trouble. What we get for all of this pain is an interpreter whose binding semantics are compatible with those of the compiler. I spent several years supporing UCI Lisp. Many users never compiled code because when they compiled it, it stopped working. The primary problem was that the binding semantics changed, and they suddenly had to declare lots of things "special". In my opinion it is worth a man-month from each implementor to get rid of this problem. Actually, I voted against this feature of CL. I would have preferred that the compiler use "special" all the time. (We did this to a compiler for a variant of UCI Lisp. It helped things immensely.) It was turned down, I think for two reasons (1) This makes the compiler pay in efficiency. Adding lexicals to the interpreter makes the interpreter pay in efficiency. Since you compile when you want speed, it makes sense to pick the definition that is fastest for the compiler (2) There are a number of people who believe that lexical binding is safer, and who want to use lexical closures. A number of things said in the original posting are just wrong. I can think of no way to implement SET so it works for lexically-bound variables in compiled code. There are such things in UCI Lisp. They are called SPECIAL. I am reasonably sure that SET does not work with them. If the manual fails to say this, it is a documentation error. The primary reason for SETF is for convenience in writing code that writes other code. Examples are macros and code to implement flavors or other structured-programming constructs. For all such purposes, it is very handy to be able to reverse the definition of a component. That is, suppose we have a list, and we refer to its components as (CAR X), (CADR X), and (CADDR X). We want to be able to change the components uniformly by doing (SETF (CADR X) ...) instead of having to transform this into (RPLACD (CAR X) ...) If a person is writing the code, this may not be so important (though it is a very common bug for a person to write (RPLACA (CDR X) where he meant (RPLACD (CAR X)). However researchers are now beginning to depend upon high-level tools. We want a macro or other code-constructor to be able to take the definition of a component and be able to build code to change the element by sticking SETF around it. It is precisly such large systems as KEE that make many of the complexities of CL necessary. Personally I would have wished for CL to be smaller. As the manager of a number of timesharing systems, I cringe at a Lisp where each user takes 8 MB of swap space. (Our DEC-20 implementation does better than this. We were very careful to allow as much to be shared as possible. The implementation that takes 8MB per user was designed primarily for single-user workstations. Unfortunately we have a situation where we want 4 people to use it.) But I have no question that the things that made it bigger will save a number of people time, and facilitate the building of large systems. My sense of things is that CL implementations, particularly after they have been in use of a few years and get tuned, will be about as fast as other Lisps. However they will be enormous. The attitude of the CL designers was "memory is cheap". If you envision CL as being used for large systems on single-user systems, this is right. That's certainly what the CL designers had in mind. Those of us trying to run large student timesharing systems may have some problems with this. It may be that for us a subset will prove helpful. Or the vendors that supply timesharing systems may simply be more careful in their implementations, so that all of the code can be shared.