How to install Common Lisp and SLIME on MS Windows

Goal of this article is to show that it is now easy to install these stuff on MS Windows (or at least on Windows 7 & 8). Like boiling rice, it turns out to be easy. To be fair, maybe it wasn’t easy in old days.

Readers are assumed to be long time Emacs users who are at least familiar with Emacs key notation and are assumed to be Common Lisp beginners. I will also assume you are using the latest stable version of GNU Emacs.

1. how to install CLISP and SBCL on MS Windows

CLISP and SBCL are two Common Lisp implementations. Let’s install both because choosing between jajangmyeon and jjamppong is hard.

SBCL stands for Steel Bank Common Lisp. I don’t know what CLISP stands for but you need to know that it does NOT stand for Common Lisp. (Elisp still stands for Emacs Lisp, unofficially.)

1.1. Installing CLISP

How I installed it is I downloaded the installer from
http://sourceforge.net/projects/clisp/files/latest/download
and I chose “Typical” during installation.

1.2. checking if installation was successful

Open Command Prompt and type clisp and enter. It will show CLISP REPL. Now you can type (+ 1 1) and press enter to see that it evaluates to 2.

1.3. Installing SBCL

How I installed it is I downloaded an installer from https://github.com/akovalenko/sbcl-win32-threads/wiki and ran it. There are many installers on that page and “MSI package for 32-bit Windows” is probably what you want.

( Update: the other day, I installed using an installer from the official SBCL page, and it works.)

1.4. checking if installation was successful

You may have to reboot your computer. Then open Command Prompt and type sbcl and enter, and so on.

2. Lisp modes on Emacs

Before we start, let’s get familiar with some Lisp mode names in Emacs. Vanilla Emacs provides at least three Lisp major modes:

  • emacs-lisp-mode (major mode just for Emacs Lisp)
  • lisp-mode (major mode for other lisp dialects)
  • lisp-interaction-mode (major mode derived from emacs-lisp-mode for the scratch buffer.)

Paredit and SLIME are Lisp minor modes and they are not shipped with Emacs.

3. how to install SLIME

You can install SLIME from MELPA. See how to install just one package from MELPA and not others

Update: You can also use quicklisp to install SLIME but I have not tested that way of installation. The rest of this article is tested only for SLIME installed from MELPA.

4. some minimal SLIME customization

SLIME doesn’t work out of the box.

Your Emacs init file probably has these two lines somewhere:

(package-initialize)
(setq package-enable-at-startup nil)

Now you need to put the following code somewhere after those two lines:

(setq inferior-lisp-program "sbcl")
(setq slime-auto-connect 'ask)

(defun my-slime-setup ()
  (require 'slime)
  (slime-setup))
(defvar my--slime-setup-done nil)
(defun my-slime-setup-once ()
  (unless my--slime-setup-done
    (my-slime-setup)
    (setq my--slime-setup-done t)))
(defadvice lisp-mode (before my-slime-setup-once activate)
  (my-slime-setup-once))

Then restart Emacs and create a new lisp file in Emacs. (the file name should be something like blahblah.lisp) SLIME mode should be automatically enabled on that buffer and you should see the word Slime in the mode line. Now write the following Common Lisp code in that buffer:

(mapcar #'+
        (list 10 20 30)
        (list 1 2 3))

Try to evaluate that form by using either C-M-x which is bound to slime-eval-defun (for evaluating a top level form), or C-x C-e which is bound to slime-eval-last-expression (for evaluating the last expression before cursor), or C-c C-r which is bound to slime-eval-region (for evaluating the selected region). Wait enough and the result of evaluation will be displayed in the echo area. Not so different from evaluating Emacs Lisp forms. When you evaluate a Common Lisp form for the first time, SLIME spends some time starting up a Common Lisp process and setting up a connection to it, and when it’s the first time starting up such a process, SLIME spend some more extra time doing some stuff. It may take a long time.

5. troubleshooting SLIME customization gone wrong

When you start changing the main structure of my example SLIME customization code, things may go wrong but don’t worry, this section might help you.

When you manually do M-x slime (which you don’t have to with my customization example) and it results in this message:

apply: Searching for program: permission denied, lisp

it may mean that your Emacs init file did not make sure slime-setup to be called, or that the value of inferior-lisp-program is lisp.

When you press C-M-x on a Common Lisp buffer and it says:

Process lisp does not exist

it may mean that SLIME mode is off for some reason or that the value of inferior-lisp-program is lisp.

When you press C-M-x on a Common Lisp buffer and it says:

slime-connection: Not connected.

it may mean that your Emacs init file did not make sure slime-setup to be called or that you forgot to do M-x slime.

6. first things to know about using SLIME

A bit of diversion first. Let’s check the four must features of Lisp editors:

  1. indentation
  2. selecting a form
  3. clipboard management
  4. inserting the closing paren automatically for you.

You indent your Common Lisp code using TAB or C-M-\ the same as usual. Selecting forms can be done by pressing C-M-SPC multiple times (after maybe moving up using C-M-u multiple times), again the same as you already do with Emacs Lisp code. For clipboard management, you are already either using Emacs’s kill ring feature or an external clipboard manager. Now the fourth thing: automatic insertion of a closing parenthesis upon your insertion of an open parenthesis. You are probably already using something for that, ParEdit or SmartParens or AutoPair or electric pair mode. If not, time to choose. I have an article on how to install AutoPair. AutoPair is stable and is a team player. ParEdit is also stable, is only for Lisp modes, and it bans you from making unmatched parens, and that’s a good thing, but some may not like that. SmartParens and electric pair mode are the new kids. If you want me to choose one for you, I choose ParEdit if you can live with three keys <C-left>, <C-right>, <C-backspace> doing odd things, or if you know how to unbind those keys. End of diversion.

The key C-M-i is bound to slime-complete-symbol which is for completion of function names and so on. That is again just like when you are editing Emacs Lisp code.

Now try writing the following Common Lisp code but this time using C-M-i to help you complete dolist and print (pretend that you forgot the spelling for dolist)

(dolist (num (list 1 3 5 7 10 1 1 1 1 1))
  (if (evenp num)
      (progn
        (print "found an even number. gonna return it")
        (return num))
      (print num)))

Now evaluate that using C-M-x. The eval result 10 will be shown. Where’s the output from print? The output is in the *inferior-lisp* buffer. You have to switch to it to see the output. OK, this one was a bit different from evaluating Emacs Lisp code involving print, but even in Emacs Lisp buffers, when you evaluate a form that prints a long output, you switch to the *Messages* buffer to see it. If you don’t like switching to the *inferior-lisp* buffer, you may want to try these commands: slime-pprint-eval-last-expression and slime-pprint-eval-region.

You might have noticed something happening in the echo area when you were writing the dolist form. That’s the command slime-space (bound to SPC) showing argument lists of Common Lisp functions for you. Just like the ElDoc minor mode that you probably use with Emacs Lisp buffers. This feature only starts working after SLIME starts a Lisp connection, but you know that is guaranteed to happen when you evaluate a form or use C-M-i to complete a function name.

Try evaluating the following Common Lisp code:

(/ 1 0)

Just as you expected, an error is signaled and you are now in debugger. How do you get out then? How to quit this debugger? You should see a new submenu in the menu bar: SLDB. That stands for SLime DeBugger mode. From that submenu, you can find a way to quit the debugger. Or if you have time, you can press C-h m to start learning how to use SLDB.

7. looking up Common Lisp documentation

When you invoke the command slime-documentation-lookup (bound to C-c C-d h and a menu item), it will look up the documentation for symbol at point and open the web page for it.

8. downloading Common Lisp HyperSpec (CLHS) for use in SLIME

You don’t have to download it to look things up, but if you want offline access, you can download it from LispWorks Downloadable Documentation.

To connect your downloaded documentation to SLIME, extract the downloaded archive and you will get a folder with name Hyperspec, and then you move that folder to the Emacs bin directory, or its parent directory, or its grandparent directory, Put the following code in Emacs init file.

(defun my-hyperspec-setup ()
  (let ((dir (locate-dominating-file invocation-directory "HyperSpec/")))
    (if dir
        (progn
          (setq common-lisp-hyperspec-root (expand-file-name "HyperSpec/" dir)))
      (warn "No HyperSpec directory found"))))

and add my-hyperspec-setup to my-slime-setup like this:

(defun my-slime-setup ()
  (my-hyperspec-setup)
  (require 'slime)
  (slime-setup))

and restart Emacs.

Now when you invoke slime-documentation-lookup it will open the local web page instead.

9. further customization how

When you see this from others code

(require 'slime)
(slime-setup)

(blahblahblah)
(blahblah)
(blahblah)

the right way to replicate that in your own Emacs would be to add the relevant part to my-slime-setup like this:

(defun my-slime-setup ()
  ;; (my-hyperspec-setup)
  (require 'slime)
  (slime-setup)

  (blahblahblah)
  (blahblah)
  (blahblah))

10. why the unusual way of customization

The reason for the odd way of invoking my-slime-setup in my code is so that my-slime-setup gets called when you open a Common Lisp file the first time and not during Emacs startup. This is so that my code does not slow down Emacs startup.

11. how to visually distinguish common lisp buffers from emacs lisp buffers.

You can put this in your init file to make parenthesis of Common Lisp code (and Scheme and Clojure) to be a bit red to distinguish Common Lisp buffers from Emacs Lisp buffers.

;;; Red the color of Common Lisp
;;; Black the color of Emacs Lisp

(defface my-common-lisp-paren-face
  '((((class color) (background dark))
     (:foreground "sienna3"))
    (((class color) (background light))
     (:foreground "sienna3")))
  "Face used for common lisp parentheses.")

(dolist (mode '(scheme lisp clojure))
  (font-lock-add-keywords
   (intern (concat (symbol-name mode) "-mode"))
   '(("(\\|)" . 'my-common-lisp-paren-face))))

Or you may want to do the other way around.

13. some differences between CLISP and SBCL

Doubly nested backquote forms are handled in different but still CLHS-compatible ways. See CLHS “innermost backquoted form should be expanded first” meaning – Stack Overflow to see how two seemingly different ways may be equivalent in a way after all.

This entry was posted in Emacs, Lisp and tagged , , . Bookmark the permalink.

4 Responses to How to install Common Lisp and SLIME on MS Windows

  1. andy peterson says:

    You can use quicklisp (the common lisp package manager) to download slime and install slime.
    See http://www.quicklisp.org/beta/#slime. When you update quicklisp packages, it will also update slime. Updates are monthly.

  2. Pingback: Lisp and Slime on Windows | Irreal

  3. The CLHS is also downloadable via Quicklisp with my CLHS ASDF wrapper (http://www.hexstreamsoft.com/libraries/clhs/), which also provides instructions for configuring Emacs/Slime to use it:

    (ql:quickload “clhs”)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s