Are you trying to get started with Common Lisp but find it difficult to make progress? People keep on saying that there are plenty free resources available online. Maybe you have even found most of them … and yet the questions remain … What is the Lisp syntax? Are there any libraries and how do I find them? Can I compile my program into a binary or are users forced to install a compiler?
The list goes on: What is the meaning of those asterisks around the *VARIABLE* names? Which implementation should I use? Where do I go for help when I get stuck?
How do I connect my IDE to the debugger because really … who in their right mind want learn Emacs just to use Common Lisp?
There are plenty learning resources on the web. For free. In the wonderful world of Common Lisp you always have multiple choices to achieve your goal. Starting with the choice of which implementation you should use.
In some aspects this post is similar to many of the other “Getting Started” articles and in some aspects it is different. This is my take on which initial choices to make and why. The choices are neither better nor worse than the alternatives but importantly, they are not binding. At any point in the future you can switch away from any of the choices I made without severe impact on your progress. The important thing is to accept some set of initial choices and to get started. You will only discover through experience whether you agree or disagree with the choices.
Common Lisp is a vast ocean of possibilities, stretching infinitely and with no horizon… And here I am pretending to understand the MOP while trying not to end up in r/badcode, like a child playing in the surf…
The steps
Before you can start working seriously you need a functional development environment. The Portacle project can give you a jump start here. It packages all the recommended tools to provide a ready-made Lisp development environment. If you choose this option configure Portacle then start with step 4 below. Installation instructions are on the Portacle page.
I prefer to install software natively. If you choose this option follow the steps from the beginning.
- Set up a Lisp implementation.
- Set up the library installer.
- Set up the development environment.
- Locate reference documentation.
- Pick a project.
- Deploy your program.
Set up an implementation
There are a number of Common Lisp implementations available, each with its own unique features. If you don’t know why you need to use a specific implementation, use CCL (Clozure Common Lisp) or SBCL (Steel Bank Common Lisp). They are easy to set up because they don’t have any external dependencies. Since Common Lisp is a standardised language you can trivially switch implementations later if you really need to.
Many people prefer SBCL. If your OS has an installation package for it, use that. Otherwise you can find the installation instructions on the website.
I prefer to use CCL because it has faster compile times than SBCL.
Install CCL
Download the version for your OS. Use the SVN method because that makes it easier to upgrade later on.
$ svn co http://svn.clozure.com/publicsvn/openmcl/release/1.11/linuxx86/ccl
Copy the file ccl/scripts/ccl64 to a directory that is in your path. On Linux a good place is /usr/local/bin. Rename it to “ccl”
$ cp ccl/scripts/ccl64 /usr/local/bin/ccl
Edit the script in /usr/local/bin. Change
CCL_DEFAULT_DIRECTORY=/usr/local/src/ccl
to point to the place where you
installed CCL
Run “Hello world”
Start CCL
$ ccl
In the REPL, execute
? (format t "Hello world!")
The command should print
Hello world!
Exit the REPL with
? (quit)
Set up the library installer
The easiest way to obtain and install libraries is to use Quicklisp.
The following steps set up Quicklisp in your Lisp implementation:
-
Download the setup script. In Linux it would be
$ wget https://beta.quicklisp.org/quicklisp.lisp
-
Install Quicklisp in CCL:
Start CCL
$ ccl
In the REPL, execute
(load "quicklisp.lisp") (quicklisp-quickstart:install) (ql:add-to-init-file)
-
Test the installation
? (ql:system-apropos "alexandria")
The command should print information about the Alexandria library. Something like this:
#<SYSTEM alexandria / alexandria-20170630-git / quicklisp 2017-07-25> #<SYSTEM alexandria-tests / alexandria-20170630-git / quicklisp 2017-07-25>
Set up a development environment
Picking a text editor
One of Common Lisp’s biggest productivity advantages is the REPL (Read-Evaluate-Print Loop). It looks and functions a lot like the operating system’s command line interface which executes commands as they are entered. Variables and defined functions remain available throughout the REPL session. New functions can be defined one at time.
In contrast to languages like C where your program must be compilable before you can test any change, in the REPL you can compile only the function you want to test without having a complete application.
To understand the implication, suppose you have function A which is called by many other functions throughout the application and you want to change A’s argument list. In C you’d have to update all the functions that call A before you can compile the program to actually test the change. In Common Lisp you can make the change, update one function and test it. Only when you are satisfied with the results you have to update the other calling functions.
The described workflow is completely possible with any random text editor and loading the source files directly in the REPL. After making and testing changes in the REPL only the final modifications need to be transferred to the source files. While using Lisp in this way is possible, there is a disconnect between the text editor and the Lisp implementation which can negate the advantages brought by the REPL.
When the text editor is able to control the REPL it allows you to make exploratory changes directly in the source files then compile and test only the modifications. At the end of this exploratory cycle the source files are already up-to-date and all that remain is to update the rest of the calling functions.
The tool that enables control over the REPL is called SLIME1. It is the most advanced and mature tool for this purpose and it is specifically developed for Emacs. SLIME has been adapted for use in other editors2 but they have fewer users and contributors and thus always lag behind the latest SLIME development.
When setting out to learn Common Lisp the path of least resistance is to use Emacs, even with all its foreign concepts and non-standard shortcut keys. Once one appreciates the power and productivity because of SLIME it is easier to look past Emacs’ aged appearance and arcane user interface.
Install SLIME
In the CCL REPL, run the following:
? (ql:quickload "quicklisp-slime-helper")
Install Emacs
Installing Emacs should be trivial. Most Linux distributions provide installation packages in their repositories and the Emacs web page provides installation instructions for Windows and macOS.
When Emacs is working, edit or create the file ~/.emacs
. To locate the file
on Windows, use the File | Visit New File menu item and type ~/.emacs
as the
filename.
Place the following code in .emacs
.
;; Set up CCL
(setq inferior-lisp-program "ccl")
;;Load Quicklisp slime-helper
(load (expand-file-name "~/quicklisp/slime-helper.el"))
Exit and restart Emacs.
Using Emacs
Emacs’ key bindings (i.e. shortcut keys) differ significantly from the standard shortcut keys used in most other editors. If you don’t know some basics and your menu bar happens to become hidden you will be helpless. This is a bare minimum introduction to using Emacs so that you will be able to edit Lisp files and run them with SLIME. The EmacsWiki key reference page has a much more thorough list.
Emacs shortcuts are a combination of a modifier key with a normal key. The modifiers are:
C
-Control
key.M
- Meta key.ALT
on PCs and⌘
on Apple.S
-Shift
key.
Key combinations are written as C-x
which means press and hold Control
and
then press x
.
C-x C-c |
Exit Emacs |
C-x C-f |
Open or create file |
C-x C-s |
Save file |
C-x k |
Close file |
M-w |
Copy selected text |
C-w |
Cut selected text |
C-y |
Paste text |
C-/ |
Undo |
C-x h |
Select all |
C-x b |
Switch between buffers |
M-x slime |
Start SLIME |
C-c C-z |
Switch to SLIME from a Lisp buffer |
C-c C-c |
Compile the function at the cursor |
C-c M-q |
Indent the function at the cursor |
C-up/down |
Move through history in SLIME buffer |
If you really want to do copy, cut and paste with the same keys used in other applications then you can search for Emacs CUA mode.
Run “Hello world”
Start SLIME
M-x slime
The first time you run SLIME there may be some delay while it is being compiled. When it is ready you should see the following in Emacs:
; SLIME 2.19
CL-USER>
In the REPL, execute
CL-USER> (format t "Hello world!")
You should see
Hello world!
printed on the screen.
Programming and debugging
With the power of the SLIME / Emacs combination and Common Lisp’s “vast ocean of possibilities” there are many ways to use the tools. Each programmer will eventually develop his or her own distinct technique.
Without spending too much time learning Emacs or SLIME early on one can become quite productive using the following approach:
Big changes:
- Edit a file
- Save the file -
C-x C-s
- Jump to the SLIME REPL -
C-c C-z
- Load the file -
(load "app.lisp")
- Run the code -
(some-function)
Small changes
- Edit a file
- Save the file -
C-x C-s
- Compile the function -
C-c C-c
- Jump to the SLIME REPL -
C-c C-z
- Run the code -
(some-function)
Locate reference documentation
When you get stuck Stack Overflow can be useful but often you get answers faster if you know about other sources of information. I posted previously on the topic of finding answers. Here is another list which is more relevant if you are only getting started.
- Learn the language
- Practical Common Lisp
- Naming conventions
- Lisp-lang
- Cliki
- Find libraries and their documentation
- Quickdocs
- Common Lisp Language reference
- HyperSpec
- Help with Emacs
- EmacsWiki
- Use SLIME more effectively
- SLIME manual
- More introductory material
- Articulate Lisp
- When all these are not enough
- Reddit r/lisp sidebar
Pick a project
To learn a new language you must write a program and for that you need a project. I have posted some ideas for beginner projects before but I think it is easier to stay motivated when you work on your own idea.
With the project in hand you now have everything to start programming and learning. At the very beginning it is easier to write all the code in one file. Loading the program is straightforward and it removes a lot of extra variables introduced when system definition files and multiple source files come into play. They are essential for bigger programs but they cause an unnecessary mental burden when you are still finding your feet.
The moment a single file becomes too convoluted to continue, stop programming and create a project skeleton with Quickproject. It creates a minimal project with all the necessary files to make it loadable with ASDF and Quicklisp.
The steps to create a project skeleton are:
(ql:quickload :quickproject)
(quickproject:make-project "path/to/project/")
Deploy your program
Common Lisp programs can be compiled into standalone executables or they can run from source code.
Buildapp is my tool of choice for creating executables. I posted before on how use it.
Server-side software are usually run from source code. Depending on how your application startup code looks like it can be as simple as
ccl -l app.lisp
Footnotes:
-
SLIME - The Superior Lisp Interaction Mode for Emacs. ↩
-
See the “Tools” section in the Reddit sidebar. ↩