Monthly Archives: November 2013

Setting up a Lisp development environment

So, you might be interested in trying Lisp, but you need a development environment.  I’m afraid at this point some of my personal preferences are going to colour my answers.  I have Linux computers, and I use Emacs as my text editor.  Now, as for Linux, most of what I’m about to say is likely also true of Windows versions of these programs, but I cannot guarantee that because I am actually quite unfamiliar with Windows in any of its incarnations.

The first thing you should do is to download the Common Lisp HyperSpec by following the download directions here.  Install that somewhere in your filesystem.

This brings us to the text editor.  Yes, there are strong feelings about the choice of text editor, particularly among those who choose Emacs vs. those who choose vi.  Really, I’d suggest that Emacs, with its built-in Lisp language, is a natural choice for Lisp development, but there are some vi/vim pointers here.  As I’m writing here about my own experiences, I’m going to describe the Emacs option.

So, you’ve installed Emacs on your operating system of choice.  Now you have to choose a Lisp implementation.  I’m going to assume you want to start out with free software.  Maybe, eventually, you’ll decide that you want to buy a commercial Lisp, but for now, we’ll discuss free implementations.

I have three Lisp implementations installed on my machines.  There’s CLISP, SBCL, and ECL.  CLISP is fine, it has a readline-based REPL, so interactive use is easy, but you’ll quickly find that you don’t actually need to interact directly with the Lisp.  I’ve settled on SBCL for my own Lisp work.  It’s under active development, well-documented, and heavily used, which means external libraries are almost certain to have been tested against SBCL.  ECL is an interesting choice, it can actually compile Lisp code to machine-generated C code.  This way, you can write shared objects in Lisp, and call them from C and C++ code.  I wouldn’t use ECL for everyday projects, but if the C output is desirable, it’s a good choice.

So, now we come to the development environment.  That preferred choice for that is SLIME running in Emacs.  You have to download it separately, it does not usually come bundled with Emacs.  Now, when you start a programming project, you open Emacs and invoke SLIME with the command M-x slime<RET>.  My .emacs configuration for SLIME is here:
 

(setq load-path (append load-path '("/home/neufeld/lisp/slime")))

(setq inferior-lisp-program "sbcl"
      slime-net-coding-system 'utf-8-unix
      lisp-indent-function 'common-lisp-indent-function
      common-lisp-hyperspec-root "file:///home/neufeld/HyperSpec/")

(require 'slime)
(slime-setup '(slime-fancy slime-asdf))

Note that I have set a variable that points to the Common Lisp HyperSpec.  That allows SLIME to look up information when you need it.

Once you’ve started SLIME, your Emacs editor has some very nice features.  One which you will quickly learn to appreciate is that SLIME watches your typing, and fills in the message window at the bottom of the screen with usage information.  For example, if you type the sequence “(sort “, that is an open parenthesis, the word ‘sort’, and a space, then SLIME looks up the documentation for the function ‘sort’, and produces this information immediately on your screen:

(sort sequence predicate &rest args &key key)

If you’ve forgotten the order of parameters, or wonder what the optional keywords are, they’re right here on the screen, you don’t have to stop programming to look up the syntax.  Further, not only does SLIME do this with the built-in functions, but as you write your code and load it into the Lisp system, SLIME recognizes your own functions as well, and produces the same helpful output as you start using those functions.

While SBCL has a fairly hostile REPL (the prompt where you enter your code), you never have to interact with it when programming under SLIME, the SLIME program presents a consistent interface to the user, regardless of the particular Lisp back-end you choose.  That interface includes command history and searching, and is, by default, stored to disc so that your history survives through restarts of the Emacs instance.

So, you now have a working Lisp IDE.  Read the SLIME documentation to find helpful shortcuts, and start programming.

Calling a C library from Lisp, when no package exists to do so

I talked about how one could find packages written to support linking Lisp to many popular external libraries.  But what do you do if you want to use a less prominent library, one that hasn’t been set up in that way, or if you have a privately developed C library that you want to link to your Lisp code?

This is where we make use of the CFFI for Lisp.  I’m not going to repeat how to use it, there are certainly tutorials available on the web.  You might start with this one.  My purpose here is to point out its existence and describe some of its abilities.

To put it simply, you can use CFFI to link into a shared object library which exports a C interface.  Using the library’s header file, you can create a Lisp wrapper that calls into the library, and then easily use this library in any of your Lisp projects.

Finding libraries for Lisp programming

If you’re interested in trying out Lisp programming, you might wonder how you can find libraries for useful functions.  Maybe you want to try your hand at some Mandelbrot set generation, but don’t want to have to figure out how to write out the graphical files for viewing.  Perhaps you want to do something with networking.

The starting point I’d recommend is the common lisp wiki at www.cliki.net. There, you can find links to working libraries that perform many useful duties, and let you concentrate on the code you’re trying to write.  For instance, under graphics libraries, you will find about 70 entries ranging from PNG/JPG output to the Cairo API, to OpenGL linkages.  Chances are you’ll find what you need for your project there, and if not, there are other possibilities, as we’ll see later, when I talk about CFFI.

Lisp sounds interesting, but… Answering the Objections

I’ve written a few series of posts intended to introduce some of the features of Lisp that make it look and feel different from C++.  I’ve talked about macros, object-oriented programming, and exception handling, because the way these work in Lisp differs qualitatively from their C++ counterparts.

Differences in function names or minor differences in syntax are fairly trivial distinctions for the average C++ programmer, who might find him/herself exposed to such things frequently, writing Perl scripts, designing yacc/bison grammars, and so on.  But some of the differences between Lisp and C++ are quite fundamental, and experience with both might sometimes help the programmer to design their code, in whatever language they are using.  For some programmers, thinking in Lisp can clarify the problem, and some have argued that adding Lisp to one’s set of languages makes one a better programmer in all languages.  Whether or not that is true, Lisp can, at least, be entertaining for programmers who write code for the enjoyment of it.

As I’ve said before, I’m not trying to convince people to become Lisp programmers here.  This isn’t a “my language is better than your language” set of posts.  Even if it were, my most familiar programming language is still C++, Lisp for me is mostly for fun and for prototyping.  But perhaps you’ve been reading about Lisp, maybe here, maybe elsewhere, and have started to think you might want to play around with it a bit, just for fun.  But then some objections come to mind, and you’re not sure it’s worth the trouble to set up for Lisp programming.  I’m going to try to address some of these possible objections in another series of posts.

I’ll be addressing these objections over the next series of posts.

Collection of Lisp exception handling posts

Just putting all the links here in one place for easy access.  This was a 6-part series describing exception handling in Lisp, specifically to point out the similarities and differences to exception handling in C++.  I went over both the more familiar C++ try/throw/catch model and a restart technique that handles exceptions without unwinding the stack. Here is the series of posts:

Part 1

Part 2

Part 3

Part 4

Part 5

Part 6