This is the beginning of what what we hope will become the canonical Common Lisp FAQ. Or, possibly, it the result of yet another in the seemingly endless series of efforts to produce such a canonical FAQ that will, like the others, fizzle after an initial burst of energy devoted largely to converting parts of older FAQs into some new better format. There has been on-again, off-again effort on this FAQ which is—as of 7 March 2007—on again. If you have questions or suggestions email peter@gigamonkeys.com or see http://wiki.alu.org/Common_Lisp_FAQ for more information on the project that is producing this FAQ. (Last updated: 2007-03-12T20:45:54+7:00)
The Online Tutorial page at CLiki lists a number of online tutorials, books and articles. (The CLiki is a wiki written in Common Lisp and devoted to providing information related to Free and Open Source software implemented in Common Lisp. The other main Lisp wiki is the wiki run by the Association of Lisp Users which lives at http://wiki.alu.org/.) Other resources that you may find useful as you start Lisping are:
Practical Common Lisp. The online version of the best-selling (as these things go) Common Lisp book. This book is aimed particularly at folks who already know how to program in some other language and want to get up to speed on Common Lisp as quickly as possible.1 For other books, some of which are also available online, see the next question.
The Common Lisp HyperSpec An HTML version of the official ANSI standard for Common Lisp prepared by Kent Pitman, the standard's editor. The HyperSpec is not meant as a tutorial but is an invaluable reference.
Planet.Lisp Aggregator for Lisp related blogs.
Common-Lisp.net A sort of Sourceforge (but better) for Common Lisp projects.
Peter Seibel's Practical Common Lisp, a.k.a. PCL, is a good starting place if you already know how to program in some other language. It's available online at http://www.gigamonkeys.com/book and in dead tree form from Apress. It has been widely praised and won a Productivity Award in the technical book category of the 16th Annual Jolt Product Excellence Awards. PCL covers almost all aspects of the language and focuses on how to actually put them together to build non-trivial programs. The book includes several "practical" chapters that walk the reader through building programs such as a Bayesian spam filter and a streaming MP3 server.
Paul Graham's ANSI Common Lisp is another popular introductory text, although it has a more textbook-ish feel and, published in 1994, may strike some readers as a bit old-fashioned. You can order a copy from Amazon, or check out your local library—unlike many other Lisp titles, there's a chance you might find it there.
The Structure and Interpretation of Computer Programs by Abelson and Sussman, commonly referred to as SICP, is a classic computer science text used for introductory computer science classes at places like MIT and UC Berkeley. It uses Scheme rather than Common Lisp but is more about a way of thinking than a specific technology so that difference shouldn't matter a great deal. It's a brilliant book that should be tackled by all serious Lispers at some point. The full text is available online from MIT at http://mitpress.mit.edu/sicp/ as well as a video lecture series by Abelson and Sussman at http://swiss.csail.mit.edu/classes/6.001/abelson-sussman-lectures/.
Paradigms of Artificial Intelligence Programming by Peter Norvig, commonly referred to as PAIP, is another classic. While demonstrating how to use Common Lisp to implement a number of important Artificial Intelligence algorithms it provides an excellent guide to the craft of programming in general and to writing efficient and tasteful Common Lisp in specific. The book is not available online but it's web site is at http://www.norvig.com/paip.html.
On Lisp is Paul Graham's advanced Lisp book. It's probably not the best first Lisp book but is an eye-opening introduction to a number of advanced Lisp techniques that every master Lisper should have in their toolkit. Though out of print, it is available online at http://www.paulgraham.com/onlisptext.html.
Ask a related question, you get a related answer:
Ranked in rough order of difficulty2:
To learn the basics:
Practical Common Lisp, by Peter Seibel is the most recent Common Lisp book, published in 2005.
Lisp, by Winston & Horn
Structure and Interpretation of Computer Programs ("SICP") (Actually about Scheme, but useful to learn how to think in Lisp)
ANSI Common Lisp, by Graham
The HyperSpec, as appropriate
Learning why macros are so cool / Advanced Lisp:
Structure and Interpretation of Computer Programs ("SICP") (Actually about Scheme, but useful to learn how to think in Lisp)
On Lisp, by Graham
The HyperSpec, as appropriate
Learning OOP The Lisp Way:
The HyperSpec, as appropriate
Learning Lisp Style
Writing a Lisp interpreter or compiler
Lisp in Small Pieces ("LiSP")
The HyperSpec, as appropriate
Oh, and did we mention, the HyperSpec?
There are a number of free (in both the "gratis" and the "libre" senses) Lisp environments:
link{
ABCL (Armed Bear Common Lisp) is an implementation of ANSI Common Lisp that runs in a Java virtual machine. It provides a runtime system, a compiler that compiles Lisp source to JVM bytecode, and an interactive REPL for program development. It runs on any platform that support Java 1.4 (or later), including Linux, Windows, and Mac OS X. It is, by the author's admission, a relatively young implementation, and has some notable limitations in its CLOS implementation. ABCL is licensed under the GNU GPL, with a special linking exception.
CLISP provides both an interpreter and bytecode compiler, and runs on Windows, and most flavours of Unix including OS X. It provides excellent Unicode support. CLISP is licensed under the GNU GPL.
CMUCL (Carnegie Mellon University Common Lisp) provides an interpreter and optimizing, native-code compiler and runs on a few flavours of Unix (including x86/FreeBSD, x86/Linux and sparc/Solaris). CMUCL can be difficult to compile; it requires itself to build itself, and bootstrapping is an issue. CMUCL is mostly public domain software, though portions are under an X-like or BSD-like licence.
ECL (Embeddable Common Lisp) is an implementation of Common Lisp running on at least x86, Sparc and PPC architectures, under Linux, FreeBSD, Solaris, MacOSX and Windows (using the cygwin environment). ECL provides a bytecode compiler and can also compile to C source. ECL is licensed under the GNU LGPL.
GCL (GNU Common Lisp) was developed in conjunction with a few large programs, most notably the computer algebra system Maxima. It was originally an implementation of the version of Common Lisp described in the first edition of Common Lisp the Language and did not aim for ANSI compliance. In recent years, however, the GCL developers have begun working toward fuller compliance with the ANSI standard. GCL is licensed under the GNU LGPL.
OpenMCL is an opensourced Common Lisp implementation derived from MCL 4.2, and runs on MacOS X/PPC, Linux/PowerPC, and Linux and Darwin on x86-64. It includes a bridge to the Cocoa framework that allows convenient manipulation of Objective C objects in CLOS. OpenMCL is licensed under the GNU LGPL.
Poplog is an incrementally-compiled runtime that includes a Common Lisp implementation, an ML implementation and a Prolog implementation, all cohabiting in the same image. It is licensed under an XFree86-style license. Poplog CL is not actively maintained.
SBCL (Steel Bank Common Lisp) is a fork of CMUCL aimed at improving maintainability by fixing the bootstrapping issues involved in recompiling. It can be compiled using any ANSI compliant Common Lisp. It runs on many Unix and Unix-like systems (including Mac OS X). SBCL is licensed in a similar fashion to CMUCL: mostly in the Public Domain, with some BSD-like and MIT-like portions.
Over time there have been quite a few vendors of commercial Lisp systems. The following are the most active:
Franz Inc's Allegro Common Lisp is a fine lisp development environment that runs and almost all platforms. See their website for more details.
Corman Lisp is a compiler for Windows 95/98/2000/ME/NT, with integration with the Windows API. It is free for personal use and fairly inexpensive compared to other commercial lisps otherwise.
LispWorks is the main product of the company of the same name. It is available in a variety of editions including a free (as in beer) personal edition with a few limitations on its use. LispWorks also provides Liquid Common Lisp, a.k.a. LCL, another Common Lisp with a slightly different set of extensions above the ANSI specification than LispWorks (the Lisp). Unless you are already using LCL, if you are going to use a LispWorks (the company) product, you probably want LispWorks (the Lisp).
A commercial, implementation of Common Lisp for the Macintosh. Digitool has not shown a lot of signs of life lately; their web page list of "What's New" was last updated in 2005.
An implementation of Common Lisp that can take advantage of SMP machines. Runs on various Unixes and was originally based on the CMUCL code base.
Not necessarily. The simplest possible development Lisp environment consists of a text editor and an xterm. Since the language standard provides facilities for dynamically loading and compiling files of Common Lisp source code and since virtually every Common Lisp implementation provides an interactive Read-Eval-Print Loop (REPL) you can get a taste of Common Lisp's interactive development style by opening your source files in a text editor of your choosing and then starting Lisp at the command line (e.g. in an xterm). From there you can edit your code in the editor, save it, and then LOAD it from the REPL and test it interactively. You can also write code directly in the REPL but then you'll have to cut-n-paste it into your editor if you want to save it.
However, most Lispers would consider this is a pretty primitive way to work. A good Lisp development environment, for instance, provides a way to compile and load files and individual expressions (such as function definitions) from within the editor at the press of a key (er, or a couple key chords anyway; this is Emacs we're talking about). In this kind of environment you use the REPL for running code but you rarely write code in the REPL that then needs to be cut-n-pasted back into a file since you write all your interesting code in a file to start with. Tighter integration also allows the editor to do things like ask the Lisp implementation where a particular function definition came from, allowing you to jump from the name of a function to it's definition at the press of a key. Likewise, when you land in the debugger it's nice to be able to press a key and jump to the source code of a particular stack frame in the backtrace.
To get this kind of rich development environment you can go one of two routes: use one of the all-in-one integrated development environments provided by commercial Lisps such as Allegro Common Lisp and LispWorks or use an editor that is capable of bidirectional interactions with Lisp. At the moment the only editor really capable of doing that is Emacs. (Note: this may change eventually as another CL Gardeners' project is working on integrating Embeddable Common Lisp into the vi-alike, Vim, with an eye toward allowing vi users to have interact with Lisp in the same way Emacs users do.) However there is no need to learn all of Emacs just to do Lisp programming; if you spend a few minutes working through Emacs's built-in tutorial (available at any time by hitting Control-h followed by t) you'll know all you need to know to get started. A good way to get started with Lisp and Emacs if you aren't already familiar an Emacs user, is to grab a Lispbox distribution from http://www.gigamonkeys.com/lispbox/; Lispbox provides an prepackaged installation of Emacs, plus a Common Lisp implementation, plus SLIME, the Superior Lisp Integration Mode for Emacs.
Vim is lisp-aware. See Larry Clapp's article at http://cybertiggyr.com/gene/15-vim/.
See also http://www.vim.org/scripts/script.php?script_id=221 for the closest thing to SLIME for Vim: VILisp. VILisp basically automates the process of cut-and-paste from Vim into Lisp, and adds a few bells and whistles, but that's about it.
See also the Gardeners project slim-vim, which has linked Vim with an implementation of Common Lisp called ECL, and is working towards integration with SLIME.
Eclipse has a Lisp plugin floating around.
J has an embedded Common Lisp in it (written in Java).
In Zen in the Martial Arts, by Joe Hyams, Joe relates the following story, from when he first began training with martial arts master Bruce Lee:
"Let me tell you a story my sifu [teacher] told me," Bruce said. "It is about the Japanese Zen master who received a university professor who came to inquire about Zen.
"It was obvious to the master from the start of the conversation that the professor was not so much interested in learning about Zen as he was in impressing the master with his own opinions and knowledge. The master listened patiently and finally suggested they have tea. The master poured his visitor's cup full and then kept on pouring.
"The professor watched the cup overflowing until he could no longer restrain himself. 'The cup is overfull, no more will go in.'
"'Like this cup,' the master said, 'you are full of your own opinions and speculations. How can I show you Zen unless you first empty your cup?'"
Bruce studied [Joe's] face. "You understand the point?"
"Yes," [Joe] said. "You want me to empty my mind of past knowledge and old habits so that I will be open to new learning."
"Precisely," said Bruce. "And now we are ready to begin your first lesson."
Empty your cup. Try to learn Lisp on its own terms, rather than with the unconscious assumption that it should be just like That Other Language you know, only slightly different.
Lisp's most superficially obvious characteristic is its extensive use of parentheses to delimit expressions. Unfortunately many would-be Lispers get stuck on the parentheses and never get far enough into Lisp to see that they are a feature, not a bug. The reasons for getting stuck are varied: for some, their parenthesis-aversion may be rooted in bad associations with parentheses picked up while using infix-based languages and dealing with overly-complex expressions like this:
(((x ^ w) * (p ^ (t + 2))) + ((a + x) ^ (b + x)))
Erik Naggum, a once frequent contributor to comp.lang.lisp explained this theory best:
In the Algol family, parentheses signal pain. In the Lisp family,
they signal comfort. Since most people are highly emotional
believers, even programmers, it is very hard for them to relinquish
their beliefs in their associations of parentheses with pain and
suffering. This has nothing to do with aesthetics, design
rationales, ease of use, the value of the code-as-data paradigm,
etc. This has everything to do with the deeply ingrained "knowledge"
that you do not need parentheses unless you want to transcend the
(overly simple) rules of the language. The psychology of programming
has taught programmers in the Algol family that parentheses are to
be minimized and that any large number of parentheses is a good sign
that the code, or worse, the thinking behind it, is too complex.
(Message-ID: <3237215494375390@naggum.no>)
Other folks figure that syntax is ultimately not that important and wonder why Lisp can't use a more "normal" syntax. It's not because Lispers have never thought of the idea—indeed, Lisp was originally intended to have a syntax much like FORTRAN, the predominant high-level language of the day, as John McCarthy describes in his history of Lisp3:
The programs to be hand-compiled were written in an informal notation called M-expressions intended to resemble FORTRAN as much as possible. ... The M-notation also used brackets instead of parentheses to enclose the arguments of functions in order to reserve parentheses for list-structure constants. It was intended to compile from some approximation to the M-notation, but the M-notation was never fully defined, because representing LISP functions by LISP lists became the dominant programming language when the interpreter later became available. A machine readable M-notation would have required redefinition, because the pencil-and-paper M-notation used characters unavailable on the IBM 026 key punch.
Later he says:
The project of defining M-expressions precisely and compiling them or at least translating them into S-expressions was neither finalized nor explicitly abandoned. It just receded into the indefinite future, and a new generation of programmers appeared who preferred internal notation to any FORTRAN-like or ALGOL-like notation that could be devised.
However it wasn't simply inertia that caused Lispers to prefer S-expressions to M-expressions. People have tried, numerous times to create a more Algol-like syntax for Lisp on the theory that it would somehow be possible to combine the best of both worlds, the power of Lisp with the popularity of Algol-style syntax. Guy Steele and Richard Gabriel recount the history of some of these attempts in their paper "The Evolution of Lisp" which is included in History of Programming Languages, Volume 2 and available at http://www.dreamsongs.com/NewFiles/HOPL2-Uncut.pdf. They close the section on these attempts with this summary:
The idea of introducing Algol-like syntax into Lisp keeps popping up and has seldom failed to create enormous controversy between those who find the universal use of S-expressions a technical advantage (and don't mind the admitted relative clumsiness of S-expressions for numerical expressions) and those who are certain that algebraic syntax is more concise, more convenient, or even more natural (whatever that may mean, considering that all these notations are artificial).
We conjecture that Algol-style syntax has not really caught on in the Lisp community as a whole for two reasons. First, there are not enough special symbols to go around. When your domain of discourse is limited to numbers or characters, there are only so many operations of interest, and it is not difficult to assign one special character to each and be done with it. But Lisp has a much richer domain of discourse, and a Lisp programmer often approaches an application as yet another exercise in language design; the style typically involves designing new data structures and new functions to operate on them—perhaps dozens or hundreds—and it's just too hard to invent that many distinct symbols (though the APL community certainly has tried). Ultimately one must always fall back on a general function-call notation; it's just that Lisp programmers don't wait until they fail.
Second, and perhaps more important, Algol-style syntax makes programs look less like the data structures used to represent them. In a culture where the ability to manipulate representations of programs is a central paradigm, a notation that distances the appearance of a program from the appearance of its representation as data is not likely to be warmly received (and this was, and is, one of the principal objections to the inclusion of loop in Common Lisp).
On the other hand, precisely because Lisp makes it easy to play with program representations, it is always easy for the novice to experiment with alternative notations. Therefore we expect future generations of Lisp programmers to continue to reinvent Algol-style syntax for Lisp, over and over and over again, and we are equally confident that they will continue, after an initial period of infatuation, to reject it. (Perhaps this process should be regarded as a rite of passage for Lisp hackers.)
When Steele and Gabriel are talking about manipulating representations of programs, they are, of course, talking about macros.4 This is where the s-expression notation really shines. An Algol-style syntax is all well and good for languages that have a finite number of basic constructs—one can define a grammar that specifies how various syntactic constructs get translated into an abstract syntax tree (AST) that can then be processed by an interpreter or compiler. Open any compiler textbook and you'll learn how to write a parser that can turn the infix syntax:
1 * 2 + 3 / 4
into the AST:

according to the precedence of the operators *, +, and
/. But in a language that supports macros we can't know, at
language design time, all the possible legal language constructs. Thus
we can't rely on having a grammar that knows how to translate all
possible syntactic constructs into ASTs. Rather, we need a way to
represent arbitrary ASTs. Which is what s-expressions are. Even if we
know nothing about the precedence of *, +, and /
this s-expression:
(+ (* 1 2) (/ 3 4))
unambiguously represents the same AST shown above.5
Likewise, when Lisp sees something like this:
(with-whatever (something)
(do-one-thing)
(do-another-thing))
it can parse it into an AST without knowing anything about the
internal syntax of the with-whatever construct. If
with-whatever is a macro, it will be passed the AST,
represented as an s-expression, and is responsible for producing a new
s-expression representing the AST that should be used in place of the
original with-whatever form.
Lisp works quite differently than most languages that you may be familiar with, for example C has a very distinct cycle. In the C style, you edit some code, compile it with a separate compiler and produce an executable. You can then run that executable, perhaps with a debugger attached to it. Modern IDEs smooth the distinctions between these steps, but under the hood they are still there.
With Lisp, you have a single Lisp process, what's known as a Lisp image, and the compiler, interpreter, debugger and your application all run within the same process. This is quite a profound difference, for example it means that your application automatically has a built in compiler! There are many different implementations of Lisp, and what is available in your image may very - for example some Lisps have no interpreter part & some only have a compiler.
I have started thinking of my Lisp image as its own environment, almost a separate little operating system.
Interacting with the Lisp image is done via the Read-Eval-Print-Loop (REPL), which as the name implies, reads input, evaluates and then prints it. You can send forms to the REPL and immediately get back the results of executing that form, this is a great way to test out the nuts and bolts of a function as you are writing it.
When you write a function by using DEFUN, you are altering the state of the Lisp image - there is now a new function that can be used within the running image.
Because a Lisp image is created by dumping a copy of a running Lisp process to disk, which creates an "image" of the process on disk. When you save an image and restart it later, all the functions you'd defined in it still exist. Saving and restarting an image is similar in spirit to compiling and running a C program, in the sense that if the C program or the Lisp image create a GUI or open network connections or connect to databases, all that has gone away when you restart the C program or the Lisp image, and the program must start over from some well defined point ("main()", in the case of a C program, and wherever you tell your image to start when you save it, in the case of Lisp).
A1: The short answer: Yes
A2: Slightly longer: Sometimes, but it depends on your implementation. See your implementation's documentation.
A3: Even longer answer to come.
Since the advent of Python, this comes up on c.l.l. with some regularity. We've had "sweet-expressions" and "indented Lisp" and probably others.
Realize a few things:
You should use an editor that makes writing Lisp easier, like Emacs or Vim. Both of these can indent based on parenthesis nesting, highlight matching parentheses, cut and paste entire blocks of code based on the parentheses, and so on. If your editor can't do all that, get a new editor.
Emacs users should check out parenface.el, which de-emphasizes parentheses with a diminished font color (or "face" in Emacs-speak). For instance, if your normal face is black-on-white, it'll make parentheses a shade of gray, so that they're less "in your face" while still being visible.
Lispers already read code based on indentation, but their editors indent and re-indent code automatically. Removing the parentheses makes that harder.
After you've written and read enough Lisp, you stop seeing the parentheses. (Reports vary from a few days to a few weeks.) They don't disappear in some magical way, but you start to see the structure of the code rather than just "lots of fingernail clippings".
For example, you can view (+ (* 1 2) (/ 3 4)) as "(+ (* 1 2) (/ 3 4))" or as

Adding or removing parentheses — or adding indentation — to the tree notation makes no sense. To a Lisper that has learned to recognize the () notation as the structure denoted by the tree diagram, it makes just as little sense.
Given all the above, if you go ahead and build or use an indentation-based Lisp ("IBL"), be prepared to abandon it after you get sufficiently into Lisp. And if you post about your IBL to c.l.l., be prepared for a less-than-welcoming response. (We'd love to hear about an IBL-er abandoning it for parentheses, though. This would provide empirical evidence to which we could direct later newbies.)
This was actually done in both research and industrial contexts, from the mid 1970s to the early 1990s. The Lisp Machines were advanced, general purpose computers designed for efficiently running Lisp programs. Virtually all their software, from device drivers and low-level operating system layers to end-user applications, was written in Lisp.
From time to time, someone proposes to start an open-source project for developing a Lisp operating system similar to those of Lisp Machines. Such ambitious projects, however, have had limited success (a list of past attempts is available) because of the sheer amount of work that would be necessary. Consider, for example the need to support the huge range of contemporary complex devices and peripherals. The community of Lisp programmers is currently unlikely to match the resources of past, well-funded Lisp Machine vendors and research institutions.
Possibly the most successful project for a Lisp operating system is Movitz, which is a Common Lisp implementation that targets the x86 architecture "on the metal". It is intended as a development platform for operating system kernels, embedded systems, and single-purpose applications. (Lisp Machines, Movitz, etc).
As a hybrid approach, many folks on cll suggest that one start with an Open Source OS, such as Linux, and have it run one or more normal Lisp processes. You get the hardware support "for free", at the expense of not having the machine run Lisp "all the way down".
Think of a mathematical proof - "Let x be the distance from origin ..."
There's some debate whether the "F" in SETF originally stood for "Form" or "Field". However, the former (no pun intended) makes a bit more sense since SETF can be used to set any form that has an appropriate "setf expander" defined. For instance the reason we can say
(setf (car foo) 10)
is because there's a setf expander that knows that you can set the CAR of a cons cell using RPLACA and thus SETF can expand the above into:
(rplaca foo 10)
The kinds of forms that can be set using SETF, called "places" are described in section 5.1.2 of the HyperSpec. New such forms can be defined by defining SETF functions, and SETF expanders using DEFSETF and DEFINE-SETF-EXPANDER.
CAR and CDR are the fundamental accessors for the head of a list and the rest of a list. Their names come from the names of two assembler macros on the IBM 704 mainframe.
These macros were used to extract two memory addresses from a 36bit register. CAR is an abbreviation of contents of address of register whilst CDR is for contents of decrement of register.
The assembler macros ended up with a home in lisp itself since they formed the basic computer operations on the 704 to perform what we can refer to as FIRST and REST.
CAR and CDR survive in modern Common Lisp mostly for
nostalgia reasons and also because of an interesting set of
abbreviations they allow. By forming new abbreviations such as
CADR and CAADDR we treat each a as a CAR and each d
as a CDR.
So CADR is an abbreviated form of (car (cdr lst)) and
CAADDR is an abbreviation of (car (car (cdr (cdr lst))))
This is called "composability" and so people like the names "CAR" and "CDR" because they're "composable".
One point of view frequently expressed on comp.lang.lisp is that if you want to think about your data structure as a list, you should use FIRST and REST, whereas if you want to think about your data structure as a set of structures with two pointers in each, you should use CAR and CDR. Following this convention can make the programmer's intent clearer to the human reader.
See also Wikipedia's entry for more http://en.wikipedia.org/wiki/Cdr
The terms Lisp-1 and Lisp-2 were invented by Kent Pitman and Richard Gabriel for use in their paper "Technical Issues of Separation in Function Cells and Value Cells". In that paper Lisp-1 and Lisp-2 are defined as "two abstract dialects of Lisp", presumed to be the same in all respects except for one, having to do with whether function names and variable names live in a single namespace or two distinct namespaces. A Lisp adopting the former strategy, such as Scheme, is a Lisp-1 and one adopting the latter, such as Common Lisp, is a Lisp-2.6
In a Lisp-1, such as Scheme, there is a single namespace for functions and variables meaning that in a function-call expression such as
(foo bar baz)
the value of foo is looked up in exactly the same way as the
values of bar and baz. If this is to be meaningful as a
function call the value of foo will, of course, need to be a
function. Thus an expression like:
(let ((foo 10))
(foo bar baz))
is necessarily an error in a Lisp-17 This is why Scheme programmers typically use
names like lst for parameters rather than list; a
parameter named list would shadow the top-level definition of
the list function.
A Lisp-2, such as Common Lisp, by contrast, uses two rules, one for
for looking up the value of a name appearing in the first position of
a function call and one for names appearing in all other positions.
Assuming foo has been defined as a function in an enclosing
scope, then the let expression above is well-formed in a Lisp-2
since the let binding affects the value of foo only in
the variable namespace, leaving the function binding
unchanged.
However a Lisp-2 that supports first-class functions, as Common Lisp does, needs to provide a way to access the function namespace in value positions. In Scheme we can write:
(apply + '(1 2 3))
because the + appearing in a value position evaluates to the
same function as it does in the expression:
(+ 1 2 3)
In Common Lisp, on the other hand, + in a value position is
evaluated as a variable name, not a function name. To get at the
function named + we need to use the special operator
FUNCTION:
(apply (function +) '(1 2 3))
Common Lisp also provides the reader macro #' as a shorthand
for FUNCTION:
(apply #'+ '(1 2 3))
Conversely, a Lisp-2 needs to provide a way to invoke a function obtained via the normal evaluation rule. In Common Lisp this is done with the function FUNCALL:
(let ((fn (if (sometest) #'foo #'bar)))
(funcall fn 1 2 3))
is equivalent to the Scheme:
(let ((fn (if (sometest) foo bar)))
(fn 1 2 3))
These could also be written without the fn variable:
;; Common Lisp
(funcall (if (sometest) #'foo #'bar) 1 2 3)
;; Scheme
((if (sometest) #'foo #'bar) 1 2 3)
Lisp-1 vs Lisp-2 is one of the classic religious wars—partisans on both sides tend to view their choice as obviously better and are mystified by the obtuseness of their opponents. Schemer's find the notion of cluttering up their language with an extra evaluation rule abhorrent especially as it necessitates new operators such as FUNCTION and FUNCALL (to say nothing of FLET and LABELS) while making a certain style of functional programming more verbose.
Common Lispers, on the other hand, think Schemers look silly spelling
list as lst and like having their forays into
functional programming stand out a bit syntactically.
ANSI — American National Standards Institute, the standards body responsible for the Common Lisp standard.
CL — Common Lisp
CLHS — Common Lisp Hyper Spec, also known as the HyperSpec, an incredibly useful HTMLized version of the ANSI Common Lisp standard. It is extensively cross linked and also includes the text of a number of "X3J13 Issues" which are write ups of issues considered by the Common Lisp standardization committee. The issues are not part of the language standard but provide useful historical background on how Common Lisp ended up the way it did.
CLISP — A particular Common Lisp implementation written by Bruno Habile. Experienced Common Lispers refer to the language in general as CL not CLISP because it would be too confusing otherwise.
CMUCL — Carnegie Mellon University Common Lisp. A well regarded Common Lisp implementation originally developed at Carnegie Mellon.
ECL — Embeddable Common-Lisp, a Lisp implementation that is notable for being able to compile Common Lisp to C source code in a way that makes it relatively easy to embed Common Lisp into C programs.
GC — Garbage Collection
GCL — GNU Common Lisp, another Common Lisp Implementation.
PCL — Both the book Practical Common Lisp and Portable Common Loops, an early implementation of CLOS that is still used by some Common Lisp implementations, notable CMUCL and SBCL.
REPL — Read Eval Print Loop, also known as "the listener". The Common Lisp equivalent of a command line, a place where you can type Lisp expressions to be evaluated immediately and have the resulting value printed.
SBCL — Steel Bank Common Lisp, another Common Lisp implementation. SBCL was derived from CMUCL and gets its name from the industries, steel and banking, that the Carnegie and Mellon of CMU were titans of.
SLIME — Superior Lisp Interaction Mode for Emacs. A featureful Lisp development environment for Emacs users. Works with most Common Lisp implementations and is a vast improvement over the venerable ILISP, particularly when dealing with multithreaded Lisps.
X3J13 — The ANSI committee responsible for the Common Lisp standard.
You may also wish to visit the Jargon File
The vast majority of Lispers will tell you "Like Emacs does it automatically". :)
More seriously, look at some Lisp books, you'll figure it out pretty quickly. One (of several) practice(s) to avoid is the C style
(
where you
(
treat parentheses like braces
)
and put them on separate
)
lines.
The simple, but not necessarily satisfying, answer is that AND and OR are macros, not functions, and APPLY and FUNCALL can only be used to invoke functions. But why are they defined as macros? So they can provide "short circuiting". That is, if you say:
(and new-value-needed (compute-new-value))
The expression (compute-new-value) will only be evaluated if
new-value-needed is true, in which case the whole expression
will evaluate to the newly computed value returned by
compute-new-value. Otherwise the expression evaluates to
NIL. Similarly, this expression
(or cached-value (expensive-computation))
will evaluate to the value of cached-value if it is
non-NIL without bothering to evaluate
(expensive-computation). On the other hand, if
cached-value is NIL, then expensive-computation
will be called and it's value returned as the value of the OR
expression.
If AND and OR were functions, rather than macros, then
(compute-new-value) and (expensive-computation) would
always be evaluated and their values ignored.
Of course if one simply has a bunch of values, possibly in a list, and would like to logically and or or them together it's irksome that you can't APPLY AND and OR. However, you can usually use the standard functions EVERY and SOME with the IDENTITY function as their predicate. That is rather than:
(apply #'and some-list) ; Illegal
say:
(every #'identity some-list)
and instead of:
(apply #'or some-list) ; Illegal
say:
(some #'identity some-list)
Note, however, that EVERY simply returns T when all the values in the list are non-NIL rather than returning the last value as AND does.
Because MAKE-ARRAY is a regular function, it's arguments are all evaluated before it is called. This can trip people up when they say something like this:
(make-array 10 :initial-element (make-foo))
intending to make an array of ten distinct objects. When this
expression is evaluated, (make-foo) is evaluated once and the
resulting object is passed to MAKE-ARRAY which makes it the value
of all ten elements of the array. If the object is later modified, the
change will be visible via any and all elements of the array. Of
course if the object is immutable that probably wouldn't matter which
is why it's okay to say things like:
(make-array 10 :initial-element 0)
To initialize an array with distinct objects, you must iterate over the array somehow. One concise idiom is the following:
(map-into (make-array 10) #'make-foo)
It's also worth noting that a call to MAKE-ARRAY without an
:initial-element argument returns an array with unspecified
array contents.
There is no function in the language specification for splitting a string (or any other sequence) into parts. And since it's not particularly hard to implement the particular kind of splitting one wants in any given case using some combination of SUBSEQ, POSITION, SEARCH, and LOOP Lispers were left to their own devices for quite some time.
However in June/July 2001, a group of Lispers on comp.lang.lisp hashed out the specification and implementation of a defacto standard library, SPLIT-SEQUENCE, containing three functions, SPLIT-SEQUENCE, SPLIT-SEQUENCE-IF, and SPLIT-SEQUENCE-IF-NOT, that are designed to fit well with the standard Common Lisp functions for dealing with sequences. In its simplest form it works like this:
(split-sequence #\Space "A stitch in time saves nine.")
gives:
("A" "stitch" "in" "time" "saves" "nine."), 28
For more details and a download link, consult the specification, available from its CLiki page.
READ-FROM-STRING is one of the rare functions that takes both
&optional and &key arguments. The complete argument list is:
string &optional eof-error-p eof-value &key :start :end :preserve-whitespace
When a function takes both types of arguments, all the optional
arguments must be specified explicitly before any of the keyword
arguments may be specified. In the example above, :start
becomes the value of the optional eof-error-p parameter and 3
is the value of the optional eof-value parameter.
To get the desired result, you should use (read-from-string
"foobar" t nil :start 3).
There are only three other functions in the COMMON-LISP package that
take both &optional and &key arguments and thus are
potentially subject to the same problem: PARSE-NAMESTRING,
WRITE-LINE and WRITE-STRING.
One possibility is that the expression you just asked Lisp to evaluate
contains an infinite loop or is simply taking a very long time to
evaluate. (Some standard new Lisper exercises are designed to lure you
into this trap; if you've written, say, a naive implementation of a
function to compute the nth Fibonacci number, evaluating even
something as seemingly innocuous as (fib 30) can take quite a
bit longer than you might be willing to wait.)
The other possibility is that you simply haven't typed a complete Lisp expression—most Lisp environments allow you to include line breaks in expressions you type at the REPL since they can use the parentheses to determine when you've typed a complete expression. If you haven't yet closed all your parens, there's nothing for Lisp to evaluate. (Some Lisp environments will help you out with this. SLIME for instance, flashes the opening paren corresponding to each closing paren you type and if you hit return in the middle of an expression puts a message the mini-buffer saying "[input not complete]".)
Other more esoteric possibilities are that you've typed a double quote
which needs to be closed or a #| nested comment opener with no
closing |#.
Continuations are a great theoretical tool; if a language has first-class, multiply-invocable continuations then one can build threads, exceptions, coroutines, and the kitchen sink on top.
However, such continuations present a a heavy burden for a Lisp implementer and may preclude or at least complicate other desirable optimizations. The ANSI standardizing committee decided that it would be better to specify the user-level control structure (CATCH, UNWIND-PROTECT, and so on) and let implementers choose whether to build those on top of continuations or not.
If you need to play with continuations, they are standard in Scheme though make sure you pick a Scheme implementation that actually supports them because they don't all.
Lisp does in fact have a benevolent, if extremely hands-off, dictator: its inventor John McCarthy. However the only diktat he has issued is that no dialect in the Lisp family of languages shall call itself simply "Lisp". Thus we have Common Lisp, Scheme, Elisp, AutoLisp, XLISP, ISLISP, and others.
Common Lisp, on the other hand, does not have a benevolent dictator because it is a language defined by a standard, not by a single individual (c.f. Perl or Python) or organization (c.f. Java). Prior to Common Lisp there were a number of competing Lisp dialects, some with several implementations, each with their own dictator, benevolent or otherwise. Common Lisp arose in an attempt to bring that diversity somewhat under control without killing off all the innovation that was going on in the different research labs and companies using and implementing Lisp.
The language standard does two things: On one hand, it establishes a contract between users and implementers of a language so that programs written in conformance with the rules defined in the standard will run in a predictable way on conforming implementations. On the other hand, it leaves some areas open to be defined by a particular implementation. Sometimes this is because there is no solution that is appropriate for all possible implementations and in other cases because folks couldn't agree on a single best way and wanted to leave room for experimentation. While it is sometimes annoying to have to deal with implementation-specific details when writing portable code, this approach to language standardization has allowed Common Lisp a fruitful diversity of implementations—there are free and open-source implementations available under different licenses as well as commercial products that provide different capabilities on different platforms at different prices.
Whether you think this situation is better or worse than that in other languages where a benevolent dictator ensures a certain uniformity, i.e. lack of diversity, it's unlikely that arguing about it in comp.lang.lisp, or anywhere else, is going to be productive. There are obviously enough folks out there who value the existing diversity of implementations to support the half-dozen or so under active development. Presumably there is something about each implementation, above and beyond its conformance to the language standard, that suits its users.
That said, it is worth considering what would really be different if there was a benevolent dictator. In languages ruled by such a dictator, the dictator typically has three powers:
To make changes to the basic syntax of the language.
To make changes to the semantics of the language.
To determine what libraries are "standard" parts of the language.
In Common Lisp, the ability to define new syntax is granted, via macros, to all users of the language; there is little need for a single dictator to handle that. And actual changes to syntax in non-Lisp languages tend to be fairly infrequent anyway because even a dictator has to answer to the god of backwards compatibility.
Changes to language semantics are even less frequent. Examples would be defining how to incorporate concurrency into the language or narrowing the definition of a basic data type such as specifying that characters represent Unicode code points. The obvious advantage of having a language dictator is that such changes can be made relatively easily. On the other hand, it means that once the dictator has ruled the decision is made. In Common Lisp, on the other hand, there are a half dozen dictators, each with their own implementation. Each can try their own approach and have the opportunity to learn from each other after seeing how different ideas work out in practice. While this can lead to slight differences between implementations, if there really is a best way it's likely that the implementations will converge on it. And if there's not a single best way, then it's actually a feature that there's no single dictator to force a single choice for all users.
Finally the "standard library" issue does not need a language-level dictator. It's fairly straightforward to write libraries that are portable between Lisp implementations given Common Lisp's reader conditionals. Most Lisp libraries that are distributed independent of a particular implementation are portable—if someone wants to declare themself the benevolent dictator for Lisp libraries, the position is vacant. Put together a set of well-tested, well-documented libraries and distribute them in a single blob as the Common Lisp Standard Library and the world will beat a path to your door.
Yes. Anyway, the Scheme standard (R5RS) says it is. ("Scheme is a statically scoped and properly tail-recursive dialect of the Lisp programming language.") On the other hand, Scheme and Common Lisp, while sharing an intellectual legacy and a number of important characteristics, also differ in ways just subtle enough to stir up a good old fashion religious war. Consequently, Scheme vs. Common Lisp discussions almost never go well. And you may run across prominent Common Lispers who will argue—in an angels on a pinhead kind of way—that Scheme is not in fact a Lisp. You may also hear folks who say "Scheme is not Lisp", meaning, Scheme is not the end-all-and-be-all of possible Lisp dialects. This is usually said in conversations with people turned off "Lisp" forever by a bad undergraduate experience with Scheme.
Ultimately Scheme and Common Lisp differ in their history and their current communities of users. Scheme was invented in order to test out certain theories of language design and continues to be used by people interested in having a small, simply defined language for further language research and pedagogy. Which is not to say that's the only way Scheme is used, but it helps give the Scheme community its particular flavor. Common Lisp, on the other hand, is the offspring of the systems-programming Lisps of the Artificial Intelligence boom. It continues to be an important AI language and is now used largely by people who care more about raw power and writing software than they do about conceptual purity and good pedagogy. Again, this is a portrait in broad strokes but there is truth in it.
As an intellectual exercise, learning both Scheme and Common Lisp will enrich your understanding of the platonic ideal of Lisp and of programming in general. As a practical matter, if you do learn both, you'll likely gravitate to one or the other based on your own predilections and the kind of projects you are interested in.
1. Practical Common Lisp was also written by the editor of this FAQ so you can take this recommendation with a grain of salt if you wish.
2. N.B. The editor of this FAQ is the author of one of these books, Practical Common Lisp. However the original answer to this question was written by someone else so we'll let it stand.
4. By "macros" I mean proper Lisp-style macros, not mere textual replacement a la the C pre processor.
5. Some folks prefer to use the term "s-expression" to refer to only the textual representation, i.e. the parentheses and letters, while others consider s-expressions to be the Lisp objects produced by when the Lisp reader reads such a textual representation. Usually it's okay to not worry too much about the distinction. It is worth noting that in Common Lisp the semantics of the language are defined in terms of Lisp objects, not textual forms which is why you we say:
(eval (list '+ 1 2))
rather than:
(eval "(+ 1 2)")
to evaluate the expression that adds 1 and 2.
6. Pitman and Gabriel's paper was based on a report they originally prepared for the ANSI Common Lisp standardization committee, X3J13, to address the question of whether Common Lisp might want to follow Scheme's lead on the Lisp-1/Lisp-2 issue rather than sticking with the Lisp-2 tradition of most of Common Lisp's other predecessors.
7. Well, unless it's a strange Lisp-1 that has also defined some meaning for a list expression whose first value is a number.