📜 ⬆️ ⬇️

Nikodemus' Common Lisp FAQ

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.txt
http://random-state.net/files/nikodemus-cl-faq.html
FAQs 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?

  1. Read a good book on Common Lisp.
  2. 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:

  1. 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.
  2. 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.
  3. 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.html

There 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.html

Do 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/manual

What 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:


Commercial:


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:



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=2531
https://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.html

Many 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/CLX
https://github.com/sharplispers/clx

Unless 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.lisp

Specialized 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-help

Among 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/pro

Language 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:

  1. open Emacs, use Slime and Lisp with Mx slime ;
  2. using, for example, ASDF, load the existing code;
  3. open the desired file, edit the function and press Cc Cc , which will recompile it;
  4. go to the Slime REPL and test the changes;
  5. 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:

 ;;    SBCL,    save-lisp-and-die. ;;     - MY-FUNCTION. (save-lisp-and-die "my.exe" :executable t :toplevel 'my-function) 


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)) ; => T  NIL 


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

Source: https://habr.com/ru/post/143618/


All Articles