* Nikodemus' Common Lisp FAQ 2007-04-14 This is a highly uncanonical Common Lisp FAQ with a strong editorial bias, by Nikodemus Siivola. Partially based on various comp.lang.lisp and general Lisp FAQs. If you think I've stolen your words I'm all to happy to 'fess up, so feel free to drop a line to . Current version of this FAQ is available from: http://random-state.net/files/nikodemus-cl-faq.txt This FAQ is posted to comp.lang.lisp every once in a while. ** Just starting out *** How can I learn Common Lisp? (1) Read a good book on Common Lisp. (2) Start using it. Many people seem to manage the first stage over and over again, but fail to act on the second one. Seriously: you cannot learn any programming language without using it, nor can you really understand one without working on a moderately large program in it. *** Which book should I read first? Read Peter Seibel's `Practical Common Lisp', a.k.a. PCL. It is a good starting place if you already know how to program in some other language. It's available both online and in print: http://www.gigamonkeys.com/book/ Another alternative is David Touretzky's `Common Lisp: A Gentle Introduction to Symbolic Computation', which is a good choice if you are new to programming or find PCL too hard. Even if you start with this, read PCL afterwards. If you've already read PCL and understood it, you can safely skip this. Available both online and in print: http://www.cs.cmu.edu/~dst/LispBook/index.html There are plenty of other books too, but these two are the best bets for starters. However, you should familiarize yourself with the `Hyperspec', aka CLHS -- the online version of the language standard, which is an invaluable reference: http://www.lispworks.com/documentation/HyperSpec/index.html Don't try to read it right now. Just remember it is there, and contains the authoritative answer to all possible questions about CL: it is the perfect place to check if you find yourself in doubt about what a given operator does. It is also the place you should look in to discover if there is a builtin that already does what you need. Also, do not neglect the documentation that comes with your implementation. *** Which implementation should I pick? Depends on your needs, but as long as you are just starting out it really doesn't matter. However, if you are expecting a particular group of people to help you, do pick an implementation they are familiar with. Once you have learned more you can make an informed decision for yourself. Moving between implementations is not that big an issue, really, so there is no point in agonizing over initial choice. That said, I am is highly partial to SBCL: http://www.sbcl.org/ SBCL is open source, runs on a number of platforms (including experimental Windows support), has a pretty good native compiler, takes ANSI compliance pretty seriously, and generally bring happiness and joy to the world. ...but then I would say that, since I am one of its developers and my company Steel Bank Studio Ltd provides commercial support for it. *** Which IDE should I use? If you are using SBCL, then you want to use Emacs and Slime: http://www.common-lisp.net/project/slime/ Even if you haven't used Emacs before, do yourself a favor and use Slime -- the learning curve isn't all that long, and you can get at the commands from menus too. If you are using another implementation, use the IDE the implementors recommend for it (though Slime works with practically every implementation). If you really really hate Emacs, then there is an Eclipse plugin called `Cusp', but I won't vouch for it: http://www.paragent.com/lisp/cusp/cusp.htm If you really really love Vi, then you are out of luck. This picture explains why: http://www.xach.com/img/lisp-and-vim.png That said, some people do seem to be happy using Lisp just fine from Vi, but how they do that is quite beyond me. Look elsewhere for help on that. For a reasonable Lisp experience your editing environment should at least: autoindent lisp correctly; match parens; provide commands like "edit definition", "compile defun", "eval expression", "describe symbol", "disassemble function", "trace function", "inspect expression", etc. for interacting with you Lisp; provide integration with the Lisp debugger. Slime does all this and more. *** Common Lisp? CL? Clisp? Lisp? `Common Lisp' is the name of the ANSI standardized language this FAQ is about. `CL' is the preferred abbreviation of that name. `Clisp' is not an acceptable abbreviation, as it is the name of a specific Common Lisp implementation. `Lisp' is a category of languages to which CL belongs. Is hasn't been written as `LISP' for the last 20 years or so. Common Lisp often referred to as just Lisp when the context is clear. *** Is there a GUI? Yes and no. CLIM (Common Lisp Interface Manager) is a semi-standardized GUI API specification, quite different from widget & event-loop based GUIs. Don't expect it to feel familiar immediately. http://random-state.net/files/how-is-clim-different.html Some people swear it is the best thing since sliced bread, and some people think sliced bread is better for building GUIs then it is. At any rate, most commercial implementations provide a CLIM implementation, and there exists a portable open source implementation called McCLIM, which has been making great strides recently. http://common-lisp.net/project/mcclim/ CLX is a portable low-level X11 interface written in Lisp, providing a level of abstraction similar to Xlib. http://www.cliki.net/CLX A number of portable widged-based GUI libraries exist, of which LTK (Tk based) is probably the best bet if you need something portable and widget based right now. http://www.peter-herth.de/ltk/ CLG is probably the most thought out GTK+ binding at the moment, but supports only CMUCL and SBCL. http://sourceforge.net/projects/clg/ Commerical implementations tend to come with non-portable GUI libraries that their proponents seem quite fond of. If you use a commercial implementation and don't need portability then the vendor toolkit is a natural choise. *** Is there a CPAN equivalent? Yes and no. `Cliki' and `common-lisp.net' are what we have. http://www.cliki.net/ http://www.common-lisp.net/ Most libraries on CLiki are install-able using ASDF-INSTALL, which also takes care of dependencies. *** What online forums are there? Comp.lang.lisp on Usenet / Google Groups is probably the largest, but is also inhabited by several trolls. While many of the frequent writers are quite knowledgeable, uninformed speculation remains common. It remains, however, at the time of the writing the only non-interactive general purpose forum -- but reading it can be a stress-inducing experience, and is definitely not necessary in order to use Lisp. http://groups.google.com/group/comp.lang.lisp There are several special-purpose mailing lists which have vastly better signal to noise ratio: all implementations tend to have their own user- or help-lists, and most libraries have their own mailing lists. One list worth a special mention is `lispweb', a mailing list focusing on web development in lisp: http://www.red-bean.com/lispweb/ http://news.gmane.org/gmane.lisp.web The IRC channel #lisp on freenode.org is quite popular also, especially among the open source users and developers. ** Language features *** How do I compile a file? Short answer: start your Lisp, and type: (compile-file "/path/to/myfile.lisp") Then you probably want to LOAD the compiled file. Long answer: most compiled languages are non-interactive -- you compile a file from the command line or IDE, and then run the compiled file. Not so with Lisp. While you can generally speaking turn your project into an executable file, the typical Common Lisp development session does not resemble the edit, compile, run cycle you've come to expect. Normally you interact with a long-running Lisp process that holds your development session, and add code to it incrementally. For example: 1. Open Emacs, start Slime and Lisp with M-x slime. 2. Load existing code to Lisp using eg. ASDF. 3. Open the file you're interested in, edit a function, and then hit C-c C-c to recompile that single function. 4. Go to the Slime REPL and test your changes. 5. Go to step 3. The ASDF alluded above is "Another System Definition Facility", which can be used to describe the way several files form a single system, and allows the files to be eg. compiled and loaded with a single command. Sort of like Make, but not at all like it really. *** How do I make an executable? The answer depends on the implementation you are using. Refer to its documentation. That said, if you are using SBCL: ;; First load you application into SBCL, then do this. MY-FUNCTION ;; is the entry point to your application. (save-lisp-and-die "my.exe" :executable t :toplevel 'my-function) *** FUNCALL and APPLY -- what's the difference, which one should I use? Short answer: Use FUNCALL if you can, APPLY otherwise. Long answer: With FUNCALL the number of arguments must be known at the call site. With APPLY (and MULTIPLE-VALUE-CALL) the number of arguments need not be known. (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 reason to write MAP-LIST-WITH-1 using APPLY, and FUNCALL is almost certain to be more efficient here. In contrast, MAP-LIST-WITH-N cannot be written using FUNCALL, as the number of arguments is not known at the call site -- APPLY has to be used. *** SET, SETQ and SETF -- what's the difference, which one should I use? Short answer: Always use SETF. Long answer: Originally, in the days of yore, long before there was Common Lisp, there were no lexical variables -- only dynamic ones. And there was no SETQ or SETF, just the SET function. What is now written as: (setf (symbol-value '*foo*) 42) was written as: (set (quote *foo*) 42) which was eventually abbreviavated to SETQ (SET Quoted): (setq *foo* 42) Then lexical variables happened, and SETQ came to be used for assignment to them too -- so it was no longer a simple wrapper around SET. Later, someone invented SETF (SET Field) as a generic way of assigning values to data structures, to mirror the l-values of other languages: x.car := 42; would be written as (setf (car x) 42) For symmetry and generality, SETF also provided the functionality of SETQ. At this point it would have been correct to say that SETQ was a Low-level primitive, and SETF a high-level operation. Then symbol macros happened. So that symbol macros could work transparently, it was realized that SETQ would have to act like SETF if the "variable" being assigned to was really a symbol macro: (defvar *hidden* (cons 42 42)) (define-symbol-macro foo (car *hidden*)) foo => 42 (setq foo 13) foo => 13 *hidden* => (13 . 42) So we arrive in the present day: SET and SETQ are athropied remains of older dialects, and will probably be booted from eventual successors of Common Lisp. Just Use SETF. *** '(1 2 3) or (list 1 2 3)? Short answer: Use (list 1 2 3) unless you understand the difference. If you have '(1 2 3) to deal with, don't modify it destructively. (Eg. with SORT or NREVERSE.) Long answer: First off, the single quote is a read macro, transforming 'anything into (quote anything) at read-time, so '(1 2 3) === (quote (1 2 3)) Secondly, QUOTE is a special operator that returns its argument unevaluated. So, '(1 2 3) returns a literal list. Like in most languages, modifying literal data leads to undefined consequences. For example, the compiler is allowed to coalesce constants including literals: (let ((a '(1 2 3)) (b '(1 2 3))) (eq a b)) ; => T or NIL The upshot of which is that modifying A may also modify B. What is QUOTE good for, then? If you have eg. large constant lists that you would like the compiler to coalesce, then putting them in as literal constants gives the compiler licence to do so.