Common Lisp学习笔记(0):从SLIME开始

按:本文是我在阅读Peter Seibel所著的Common Lisp教程Practical Common Lisp(免费在线阅读地址:http://gigamonkeys.com/book/)的学习笔记。这篇文章的主要内容包括Common Lisp的介绍以及如何搭建Common Lisp编程环境(SBCL + Emacs + SLIME)两部分。因为本文并不怎么涉及Common Lisp的具体知识,所以编号为0。

目录

什么是Common Lisp

在讲解一样东西前先对它进行一番介绍是个好习惯,所以本文的第一个内容便是对Common Lisp的介绍。

Common Lisp是一中编程语言,它是Lisp的诸多方言中的一种。

Lisp的原始写法似乎应该是LISP,即LISt Processor的缩写,不过Lisp这种写法似乎比LISP更常见(而且,在我看来,也更可爱 = =)。Lisp是John McCarthy在1960年左右创造的一种基于λ演算的函数式编程语言,可以说是历史悠久、源远流长(其古老程度和FORTRAN老哥有一拼)。当然在初期由于没有什么统一的规范或者标准,不同的人采用了不同的方式对Lisp进行实现,也就出现了许多方言,Common Lisp便是其中一种(另一个主要的Lisp方言是Scheme,此外还有一个和Emacs一起的Emacs Lisp)。

我是通过Peter Seibel所著的Practical Common Lisp一书(免费在线阅读地址:http://gigamonkeys.com/book/)来学习Common Lisp的。此前我有翻过Paul Graham的ANSI Common Lisp,尽管我是被后者的作者的洗脑带上学习Common Lisp的道路的,但我认为它并不适合作为Common Lisp的入门教程(尽管看起来它的定位是Common Lisp入门教程),读这本书会感觉很累,而且恐怕要很久以后才能看到Common Lisp的优势(我读这本书读了好几章都没读到)。而Peter Seibel的这本Practical Common Lisp的第三章便有一个实际的项目——实现一个非常简单的音乐数据库,在这一开始你就能对Common Lisp的各种概念(包括Paul Graham所极力称赞的macro)有一个大致的了解。

搭建Common Lisp编程环境

搭建Common Lisp编程环境的方法有很多种,这里我使用的是最常见的一种:SBCL + Emacs + SLIME。

SBCL是Steel Bank Common Lisp的简称,它是Common Lisp的一种高质量的开源实现,可以运行在Linux和OS X上。其他著名的Common Lisp的实现还包括Allegro Common Lisp(商业软件,可运行于Linux,Windows以及OS X),OpenMCL(开源软件,据说非常适合OS X用户)等。我是直接使用Fedora的yum软件安装的SBCL,命令如下:


Emacs是Editor MACroS的简称(吐槽:这是哪门子的缩写),它是Linux下最受欢迎的两个文本编辑器之一(另一个是vim)。虽然从个人喜好上来说我对vim更有爱(吐槽:Emacs在设计的时候压根没考虑过我们这种二指禅用户的用户体验!),但是因为我没有找到vim上的类似Emacs SLIME的好东西(似乎有个叫Limp的东西,但名气不大我也就没去用 = =),所以还是选择了用它来搭建我的Common Lisp编程环境。在Fedora上可以直接使用yum软件安装Emacs:


SLIME是the Superior Lisp Interaction Mode for Emacs的简称,从它的名字上你就能知道它是干什么的,简单来说,使用它我们可以非常轻松地体验Common Lisp编程的REPL(Read-Eval-Print Loop)旅程。在Fedora上依然可以直接使用yum软件安装SLIME:

只是安装完Emacs和SLIME以后还不能进入说好的Lisp Interaction Mode,可以通过修改~/.emacs文件为其进行配置。官方的说明是这样的:

有看过Lisp代码的童鞋会发现,其实上面的配置文件本身就是Lisp代码,没错,Emacs这个被称作“神之编辑器”的东西就是使用Lisp语言进行扩展的。上面的文件中的第一行和第二行里需要填写Lisp system(在我这个例子中,即SBCL)和SLIME的路径,因为yum使用的软件管理程序是rpm,所以可以通过使用下面的命令就可以查看SBCL和SLIME的安装路径:

根据返回的结果编辑~/.emacs文件(话说,我竟然是使用vim编辑~/.emacs……),其中Lisp system的路径填写sbcl(或者其他的Lisp实现)的二进制文件路径就好(在我的例子中就是/usr/bin/sbcl),SLIME的路径应该填写那个放着包括swank-loader.lisp等很多lisp文件的目录(在我的例子中就是/usr/share/common-lisp/source/swank/),修改后我的~/.emacs文件如下:

然后打开Emacs,在键盘上敲击M-x(在普通PC机上即同时Alt键和x键,下同),然后输入slime即可进入传说中的Lisp Interaction Mode。

注:经过这一步骤如果出现如下问题:

可以参考这里的解决方案(建议采用这种方法),或者在~/.emacs文件尾部添加如下代码:


进入SLIME后即可直接在里面输入Lisp代码,敲击回车键后代码会立刻被执行并输出结果,然后等待你输入下一段代码(知道为什么叫Read-Eval-Print Loop了吗?)。例如Hello World的程序代码:

得到结果如下:

其中第一行是因为执行format函数而输出到屏幕上的文字,第二行则是format函数的返回值。有过Ruby编程经验的朋友一定会对此感到十分亲切。

还可以通过输入C-x(在普通PC机上即同时Ctrl键和x键,下同),C-f,然后输入文件名来打开(如果存在)或者新建(如果不存在)一个文件。譬如我们可以新建一个hello.lisp,然后输入如下代码:

然后在Emacs中移动光标到这两行中的任一行,输入C-c,C-c,即可编译这段代码到SLIME中,然后输入C-x,b,回车(其实是切换到了上一次打开的缓冲区)后进入SLIME,输入:

会发现得到了和上次一样的输出,说明我们成功编译了一个名叫hello-world的函数并成功调用了它。再输入C-x,b,回车返回hello.lisp文件,可以通过C-x,C-s保存它。通过这种方式,我们很轻松地编写、编译、运行并保存了一个lisp文件。

编写一个Lisp文件
编译并运行一个Lisp文件


下面附上一些在Common Lisp编程中可能会比较常用的Emacs和SLIME快捷键(只列出一些我认为比较常用的,当然也欢迎补充):

文件操作缓冲区操作编辑操作其他操作SLIME操作

Emacs快捷键
C-x,C-f 打开或新建一个文件
C-x,C-v 打开或新建一个文件,取代当前缓冲区
C-x,C-s 保存当前缓冲区
C-x,C-w 把当前缓冲区另存为
C-x,C-b 打开缓冲区列表
C-x,b 切换缓冲区
C-a 移动光标到行首
C-e 移动光标到行尾
C-v 向下翻页
M-v 向上翻页
C-k 删除当前光标到此行行尾的所有字符(可以先使用C-a移动到行首以删除整行)
C-_ 撤销上一步操作(注意因为_是下划线,可能需要同时按住Shift键)
Esc,数字,某操作 执行n遍某操作,譬如Esc,5,C-k可以删除5行
C-c,C-c 编译并装载光标所在的整个Lisp Form
C-c,C-k 编译并装载当前缓冲区中的整个源文件