Lisp philosophy1
by TANAKA Tomoyuki2
``There are two kinds of computer languages: Lisp and all other languages."I would like to summarize the appeal that Lisp has had for me. I've never seen an essay focusing on Lisp philosophy, with the possible exception of [Greenberg], which emphasizes Lisp's ``object" concept. First of all, let me state that by ``philosophy behind Lisp" I don't mean what John McCarthy had in mind when he designed LISP 1.5 in the early 1960s. What is much more important to me is to get at the core of attraction that Lisp has possessed over Lisp enthusiasts around the world for decades.
How can we make it easier on the programmers? One sure way is by letting them free their minds from petty syntactic details. Some computer languages make a big deal out of exact placement of semicolons and operator precedence. Lisp has parentheses, which take care of most of syntax. One never has to memorize operator precedence because it's all there in the parentheses.
Syntax and operation of Lisp are further simplified because Lisp provides most of its facility as functions, which share these traits:
What can not be provided as functions (mostly control structure constructs) are provided as special forms and macros, which have their own peculiar syntax, but an effort is made to reduce their number.
Time and time again we find in Lisp a spirit to avoid arbitrary rules, which are caused by hardware limitations or otherwise. There is virtually no upper limit on the number of characters one can use in variable and function names, nor is there an upper limit on the largest integer that the system can handle (the bignum facility).
Compare this with FORTRAN, in which conventions that made things convenient in the punched-cards days now cause programmers' inconvenience and irritation: a program line must begin at a certain column; ISUM is an integer, whereas SUM is a real; everything has to be written in upper case; etc., etc. ad nauseum.
It's much easier to debug one's code if the code itself can be run, instead of the compiled object code. So Lisp provides the interpreter. Users' concern caused by intermixing of compiled and interpreted code must be kept to a minimum, so the interperter should faithfully simulate the operation of the compiler.6 When an error occurs, it would be nice if a user can see exactly what went wrong by examining call history and variable bindings in that context, then furthermore change the function definition in question and resume execution.
All these demands are realized in Lisp, summed up as these four points in [Gabriel, Page 11]: (1) functions may be defined on the fly by the user, (2) functions can be compiled separately, (3) compiled and interpreted calls can be intermixed, and (4) when an error or interrupt occurs, the stack can be decoded within the context of the error.
Although Gabriel calls these points the ``Lisp philosophy", I feel that the Lisp philosophy runs much deeper, and these features of Lisp, though of crucial importance to Lisp, are but manifestations of deeper characteristics.
Lisp's user assistance does not stop here. A readable and complete manual helps programmers immensely. Without such a manual, programming is like playing an adventure game: ``Let's try and see if this works ...". On-line documentation is also important, because when programming at a terminal, it's easier to type (help func-xxx) than looking up func-xxx in a manual.
You will agree with me that, when taking all these things into account, writing a program which is hard to read is not in tune with the philosophy of Lisp. With pretty printer, documentation strings, and constructs like defstruct, Lisp encourages well-commented and readably indented programs, and as a result, Lisp programs usually are very readable, just as C programs are not. I find tricky programs written by hackers that magically get the job done completely against the philosophy of Lisp.
There is another aspect to the philosophy of Lisp: the spirit of compromise that heeds the practical side of a programming language. This must be based on the conviction that a clean and beautiful language can be practical too.
Many new languages have been proposed by the researchers of the ``functional programming" school. These languages are important to computer science, of course, because they explore future directions of computer languages. But I've never heard of a truly practical system being written in a functional language: such as an operating system, a text editor, an expert system, or a compiler for another language. All of these things have been written in Lisp. Optional declarations on variable types, function use, etc. enable optimizing compilers to produce code comparable to other language compilers in speed, making Lisp a practical language.
One reason for Lisp's constant attention to power was its use as a system description language for itself. We were all impressed when we first saw the definition of eval and apply in LISP 1.5 Programmer's Manual [McCarthy, et al.]. What struck me was the recursivity in its self-description. Lisp-in-Lisp then served as an educational tool [Nakanishi] [Winston and Horn], but later on, real Lisp systems written in Lisp began to appear. Reading the Spice Lisp compiler [Spice], I was struck once again with that awesome self-documentation of its operation. The size of Common Lisp is not a gigantic mishmash, but rather a minimum solution for an equation called self-description.
Common Lisp was designed with compatibility with other Lisps in mind. Because of this, it is not as clean as it could be. I'm not sure if facility like multiple values and closures are worth the added complexity of the system. When I program, nestedly bound special variables are the primary source of bugs. Gargantuan format and the sharp sign macro are against the Lisp philosophy, and should be outside the language specification. Although it doesn't bother me, I do notice that it is overly English-centric. If the function name array-has-fill-pointer-p doesn't bother you, see that it's not that much different from this-is-an-array-that-comes-with-a-fill-pointer-p. Maybe this is one of the reasons Europeans want another standard.
Still, I am happy with Common Lisp. It is clearly the closest thing that came to my Lisp philosophy.
You will see that what I have in mind is not exactly Common Lisp or any Lisp, but more importantly a language with all these aspects I described: A powerful and beautiful computer language permeated with the spirit to make it easier on the programmers. Let me call such a language a ``LISP", an acronym for ``Language Imbued with Support for Programmers". Then this question comes to my mind: Is Lisp the only LISP, or could there be other LISPs?
Here is my answer: Lisp is so far the only LISP I know. There could be others in the future, but if there were a LISP which is not Lisp, it would have to be remarkably similar to Lisp.
Three more items that helped me enjoy Lisp more
Some descriptions of the author's technical involvement with Lisp
This document was generated using the LaTeX2HTML translator Version 98.1p1 release (March 2nd, 1998)
Copyright © 1993, 1994, 1995, 1996, 1997, Nikos Drakos, Computer Based Learning Unit, University of Leeds.
The command line arguments were:
latex2html -show_section_numbers -split 0 -address LP.tex.