引き続いて,SBCL のDebianへの標準インストールとSBCL+Slime + emacs環境について,インストール方法を以下にお知らせします.

「人工知能プログラミングのための Common Lisp 入門」の参加者で Linux環境で SBCL を使ってみようとされる方は,こちらの記述を参考にお願いします.

注意:テキストとしてコード部分をコピペしても,コマンド実行できない場合は,申し訳ありませんが,空白文字についてはスペースを手打ちしてください.

付録2 SBCL のインストール

付2.1 Debian にパッケージとしてインストール

SBCL を一番簡単にインストールする方法は,Debian や Ubuntu など Debian系の Linux にインストールするやり方である.ただし,Debian系でも openSUSE では YaST で SBCL を標準インストールできない.CentOS や Fedora のような RedHat系では標準パッケージとしては SBCL が提供されない.Debian 標準パッケージへの SBCL 取り込みはどうしてもワンテンポ・ツーテンポ遅くなるので,最新版を使いたい場合や RedHat系 Linux にインストールしたい場合には,直接本家のサイトからダウンロード・インストールすることになるが,本書の範囲では最新版をインストールするほどのことはない.以下の説明では Debian に標準パッケージとしてインストールする場合を対象に説明する.


GUIであれば,「アプリケーション」→「システムツール」→「ソフトウェアの更新」を使って,CUIであればroot 権限で「apt-get upgrade」を使ってシステムを最新状態にしてから,Synaptic パッケージマネージャか apt-get コマンドを使って SBCL と emacs 関連パッケージをインストールする.

# apt-get upgrade
...
# apt-get install emacs cl-swank slime sbcl
...

sbcl パッケージをインストール後,通常のユーザに戻ってコマンドラインに sbcl と打ち込むことで SBCL が起動する.

$ sbcl
This is SBCL 1.2.4.debian, an implementation of ANSI Common Lisp.
...
* t

T
* nil

NIL
* (quit)
$

ご覧のように,裸の SBCL のプロンプトはしごく簡単で味も素っ気もない.しかも Allegro Common Lisp のような Linux に類似のコマンドも使えない.そこで SBCL のライブラリとして提供されている sb-aclrepl を require することにする.

付2.2 SBCL ライブラリ sb-aclrepl を要求する

SBCL のライブラリは,/usr/lib/sbcl/ に保存されているが,ここにあるライブラリは単純に次のように require して使うことができる.

* (require :sb-aclrepl)

("SB-ACLREPL" "ASDF")
CL-USER(1): t

T
CL-USER(2): nil

NIL
CL-USER(3): :pwd
Lisp's current working directory is "/home/seiji/".
CL-USER(4): :cd ..
/home/
CL-USER(5): :cd ~
/home/seiji/
CL-USER(6): :exit
seiji@debian:~$

これで見かけ上,SBCL も ACL と同じようになった.第1部のプログラム説明では,常にこのライブラリが有効に使用されていると理解されたい.

付2.3 ライブラリマネージャ quicklisp を利用する

以前には Common Lisp には CPAN のような総合的で便利なライブラリ・リポジトリがないというのが問題とされていた.しかしこの状況は最近 quicklisp の登場によって劇的に改善された.本書においても,SBCL ではこの quicklisp を標準のライブラリ・リポジトリとして利用することにする.

Quicklisp 本家のサイトにあるインストール手続きに従って,以下のようにインストールする.ただし,curl を利用するので,まだインストールしていない場合には,最初に管理者権限で curl をインストールしてほしい.

root@debian:/home/seiji# apt-get install curl
...
root@debian:/home/seiji# exit
exit

次に通常ユーザとして curl を使って quicklisp をインストールする.

seiji@debian:~$ curl -O https://beta.quicklisp.org/quicklisp.lisp
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 57144 100 57144 0 0 10230 0 0:00:05 0:00:05 --:--:-- 14057
seiji@debian:~$
curl -O https://beta.quicklisp.org/quicklisp.lisp.asc
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 882 100 882 0 0 158 0 0:00:05 0:00:05 --:--:-- 218
seiji@debian:~$ gpg --verify quicklisp.lisp.asc quicklisp.lisp
gpg: ディレクトリー「/home/seiji/.gnupg/」ができました
gpg: 新しい構成ファイル「/home/seiji/.gnupg/gpg.conf」ができました
gpg: 警告: 「/home/seiji/.gnupg/gpg.conf」のオプションは起動している間、有効になりません
gpg: 鍵輪「/home/seiji/.gnupg/pubring.gpg」ができました
gpg: 2015年01月29日 06時13分26秒 JSTにRSA鍵ID 028B5FF7で施された署名
gpg: 署名を検査できません: 公開鍵が見つかりません

gpg では警告がいっぱい出るが,気にする必要はない.

次に quicklisp を使ってリモートからコピーしてローカルのライブラリリポジトリを作成する.

seiji@debian:~$ sbcl --load quicklisp.lisp
This is SBCL 1.2.4.debian, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.

SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses.  See the CREDITS and COPYING files in the
distribution for more information.

  ==== quicklisp quickstart 2015-01-28 loaded ====

    To continue with installation, evaluate: (quicklisp-quickstart:install)

    For installation options, evaluate: (quicklisp-quickstart:help)

* (quicklisp-quickstart:install)

; Fetching #<URL "http://beta.quicklisp.org/client/quicklisp.sexp">
; 0.82KB
==================================================
838 bytes in 0.01 seconds (136.39KB/sec)
; Fetching #<URL "http://beta.quicklisp.org/client/2015-09-24/quicklisp.tar">
; 240.00KB
==================================================
245,760 bytes in 0.00 seconds (48000.00KB/sec)
; Fetching #<URL "http://beta.quicklisp.org/client/2015-09-24/setup.lisp">
; 4.94KB
==================================================
5,054 bytes in 0.00 seconds (4935.55KB/sec)
; Fetching #<URL "http://beta.quicklisp.org/asdf/2.26/asdf.lisp">
; 194.07KB
==================================================
198,729 bytes in 0.86 seconds (226.45KB/sec)
; Fetching #<URL "http://beta.quicklisp.org/dist/quicklisp.txt">
; 0.40KB
==================================================
408 bytes in 0.00 seconds (99.61KB/sec)
Installing dist "quicklisp" version "2015-09-24".
; Fetching #<URL "http://beta.quicklisp.org/dist/quicklisp/2015-09-24/releases.txt">
; 313.76KB
==================================================
321,290 bytes in 0.00 seconds (156879.88KB/sec)
; Fetching #<URL "http://beta.quicklisp.org/dist/quicklisp/2015-09-24/systems.txt">
; 235.62KB
==================================================
241,274 bytes in 1.51 seconds (155.73KB/sec)

  ==== quicklisp installed ====
    To load a system, use: (ql:quickload "system-name")

    To find systems, use: (ql:system-apropos "term")

    To load Quicklisp every time you start Lisp, use: (ql:add-to-init-file)

    For more information, see http://www.quicklisp.org/beta/

NIL

SBCL を起動するたびに quiclisp を自動的に使用できるよう,SBCL 用初期化ファイルを作成する.

* (ql:add-to-init-file)
I will append the following lines to #P"/home/seiji/.sbclrc":

  ;;; The following lines added by ql:add-to-init-file:
  #-quicklisp
  (let ((quicklisp-init (merge-pathnames "quicklisp/setup.lisp"
                                         (user-homedir-pathname))))
    (when (probe-file quicklisp-init)
      (load quicklisp-init)))

Press Enter to continue.

#P"/home/seiji/.sbclrc"
* (quit)
seiji@debian:~$

確かにホームディレクトリ直下に,.sbclrc という名前のファイルができている.

seiji@debian:~$ cat .sbclrc

;;; The following lines added by ql:add-to-init-file:
#-quicklisp
(let ((quicklisp-init (merge-pathnames "quicklisp/setup.lisp"
(user-homedir-pathname))))
(when (probe-file quicklisp-init)
(load quicklisp-init)))

seiji@debian:~$ ls quicklisp*
quicklisp.lisp  quicklisp.lisp.asc

quicklisp:
asdf.lisp  client-info.sexp  dists  local-projects  quicklisp  setup.lisp  tmp
$

ついでに sb-aclrepl を要求するコードも .sbclrc に追加しておこう.vi などお好みのエディタを用いて,以下のように下線部を追加し保存する.

seiji@debian:~$ vi .sbclrc
seiji@debian:~$ cat .sbclrc

;;; The following lines added by(a  ql:add-to-init-file:
#-quicklisp
(let ((quicklisp-init (merge-pathnames "quicklisp/setup.lisp"
                                       (user-homedir-pathname))))
  (when (probe-file quicklisp-init)
    (load quicklisp-init)))
(require :sb-aclrepl)

こんな風になればOKだ.

seiji@debian:~$ sbcl
This is SBCL 1.2.4.debian, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.

SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses.  See the CREDITS and COPYING files in the
distribution for more information.
CL-USER(1): :exit
seiji@debian:~$


付2.4 開発環境 emacs+slime+sbcl

Allegro Common Lisp のような統合開発環境ではないが,それに近いものとして,emacs と slime の組み合わせで SBCL を利用する方法を紹介する.GUI なら「アプリケーション」→「プログラミング」→「emacs」で,CUIならコマンドラインで emacs とタイプして emacs を起動し,emacs が立ち上がったら,<ESC>-x (M-x) の次に「slime」と打てば,emacs 環境の中で sbcl の REPL を使うことができるようになる.

Slime1


この環境の何が嬉しいかというと,Lisp のソースコードと REPL での実行が緊密に統合されていて,emacs 環境から離れずに書式を実行できるとか, REPL 環境で関数をタイプ入力した時,emacs エコー領域にその引数が表示されることである.このことで一々プログラム仕様書にまで戻ることなく,安心してプログラミングを進めることができる.

下図は(+ 2 3)の書式を emacs 上でタイプしたのち,C-x C-e した結果である.

Slime2


下図では「(cons」の次に空白を一つ打ってエコー領域に cons のコーリングシーケンスが表示され,se1 の入力待ちであることがガイドされている.

Slime3


また,任意の字句についてシンボルを選んでおいて,C-c C-d h とタイプ入力すれば,そのシンボルについてのHyperspecドキュメンテーションが閲覧できる.ただし,これはインターネット環境にあるときでローカル環境でも同じことをするにはHyperspecをローカルにインストールしておまじないを掛ける必要がある.具体的なやりかたは「slime hyperspec」などで検索すればいくらでも情報が得られるので,そういうのが得意な人は頑張ってほしい.

Slime 環境では emacs と SBCL  がソケット結合されるため,sb-aclrepl は残念ながら有効にならないが quicklisp は大丈夫である.本書では説明の都合上 emacs 環境を用いた記述ではないが,emacs を使いなれた人であれば是非この環境に慣れて SBCL のプログラミングに熟達しよう.

付2.5 ブレーク時の対処方法

Common Lisp でプログラミングしていると,ミススペルなどによって未定義の関数を呼び出そうとしたり,値が束縛されていないシンボルの値を読もうとしたりして,ブレークする瞬間が必ずある.そのような時には原因がすぐ同定できれば,ブレーク状態から脱出することになるが,その方法は処理系依存である.そこでここでは SBCL におけるブレークからの脱出方法について説明する.

以下は未束縛シンボルの値を取りに行った場合である.

seiji@debian:~$ sbcl

   ...

CL-USER(1): foo
debugger invoked on a UNBOUND-VARIABLE in thread
#&THREAD "main thread" RUNNING {10039CE593)>:
  The variable FOO is unbound.

Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [ABORT] Exit debugger, returning to top level.

(SB-INT:SIMPLE-EVAL-IN-LEXENV FOO #<NULL-LEXENV>)
0] 0

CL-USER(2):

ブレークの原因を示すメッセージとともに,処理の選択肢が番号付きで示される.ここではたまたま簡単な場合で一つしか示されなかったが,いずれにしても選択肢の中には必ず,"Exit debugger, returning to top level." というものがあるので,その該当する番号を入力すればよい.ここでは0を入力して,もとの REPL に戻った.トップレベルというのは,このブレーク前の REPL 環境のことである.

Slime と emacs  を使った場合には,本質的には同じことだが,ちょっとだけ変化する.次の図を見られたい.

breakOnSlime


ここでは,"SLIME's top level" に戻るために,カーソルを Restarts:部の 1 のところまで持っていき,そこでEnterキーを押せばよい.