Nikodemus' Common Lisp FAQ
Last updated 2012-04-13
This is a very unofficial Common Lisp FAQ, reflecting Nikodemus Siivola’s subjective opinion. This text is based in part on other FAQs found on the Internet and comp.lang.lisp.
If you think that I used your text, I will be glad to admit it, so write to nikodemus@random-state.net.
The current version of this FAQ is available at the following addresses:
http://random-state.net/files/nikodemus-cl-faq.txthttp://random-state.net/files/nikodemus-cl-faq.htmlFAQs are also periodically published in comp.lang.lisp.
The very beginning
Common Lisp? CL? Clisp? Lisp?
Common Lisp is the name of the ANSI standardized language.
“CL” is the most preferred abbreviation of the previous name.
“Clisp” is not a proper abbreviation, because it is the name of one of the implementations of Common Lisp.
"Lisp" is the category of languages to which CL belongs.
“LISP” is no longer written for 20 years, Common Lisp is often shortened to Lisp if
it is clear from the context exactly what is at stake.
So what?
You can read about the language here:
http://random-state.net/features-of-common-lisp.html')
How to learn Common Lisp?
- Read a good book on Common Lisp.
- Start using it.
Many people often try to go through the first path, but forget about the second one.
Well, really, you can't learn how to program in the language without starting to use it. And then, without working on a fairly large program, many things are impossible to understand correctly.
What pitfalls to bypass?
Any good book will tell you about the features and tricks of the language, but there are a couple of psychological and social issues that many stumble upon:
- Learning about Lisp macros is crazy.
Lisp macros are great stuff, but the power they give to newbies is often confusing.
Often a symptom of a problem is an attempt to do something without a clear understanding of why it is being done. Remember, all that can be done with macros can be done without them. Of course, it may turn out not so practical, but the memory of this lowers from heaven to earth.
Before you learn to run, learn to walk. It is worth it, especially since then you can fly. - Lisp is not perfect, and this is not news.
Some come to Lisp with high expectations and are disappointed. Others compare Lisp with X and discover that the former is losing in some ways.
Both may reason correctly and have valid claims, but problems begin when these people begin to voice their claims somewhere, for example, on #lisp.
If the reasoning is correct, most likely the question has already been discussed a hundred times and no one has enough strength or desire for a second discussion.
If the reasoning is wrong or they are more theoretical than practical, then despite the fact that every year disaffected beginners constantly raise such questions, no one has enough strength or desire to re-discuss.
This does not mean that talking bad about Lisp on the Internet is forbidden, but ... If you are a beginner, come and say that everything is bad, do not expect that people will come to you with open arms. Even if you are a hundred times right.
Complaints from oldies, who also made a lot for the community, have much more weight. - Experienced public lispers see a lot of trolls.
MANY TROLLS! A confused newbie sometimes looks like a troll, largely because most trolls most often disguise themselves as Lisp beginners.
Therefore, people may think that you are a troll and respond accordingly.
The best way to avoid this is to be polite. If someone tells you that you are mistaken or mistaken, suppose for a moment that he is either right, or it looks like you are mistaken or mistaken.
What book to start with?
Start with Practical Common Lisp (also known as PCL) by Peter Seibel. This is a good starting point if you already have some programming language. The book is available in electronic and printed form:
http://www.gigamonkeys.com/book/Another good book is Common Lisp: A Gentle Introduction to Symbolic Computation by David Touretzky. Newbies in programming, or those who find PCL too complicated, should read this book. If you start with it, then read PCL. Although if you have already read PCL and understood everything, you can safely skip this one. The book is available in electronic and printed form:
http://www.cs.cmu.edu/~dst/LispBook/index.htmlThere are a lot of good books, but these two are the best for beginners. Land of Lisp is not bad, but in my humble experience it can form a misconception. If you start with it, read PCL anyway.
Be sure to check out Hyperspec or CLHS, the electronic version of the language standard. This is just the most valuable reference:
http://www.lispworks.com/documentation/HyperSpec/index.htmlDo not immediately rush to read the directory. Just know where it is, it contains the official answers to all possible questions about the CL. This is the perfect place to find out what an operator is doing. In addition, it is worth looking into it to find out if the functionality you need is implemented in the language.
Do not neglect the documentation that came with your implementation. In the case of SBCL, the guide is located at:
http://www.sbcl.org/manualWhat should I get the implementation?
It depends on what you need, although if you are just starting, it does not matter. However, if you are waiting for help from some group of people, take the realization that this group uses.
As you learn, you will be able to make an informed choice. The transition between implementations is not very difficult, so this is not a reason for doubts.
I am very partial to SBCL:
http://www.sbcl.org/SBCL is good because it comes with open source, runs on many platforms (including Windows), includes a compiler, is very serious about compatibility with the ANSI standard and generally brings joy and peace in the world ... and here I must to mention that I am one of the developers of SBCL and my company
Steel Bank Studio Ltd provides commercial support for it.
If for some reason SBCL does not suit you, I can suggest to go through the following lists:
Open:
- Clozure cl
- CMUCL
- Clisp
- ABCL
- Ecl
Commercial:
- Lispworks
- Allegro CL
- Scieneer
Where are the libraries? Is there an analogue of CPAN or RubyGems?
QuickLisp is very similar to RubyGems:
http://www.quicklisp.org/It provides lots of libraries and manages dependencies between them. This is a very, very necessary tool.
The closest to CPAN are Cliki and common-lisp.net:
http://www.cliki.net/http://www.common-lisp.net/... but nothing is better, really.
How to use IDE?
If you are working with SBCL, then use Emacs and Slime:
http://www.common-lisp.net/project/slime/Even if you didn’t use Emacs before, make an effort on yourself and use Slime - the learning curve is not very steep and all commands are available through the menu.
You can configure Slime using Quicklisp, see below the section “How to set up the environment?”. You can start learning with
Mx slime-cheat-sheet
, however, this is only a small part of the Slime features.
When using another implementation, use the IDE that the developer recommends (although Slime works with almost all implementations).
For practical work with Lisp, the editor should at least:
- correctly set up the Lisp code;
- understand pair brackets;
- be able to execute the commands Edit Definition, Compile Defun, Eval Expression, Describe Symbol, Disassemble Function, Trace Function, Inspect expression and other commands to interact with your Lisp;
- interact with the debugger;
- interact with the inspector.
Slime can do all of the above and much more.
If you like Vi (m), take a look at Slimv, which links Vim to the part of Slime written in Common Lisp:
http://www.vim.org/scripts/script.php?script_id=2531https://bitbucket.org/kovisoft/slimv/http://kovisoft.bitbucket.org/tutorial.html... but I can not vouch for this, because I do not use Vim / Slimv.
How to set up the environment?
A good guide (at the time of writing) on getting SBCL, Slime and setting up Quicklisp is located here:
http://mohiji.nfshost.com/2011/01/modern-common-lisp-on-linux/http://mohiji.nfshost.com/2011/01/modern-common-lisp-on-osx/Guidelines for configuring Clisp on Windows. However, it is impossible to grasp the immense:
http://mohiji.nfshost.com/2011/01/modern-common-lisp-on-windows/Is there a GUI?
Yes and no. One GUI that everyone would use is not.
Commercial Lisp's are mostly shipped with GUI libraries, and it seems that supporters of these implementations like the supplied libraries. However, the code for such libraries is not transferred between Lisp'ami. If you are using a commercial implementation and the portability of the code is not interesting for you, then choose the tools offered by the developer. Depending on how the library is made, the code may be transferred to different operating systems, perhaps this is exactly what you need.
In the camp of the open code, too, there are several solutions.
CommonQt is a binding of Common Lisp to the Qt smoke library:
http://common-lisp.net/project/commonqt/LTK is built on top of Tk:
http://www.peter-herth.de/ltk/CL-GTK2 and CLG are GTK + bindings, but I can't say anything about the current state of these developments. It is also worth looking at GTK Server.
http://common-lisp.net/project/cl-gtk2/http://sourceforge.net/projects/clg/ http://www.gtk-server.org/CLIM (Common Lisp Interface Manager) is an almost standardized GUI API specification that is quite different from the GUIs listed above. Do not expect that everything will be familiar and clear.
http://random-state.net/files/how-is-clim-different.htmlMany swear that this is the best thing to build a GUI, others argue that this is not the case. Be that as it may, most commercial Lisp implement CLIM, and there is still a portable open library called McCLIM, which is quite convenient, although not very advanced lately.
http://common-lisp.net/project/mcclim/CLX is a portable low-level Lisp interface to X11, providing an abstraction layer comparable to Xlib.
http://www.cliki.net/CLXhttps://github.com/sharplispers/clxUnless strictly limited to GUI issues, I’ll be wrong if I don’t mention CL-OPENGL, a portable binding to the OpenGL API, GLU and GLUT:
http://common-lisp.net/project/cl-opengl/What are the forums?
Not a forum of course, but there is a Planet Lisp - Common Lisp blog aggregator. A lot of interesting information, without excess.
http://planet.lisp.org/LispForum is just a good forum:
http://www.lispforum.com/but I don’t vouch for it, as I’m not often there.
There are also comp.lang.lisp groups on Usenet / Google Groups, but they are densely populated by trolls. The authors who write there are quite literate, and the speculations of the profane are an ordinary phenomenon. Reading these groups can be tough, but you don't need to read them to use Lisp.
http://groups.google.com/group/comp.lang.lispSpecialized mailing lists have a much better signal-to-noise ratio. All implementations try to create their own user and reference mailing lists, most libraries also create their own mailing lists. For SBCL there is, for example, this:
https://lists.sourceforge.net/lists/listinfo/sbcl-helpAmong open-source developers and users, the #lisp channel on freenode.org is popular. Keep in mind, however, that on #lisp they stick to the theme rather rigidly, and this is Common Lisp, not “Lisp at all”. For this, there is the #lispcafe channel with much softer rules.
The game development community is pretty active, but I’m not familiar with it. Google to help you.
Common Lisp Professionals chat on the pro list. Discussion of other Lisp dialects is oftopikom, novice questions are NOT accepted.
http://lists.common-lisp.net/mailman/listinfo/proLanguage properties
How to compile a file?
The short answer is: start Lisp and type:
(compile-file "/path/to/myfile.lisp")
Then, most likely, you will need to load (load ...) the compiled file.
Detailed answer: most compiled languages are non-interactive — you compile a file from the command line or an IDE, then run the compiled file. In Lisp, it's not like that.
While in the general case you can turn your project into an executable file, a typical working session is not like the edit-compile-execute cycle, as one would expect.
Usually, the interaction occurs with a running Lisp process that contains a work session to which you interactively add code.
For example:
- open Emacs, use Slime and Lisp with
Mx slime
; - using, for example, ASDF, load the existing code;
- open the desired file, edit the function and press
Cc Cc
, which will recompile it; - go to the Slime REPL and test the changes;
- repeat from step 3.
The above abbreviation ASDF stands for “Another System Definition Facility”. This system allows you to specify a way to collect multiple files into a single system for downloading or compiling one command. Something like Make.
How to make an executable file?
The answer depends on the implementation you are using. See the documentation. If we talk about SBCL:
FUNCALL and APPLY - what's the difference, what to use?
The short answer is: wherever you can use
FUNCALL
, in other cases use
APPLY
.
Detailed answer: when calling
FUNCALL
number of arguments must be known.
APPLY
(and
MULTIPLE-VALUE-CALL
) does not require information on the number of arguments.
(defun map-list-with-1 (function list arg) (mapcar (lambda (elt) (funcall function elt arg)) list)) (defun map-list-with-n (function list &rest args) (mapcar (lambda (elt) (apply function elt args)) list))
There is no need to write
MAP-LIST-WITH-1
using
APPLY
, the
FUNCALL
call
FUNCALL
almost certainly be more efficient.
In contrast,
MAP-LIST-WITH-N
cannot be written using
FUNCALL
, since the number of arguments to the caller is unknown. Should use
APPLY
.
SET, SETQ and SETF - what's the difference, what to use?
The short answer is: always use
SETF
.
Detailed answer: Long ago, when there was no Common Lisp, there were no lexical variables, there were only dynamic ones. And then there was neither
SETQ
, nor
SETF
, only
SET
.
What is spelled today as
(setf (symbol-value '*foo*) 42)
recorded like that
(set (quote *foo*) 42)
which eventually decreased to
SETQ
(SET Quoted)
(setq *foo* 42)
Then lexical variables appeared and
SETQ
began to be used for their assignment, so
SETQ
no longer just a wrapper around
SET
.
Later, someone invented
SETF
(SET Field) as a generalized way of assigning values in data structures, mirroring L-values in other languages:
x.car := 42;
recorded as
(setf (car x) 42)
For symmetry and generality, the
SETF
also includes the
SETQ
functionality. It can be said that
SETQ
was a low-level primitive, and
SETF
was a high-level operation.
Then came the symbolic macros. Since the character macros are transparent, it was done so that the
SETQ
behaves as a
SETF
in the case when the assigned “variable” is actually a character macro:
(defvar *hidden* (cons 42 42)) (define-symbol-macro foo (car *hidden*)) foo => 42 (setq foo 13) foo => 13 *hidden* => (13 . 42)
And here we are in our days:
SET
and
SETQ
are essentially an atavism, left over from the old dialects, and may be thrown out of what will be the next Common Lisp.
Always use
SETF
.
'(1 2 3) or (list 1 2 3)?
The short answer is: write
(list 1 2 3)
until you understand the difference. If you write
'(1 2 3)
do not modify it destructively (i.e. using
SORT
or
NREVERSE
).
Detailed answer: First, the single quote is a macro that converts
'anything
at
(quote anything)
while reading so
'(1 2 3) === (quote (1 2 3))
Secondly,
QUOTE
is a special operator that returns its arguments not computed. So
'(1 2 3)
returns a literal list. As with most languages, modifying literal data leads to undefined consequences. For example, the compiler can connect constants containing literals:
(let ((a '(1 2 3)) (b '(1 2 3))) (eq ab))
The consequence is the fact that changing A can also change and B. Then what is
QUOTE
good for? If, for example, you have large immutable lists that the compiler can put together, then marking them as literal gives the compiler the right to do so.
What the * Ears *?
Whatever you use to declare variables,
DEFVAR
or
DEFPARAMETER
, always do * SUCH-NAME *. And do not do this for local variables.
(defvar *-* ...) (defvar -- ...)
What for? If you still do not know what special variables are, continue to read the book you are reading and come back as you finish, but for now use the ears.
Ears protect against two simple mistakes that are very easy to make.
Error 1: random binding of a special variable.
(defparameter foo "foo!") (defun say-it () (write-line foo)) (defun say-more (foo) (say-it) (format t "now say ~A~%" foo))
Now
(say-more "bar!")
will print
say bar! now say bar!
instead of the expected
say foo! now say bar!
... oops!
Error 2: due to a typo, reading is made from a special instead of a local variable; no warning is issued.
Usually you will receive a compile-time warning and a run-time error in case
(defun foo (bar) bat)
but if you write before
(defparameter bat "baseball")
then there will be no error and you will spend a lot of time debugging, trying to figure out what is wrong.
If you are writing code for yourself, it doesn’t matter whether you put your ears or not, but when you publish a code, the absence of * ears * means a waste of other people's time. Do not do this, please!
The absence of ears creates a sense of error: when I see
(defparameter - ...)
I understand that it is necessary to read the code with particular caution, because there is no guarantee that the code that looks quite harmless from the first sight will not have non-local side effects or dependencies.
Always put * ears *. They say that there are exceptions to all the rules, but in this case it is very difficult to find a real exception to this rule.
Good code
- Nikodemus