<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5582672144555408512</id><updated>2012-02-16T17:37:43.427+09:00</updated><title type='text'>Modern Common Lisp</title><subtitle type='html'>Introduction of Modern Common Lisp.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://modern-cl.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5582672144555408512/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://modern-cl.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>深町英太郎</name><uri>http://www.blogger.com/profile/10400604075787200611</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-XkcknpZ6_Bk/TWSEhQy5bxI/AAAAAAAAAAc/anz9Z_tVr2w/s220/redhat.png'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>6</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5582672144555408512.post-1576993284207101684</id><published>2011-07-19T18:21:00.013+09:00</published><updated>2011-10-03T19:31:57.722+09:00</updated><title type='text'>第6回 Common Lispライブラリを書く</title><content type='html'>&lt;p&gt;　僕のブログで「Modern Common Lispはターゲットをどこに置いているのか」という質問をいただきました。最初は環境構築から始まっており、初心者向けに見えますが、次はHello, Worldもせずにライブラリの解説をしています。&lt;/p&gt;&lt;p&gt;　Modern Common Lispのターゲットは、&lt;strong&gt;これからのCommon Lisp&lt;/strong&gt;を学びたい人です。当初はこの連載を読めばCommon Lispについてのすべてを学べるAll-In-One形式にしようと考えていたのですが、それでは時間がかかりすぎてしまうため、いくつかの過程を省いて進めます。たとえば、Lispでは必要なリスト処理などはここでは解説しません。理由は、それを学ぶための書籍が既に多く存在するからです。Common Lispの基本文法はそれらの書籍を参照してください。この連載は、Common Lispの入門書と並行、または読了後に読むことをおすすめします。&lt;/p&gt;&lt;p&gt;　さて、前回の僕の記事では主要なライブラリとその使い方について紹介しました。今回は自分のCommon Lispのライブラリを書く手順についてです。&lt;/p&gt;&lt;h2&gt;Sleep Sortのライブラリをつくろう&lt;/h2&gt;&lt;p&gt;　1ヶ月以上前のことになりますが、Sleep Sortというソートアルゴリズムが話題になりました。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://e-arrows.sakura.ne.jp/2011/05/sleep-sort-in-common-lisp.html"&gt;4chan発のソートアルゴリズム"Sleep sort"をCommon Lispで - 八発白中&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;　実装が簡単なので、例として今回はこのライブラリを作りたいと思います。&lt;/p&gt;&lt;h2&gt;CL-Projectでスケルトン生成&lt;/h2&gt;&lt;p&gt;　まずはライブラリの雛形を作ります。雛形の生成には&lt;a href="https://github.com/fukamachi/cl-project"&gt;CL-Project&lt;/a&gt;というライブラリを使います。まずはQuicklispでインストールしましょう。&lt;/p&gt;&lt;pre class="prettyprint lang-lisp"&gt;&lt;br /&gt;(ql:quickload :cl-project)&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;　雛形を作るには関数&lt;code&gt;make-project&lt;/code&gt;を使います。あらかじめ依存することが分かっているライブラリはこのタイミングで指定しておきましょう。今回はcl-annot(後述)と、スレッドを使いそうなのでbordeaux-threadsの2つを指定しています。&lt;/p&gt;&lt;pre class="prettyprint lang-lisp"&gt;&lt;br /&gt;(cl-project:make-project #p"lib/sleepsort/"&lt;br /&gt;  :author "Eitarow Fukamachi"&lt;br /&gt;  :email "e.arrows@gmail.com"&lt;br /&gt;  :license "LLGPL"&lt;br /&gt;  :depends-on '(:bordeaux-threads cl-annot))&lt;br /&gt;;-&gt; writing /Users/fukamachi/Programs/lib/sleepsort/.gitignore&lt;br /&gt;    writing /Users/fukamachi/Programs/lib/sleepsort/README.markdown&lt;br /&gt;    writing /Users/fukamachi/Programs/lib/sleepsort/sleepsort-test.asd&lt;br /&gt;    writing /Users/fukamachi/Programs/lib/sleepsort/sleepsort.asd&lt;br /&gt;    writing /Users/fukamachi/Programs/lib/sleepsort/src/sleepsort.lisp&lt;br /&gt;    writing /Users/fukamachi/Programs/lib/sleepsort/t/sleepsort.lisp&lt;br /&gt;;=&gt; #P"/Users/fukamachi/Programs/lib/sleepsort/sleepsort.asd"&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;　これで#p"lib/sleepsort/"にスケルトンができました。空のプロジェクトはそのままの状態でも&lt;code&gt;ql:quickload&lt;/code&gt;することができます。&lt;/p&gt;&lt;pre class="prettyprint lang-lisp"&gt;&lt;br /&gt;(ql:quickload :sleepsort)&lt;br /&gt;;-&gt; To load "sleepsort":&lt;br /&gt;      Load 1 ASDF system:&lt;br /&gt;        sleepsort&lt;br /&gt;    ; Loading "sleepsort"&lt;br /&gt;    [package sleepsort]&lt;br /&gt;;=&gt; (:SLEEPSORT)&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;span style="color: red;"&gt;※注)&lt;/span&gt; もし#p"lib/sleepsort/"にパスが通っていない場合、REPLを再起動するとロードできなくなります。ローカルのプロジェクトをQuicklispでロードできるようにするには&lt;a href="http://modern-cl.blogspot.com/2011/03/quicklisp.html"&gt;第2回 Quicklispによるライブラリ環境&lt;/a&gt;を参照してください。&lt;/p&gt;&lt;h2&gt;雛形の構成&lt;/h2&gt;&lt;p&gt;　CL-Projectが生成する雛形は以下のような最小構成です。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;README.markdown&lt;/code&gt;: README。&lt;/li&gt;&lt;li&gt;&lt;code&gt;sleepsort.asd&lt;/code&gt;: ライブラリ(system)の定義ファイル。&lt;/li&gt;&lt;li&gt;&lt;code&gt;sleepsort-test.asd&lt;/code&gt;: ライブラリのテスト用の定義ファイル。&lt;/li&gt;&lt;li&gt;&lt;code&gt;src/&lt;/code&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;sleepsort.lisp&lt;/code&gt;: メインのソースファイル。&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;t/&lt;/code&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;sleepsort.lisp&lt;/code&gt;: メインのテストファイル。&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;　ディレクトリトップには&lt;code&gt;.asd&lt;/code&gt;ファイルが2つあります。これは他の言語で言うところのMakefileです。ASDFによるライブラリの定義ファイルです。Quicklispはこのファイルから必要なファイルを判断してライブラリをロードしています。&lt;/p&gt;&lt;p&gt;　&lt;code&gt;src&lt;/code&gt;ディレクトリは主なソースコードを置く場所です。この中には最初1つのファイルが置かれていますが、他にファイルを分けたいと思ったときにはこのディレクトリにファイルをどんどん追加していきます。&lt;/p&gt;&lt;p&gt;　&lt;code&gt;t&lt;/code&gt;ディレクトリは自動テストを置く場所です。&lt;/p&gt;&lt;h2&gt;関数を実装&lt;/h2&gt;&lt;p&gt;　では、肝心の関数の定義をします。&lt;code&gt;src/sleepsort.lisp&lt;/code&gt;を開いてください。以下のようになっているはずです。&lt;/p&gt;&lt;pre class="prettyprint lang-lisp"&gt;&lt;br /&gt;#|&lt;br /&gt;  This file is a part of sleepsort project.&lt;br /&gt;  Copyright (c) 2011 Eitarow Fukamachi (e.arrows@gmail.com)&lt;br /&gt;|#&lt;br /&gt;&lt;br /&gt;(in-package :cl-user)&lt;br /&gt;(defpackage sleepsort&lt;br /&gt;  (:use :cl))&lt;br /&gt;(in-package :sleepsort)&lt;br /&gt;&lt;br /&gt;;; blah blah blah.&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;　これに&lt;code&gt;sleepsort&lt;/code&gt;という関数を追加します。&lt;/p&gt;&lt;pre class="prettyprint lang-lisp"&gt;&lt;br /&gt;#|&lt;br /&gt;  This file is a part of sleepsort project.&lt;br /&gt;  Copyright (c) 2011 Eitarow Fukamachi (e.arrows@gmail.com)&lt;br /&gt;|#&lt;br /&gt;&lt;br /&gt;(in-package :cl-user)&lt;br /&gt;(defpackage sleepsort&lt;br /&gt;  (:use :cl)&lt;br /&gt;  (:import-from :bordeaux-threads&lt;br /&gt;                :make-thread&lt;br /&gt;                :join-thread))&lt;br /&gt;(in-package :sleepsort)&lt;br /&gt;&lt;br /&gt;(cl-annot:enable-annot-syntax)&lt;br /&gt;&lt;br /&gt;@export&lt;br /&gt;(defun sleepsort (&amp;rest args)&lt;br /&gt;  "A function to do 'sleep sort' arguments."&lt;br /&gt;  (let* (result&lt;br /&gt;         (threads (mapcar (lambda (arg)&lt;br /&gt;                            (bordeaux-threads:make-thread&lt;br /&gt;                             (lambda ()&lt;br /&gt;                               (sleep arg)&lt;br /&gt;                               (push arg result))))&lt;br /&gt;                          args)))&lt;br /&gt;&lt;br /&gt;    (dolist (thread threads)&lt;br /&gt;      (bordeaux-threads:join-thread thread))&lt;br /&gt;&lt;br /&gt;    (nreverse result)))&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;　&lt;code&gt;@export&lt;/code&gt;アノテーションを有効にするために&lt;a href="https://github.com/arielnetworks/cl-annot"&gt;cl-annot&lt;/a&gt;を使っています。このアノテーションを使うと、指定した関数がパッケージ外でも参照できるようになります。&lt;/p&gt;&lt;p&gt;　cl-annotの詳しい解説は、作者の松山が今後紹介記事を書いてくれる予定です。&lt;/p&gt;&lt;h2&gt;テストを書く&lt;/h2&gt;&lt;p&gt;　モダンなライブラリに自動テストは欠かせません。雛形にはテスト用のファイルも含まれています。&lt;code&gt;t/sleepsort.lisp&lt;/code&gt;を開いてください。&lt;/p&gt;&lt;pre class="prettyprint lang-lisp"&gt;&lt;br /&gt;#|&lt;br /&gt;  This file is a part of sleepsort project.&lt;br /&gt;  Copyright (c) 2011 Eitarow Fukamachi (e.arrows@gmail.com)&lt;br /&gt;|#&lt;br /&gt;&lt;br /&gt;(in-package :cl-user)&lt;br /&gt;(defpackage sleepsort-test&lt;br /&gt;  (:use :cl&lt;br /&gt;        :sleepsort&lt;br /&gt;        :cl-test-more))&lt;br /&gt;(in-package :sleepsort-test)&lt;br /&gt;&lt;br /&gt;(plan nil)&lt;br /&gt;&lt;br /&gt;;; blah blah blah.&lt;br /&gt;&lt;br /&gt;(finalize)&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;　この"blah blah blah."の部分を消して、以下のように置き換えてみます。&lt;/p&gt;&lt;pre class="prettyprint lang-lisp"&gt;&lt;br /&gt;(diag "Testing 'sleepsort'. Wait some seconds...")&lt;br /&gt;(is (sleepsort 5 3 6 3 6 3 1 4 7) '(1 3 3 3 4 5 6 6 7))&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;　テストを走らせるには(test-system :sleepsort)を実行します。&lt;/p&gt;&lt;pre class="prettyprint lang-lisp"&gt;&lt;br /&gt;(test-system :sleepsort)&lt;br /&gt;To load "sleepsort-test":&lt;br /&gt;  Load 1 ASDF system:&lt;br /&gt;    sleepsort-test&lt;br /&gt;; Loading "sleepsort-test"&lt;br /&gt;[package sleepsort-test]&lt;br /&gt;# Testing 'sleepsort'. Wait some seconds...&lt;br /&gt;ok 1&lt;br /&gt;&lt;br /&gt;(:SLEEPSORT-TEST)&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;　Sleep Sortの実行は、その性質上時間がかかります。7秒ほど待ったあと、"ok"と表示されればテスト成功です。&lt;/p&gt;&lt;p&gt;　詳しいCL-TEST-MOREの説明は&lt;a href="https://github.com/fukamachi/cl-test-more"&gt;https://github.com/fukamachi/cl-test-more&lt;/a&gt;を参照してください。&lt;/p&gt;&lt;h2&gt;Quicklispに登録する&lt;/h2&gt;&lt;p&gt;　せっかく作った有用なライブラリはQuicklispに登録すべきです。現在Quicklispへの登録は承認制になっており、月に一度の更新時に取り込まれます。日にちは固定ではないですが、だいたい毎月20日前後に更新されます。&lt;/p&gt;&lt;p&gt;　登録の申請はGitHub Issuesで行います。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="https://github.com/quicklisp/quicklisp-projects/issues"&gt;Issues - quicklisp/quicklisp-projects - GitHub&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;　右上の「New Issue」をクリックし、ライブラリ名とリポジトリのURLを書いて登録してください。&lt;/p&gt;&lt;h2&gt;おわりに&lt;/h2&gt;&lt;p&gt;　さて、今回は自分のライブラリを作って公開するまでを紹介しました。公開するためでなくても、何かアプリケーションを作るときはasdファイルを書いてモジュール単位で管理するため、Common Lispでまとまったプログラムを書くときには必要な手順でしょう。&lt;/p&gt;&lt;p&gt;　次回の僕の回ではCL-TEST-MOREでの自動テストについてより詳しく解説します。&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5582672144555408512-1576993284207101684?l=modern-cl.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://modern-cl.blogspot.com/feeds/1576993284207101684/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://modern-cl.blogspot.com/2011/07/6-common-lisp.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5582672144555408512/posts/default/1576993284207101684'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5582672144555408512/posts/default/1576993284207101684'/><link rel='alternate' type='text/html' href='http://modern-cl.blogspot.com/2011/07/6-common-lisp.html' title='第6回 Common Lispライブラリを書く'/><author><name>深町英太郎</name><uri>http://www.blogger.com/profile/10400604075787200611</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-XkcknpZ6_Bk/TWSEhQy5bxI/AAAAAAAAAAc/anz9Z_tVr2w/s220/redhat.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5582672144555408512.post-8470741933523706183</id><published>2011-07-10T01:27:00.000+09:00</published><updated>2011-07-10T01:27:01.443+09:00</updated><title type='text'>第5回 SLIMEの使い方 開発サイクルについて</title><content type='html'>&lt;p&gt;前々回の「&lt;a href="http://modern-cl.blogspot.com/2011/04/3-slime.html"&gt;基礎編&lt;/a&gt;」ではSLIMEのインストール方法とその基本的な使い方について説明しましたが、具体的にどのように開発したら良いか分からないと思います。今回はその補足としてSLIMEにおける開発サイクルについて説明します。&lt;/p&gt;&lt;h2&gt;SLIMEにおける開発サイクル&lt;/h2&gt;&lt;p&gt;SLIMEにおける開発サイクルは基本的には次のようになります。&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;code&gt;M-x slime&lt;/code&gt;でSLIMEを起動&lt;/li&gt;&lt;li&gt;lispファイルを編集&lt;/li&gt;&lt;li&gt;REPLバッファで動作確認&lt;/li&gt;&lt;li&gt;2に戻る&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;一般的な開発サイクルには「コンパイル」とか「アプリケーションの再起動」というタスクがありますが、SLIMEの開発サイクルにはそれがありません。その代わりSLIMEには、アプリケーションへの変更を即座に反映させる仕組みがあります。これにより、待ち時間を極力短縮して、またエディタとターミナルを行き来することなく、効率的に（また気持ち良く）開発することが可能になります。この、いわゆるインクリメンタルなアプリケーションの構築は、SLIMEを使う最大の利点と言っても過言ではありません。&lt;/p&gt;&lt;p&gt;もっとも、(2)の「lispファイルを編集」するための十分な知識を持っていなければ、その利点もあまり感じられないでしょう。本連載でもこの点を重点的に解説していく予定です。本エントリの後半もその解説になります。&lt;/p&gt;&lt;p&gt;Webアプリケーションなどを開発する際は、(3)は「ブラウザで動作確認」になります。もちろんユーティリティ関数のテストやモデルデータの確認をREPLで行うこともあります。要は使い分けです。&lt;/p&gt;&lt;p&gt;ところで、アプリケーションをインクリメンタルに構築していくという性質上、何かの拍子に変数の値がおかしくなったり、謎のエラー（というわけではないですが、原因を考えるのが本質的でないエラー）が発生したりします。そういう時は、&lt;code&gt;M-x slime-restart-inferior-lisp&lt;/code&gt;として開発サイクルを一度リセットします。この操作は重要なので是非覚えてください。&lt;/p&gt;&lt;h2&gt;バッファでの操作&lt;/h2&gt;&lt;p&gt;ここでの操作は上記した開発サイクルの(2)に該当します。SLIMEで一番重要な操作ですので、是非習得してください。&lt;/p&gt;&lt;h3&gt;&lt;code&gt;C-c C-c&lt;/code&gt; (&lt;code&gt;slime-compile-defun&lt;/code&gt;)&lt;/h3&gt;&lt;p&gt;このコマンドは現在ポイントしているトップレベル関数（実は関数以外でも有効）をコンパイルするコマンドです。コンパイルというと少しヘビーなイメージを持ちますが、ここでは関数を定義するぐらいのイメージで問題ありません。実際に例を示します。まず適当な&lt;code&gt;lisp&lt;/code&gt;ファイルに次のコードを書いてください。&lt;/p&gt;&lt;pre class="prettyprint lang-lisp"&gt;&lt;code&gt;(defun fact (n)&lt;br /&gt;  (if (&amp;lt;= n 1)&lt;br /&gt;      0&lt;br /&gt;      (* n (fact (1- n)))))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;次にこのフォームをポイントして&lt;code&gt;C-c C-c&lt;/code&gt;します。コンパイルが成功したというメッセージがミニバッファに表示されるはずです。これで&lt;code&gt;fact&lt;/code&gt;関数が定義され利用できるようになりました。&lt;/p&gt;&lt;p&gt;&lt;code&gt;C-c C-z&lt;/code&gt;あるいは&lt;code&gt;M-x slime-repl&lt;/code&gt;としてREPLバッファを表示し、次のコードを実行してみましょう。&lt;/p&gt;&lt;pre class="prettyprint lang-lisp"&gt;&lt;code&gt;CL-USER&amp;gt; (fact 10)&lt;br /&gt;0&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;結果が0になっていて、どうも&lt;code&gt;fact&lt;/code&gt;関数にバグがあるようです。実は&lt;code&gt;n&lt;/code&gt;が1以下のときに&lt;code&gt;1&lt;/code&gt;ではなく&lt;code&gt;0&lt;/code&gt;を返してしまっていさう。そこで再びlispファイルを開いて次のように修正してください。&lt;/p&gt;&lt;pre class="prettyprint lang-lisp"&gt;&lt;code&gt;(defun fact (n)&lt;br /&gt;  (if (&amp;lt;= n 1)&lt;br /&gt;      1&lt;br /&gt;      (* n (fact (1- n)))))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;そして、先と同じように&lt;code&gt;C-c C-c&lt;/code&gt;します。関数が定義できたら&lt;code&gt;C-c C-z&lt;/code&gt;あるいは&lt;code&gt;M-x slime-repl&lt;/code&gt;でREPLバッファを表示し、先と同じコードを実行してみましょう。&lt;/p&gt;&lt;pre class="prettyprint lang-lisp"&gt;&lt;code&gt;CL-USER&amp;gt; (fact 10)&lt;br /&gt;3628800&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;正しい結果が返ってきていますね。この例でも分かるように、バッファでの操作で一番重要なコマンドは&lt;code&gt;C-c C-c&lt;/code&gt;です。関数定義（もっと言えばトップレベルフォーム）を編集した際は、&lt;code&gt;C-c C-c&lt;/code&gt;する癖を付けるのが良いでしょう。&lt;/p&gt;&lt;p&gt;また、&lt;code&gt;C-c C-c&lt;/code&gt;することで、コンパイラがおかしなコードを拒否したり警告してくれます。これはバグの早期発見に有効です。試しに次のようなコードを書いて&lt;code&gt;C-c C-c&lt;/code&gt;してみてください。&lt;/p&gt;&lt;pre class="prettyprint lang-lisp"&gt;&lt;code&gt;(defun f (n)&lt;br /&gt;  (let ((m (* n 2)))&lt;br /&gt;    (1+ n)))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;すると&lt;code&gt;let&lt;/code&gt;部分に下線が引かれると思います。この下線は警告を表わしており、&lt;code&gt;C-x \``あるいは&lt;/code&gt;M-x next-error`で警告の内容を詳細表示できます。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;cd /home/tomo/tmp/&lt;br /&gt;1 compiler notes:&lt;br /&gt;&lt;br /&gt;/home/tomo/tmp/a.lisp:2:3:&lt;br /&gt;  style-warning: Unused lexical variable M&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;このように&lt;code&gt;m&lt;/code&gt;という変数が未使用であるのが分かりますね。&lt;/p&gt;&lt;p&gt;余力がある方は、明らかにエラーとなるコードを書いてみて、&lt;code&gt;C-c C-c&lt;/code&gt;してみることをおすすめします。&lt;/p&gt;&lt;h3&gt;&lt;code&gt;C-c C-k&lt;/code&gt; (&lt;code&gt;slime-compile-and-load-file&lt;/code&gt;)&lt;/h3&gt;&lt;p&gt;&lt;code&gt;C-c C-c&lt;/code&gt;ほどではありませんが、それでも頻繁に使うのが&lt;code&gt;C-c C-k&lt;/code&gt;です。このコマンドはファイル全体をコンパイルしてロードします。「コンパイル」とか「ロード」はCommon Lispの用語ですが、ここではあまり気にせず、ファイルを先頭から読み直すコマンド、ぐらいのイメージで捉えてください。&lt;/p&gt;&lt;p&gt;&lt;code&gt;C-c C-k&lt;/code&gt;は基本的には、まだロードされていないファイルをロードするときに使います。このとき、&lt;code&gt;C-c C-c&lt;/code&gt;同様、コンパイルできないコードはエラーや警告として視覚的に表示され、&lt;code&gt;C-x \``あるいは&lt;/code&gt;M-x next-error`で順番に確認することができます。&lt;/p&gt;&lt;p&gt;また&lt;code&gt;C-c C-k&lt;/code&gt;は、&lt;code&gt;C-c C-c&lt;/code&gt;し忘れていないことを確定するのにも便利です。その他にも対応していない括弧などを検出するのにも使えます。&lt;/p&gt;&lt;p&gt;一般的に、何かおかしくなったら&lt;code&gt;C-c C-k&lt;/code&gt;してみる、それでも駄目なら上記した&lt;code&gt;M-x slime-restart-inferior-lisp&lt;/code&gt;する、という運用になります。&lt;/p&gt;&lt;h3&gt;&lt;code&gt;C-c C-z&lt;/code&gt; (&lt;code&gt;slime-repl&lt;/code&gt;)&lt;/h3&gt;&lt;p&gt;すでに登場しましたが、このコマンドはREPLバッファを表示します。REPLバッファは頻繁に使うことになるので、是非覚えてください。&lt;/p&gt;&lt;h3&gt;&lt;code&gt;M-.&lt;/code&gt; (&lt;code&gt;slime-edit-definition&lt;/code&gt;)&lt;/h3&gt;&lt;p&gt;このコマンドは現在ポイントしているシンボルの定義を探すコマンドです。コーディング時はもちろんのことながら、コードリーディング時やデバッグ時にも非常に有用です。次に説明する&lt;code&gt;M-,&lt;/code&gt;と対で覚えてください。&lt;/p&gt;&lt;h3&gt;&lt;code&gt;M-,&lt;/code&gt; (&lt;code&gt;slime-pop-find-definition-stack&lt;/code&gt;)&lt;/h3&gt;&lt;p&gt;このコマンドは&lt;code&gt;M-.&lt;/code&gt;を実行したときの場所に戻るコマンドです。&lt;code&gt;M-.&lt;/code&gt;で定義を確認した後に、&lt;code&gt;M-,&lt;/code&gt;で元の場所に戻るというのが一般的な使い方です。&lt;/p&gt;&lt;h2&gt;REPLでの操作&lt;/h2&gt;&lt;p&gt;「バッファでの操作」で説明した操作はREPLでも有効ですが、いくつか追加機能が用意されているので、それを紹介します。&lt;/p&gt;&lt;h3&gt;&lt;code&gt;M-p&lt;/code&gt;, &lt;code&gt;M-n&lt;/code&gt;&lt;/h3&gt;&lt;p&gt;&lt;code&gt;M-p&lt;/code&gt;, &lt;code&gt;M-n&lt;/code&gt;はそれぞれ前の履歴、次の履歴を補完します。最低限これだけは記憶してください。同じ式を何度も入力するのはよしましょう。&lt;/p&gt;&lt;h3&gt;&lt;code&gt;M-r&lt;/code&gt;&lt;/h3&gt;&lt;p&gt;このコマンドは正規表現で履歴を検索して補完します。目的の履歴が最初に補完されない場合は、&lt;code&gt;M-p&lt;/code&gt;, &lt;code&gt;M-n&lt;/code&gt;で順番に探します。インクリメンタルな検索が出来れば便利ですが、現状ではそのような機能はないようです。誰かanythingで実装してくれないかな。&lt;/p&gt;&lt;h3&gt;特殊な変数&lt;/h3&gt;&lt;p&gt;REPL（Top Level Loop）では&lt;code&gt;*&lt;/code&gt;, &lt;code&gt;**&lt;/code&gt;, &lt;code&gt;***&lt;/code&gt;という特殊な変数が利用できます。&lt;code&gt;*&lt;/code&gt;には前回評価した式の結果が入り、&lt;code&gt;**&lt;/code&gt;には前々回、&lt;code&gt;***&lt;/code&gt;には前々々回に評価した式の結果が入ります。評価結果を再利用するときに便利です。簡単な例を示しておきます。&lt;/p&gt;&lt;pre class="prettyprint lang-lisp"&gt;&lt;code&gt;CL-USER&amp;gt; (+ 1 2)&lt;br /&gt;3&lt;br /&gt;CL-USER&amp;gt; (* * *)&lt;br /&gt;9&lt;br /&gt;CL-USER&amp;gt; (- * **)&lt;br /&gt;6&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;二番目の式の最初の&lt;code&gt;*&lt;/code&gt;は変数参照じゃなくて関数適用です。誤解しないように。よく分からない人はCommon Lispの入門ページなどで勉強してください。&lt;/p&gt;&lt;h2&gt;まとめ&lt;/h2&gt;&lt;p&gt;とりあえず今回はここまでです。次回以降は実際に何か作りながら、より実践的な内容について解説したいと思います。&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5582672144555408512-8470741933523706183?l=modern-cl.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://modern-cl.blogspot.com/feeds/8470741933523706183/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://modern-cl.blogspot.com/2011/07/5-slime.html#comment-form' title='3 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5582672144555408512/posts/default/8470741933523706183'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5582672144555408512/posts/default/8470741933523706183'/><link rel='alternate' type='text/html' href='http://modern-cl.blogspot.com/2011/07/5-slime.html' title='第5回 SLIMEの使い方 開発サイクルについて'/><author><name>m2ym</name><uri>http://www.blogger.com/profile/05102691172048785454</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5582672144555408512.post-4306541851512768510</id><published>2011-04-23T15:04:00.002+09:00</published><updated>2011-04-23T15:08:02.740+09:00</updated><title type='text'>第4回 Common Lispライブラリガイド</title><content type='html'>&lt;p&gt;　さて、Modern Common Lispはこれで4回目です。環境構築も完成に近づき、Common Lispでプログラムを始められる状態になりつつあります。ブログの主題も環境構築から実践へと移ります。&lt;/p&gt;&lt;p&gt;　今回はCommon Lispでプログラムを書く際によく必要になるであろうライブラリの紹介です。Common LispはSchemeと比べると仕様の大きな言語には違いありませんが、最近普及しているPythonなどに比べると標準ライブラリも小さいです。そのため、適切なライブラリを適切に使用するという能力は、他の言語以上にCommon Lispで必要になるでしょう。&lt;/p&gt;&lt;p&gt;　ここで紹介するライブラリはすべてQuicklispに入っているのですぐ利用できます。まだインストールしていない人は以下のエントリを参考にインストールしてください。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://modern-cl.blogspot.com/2011/03/quicklisp.html"&gt;Modern Common Lisp: 第2回 Quicklispによるライブラリ環境&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;正規表現を使う - CL-PPCRE&lt;/h2&gt;&lt;p&gt;　Common LispにはPerlのように標準で正規表現が付属するわけではありませんが、Perl5互換の正規表現ライブラリ「CL-PPCRE」があります。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://weitz.de/cl-ppcre/"&gt;http://weitz.de/cl-ppcre/&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;　Let Over Lambdaでべた褒めされているのが印象的でした。ガリガリにチューニングされていてPerlの正規表現エンジン(つまりCで書かれた正規表現エンジン)よりも高速らしいです。&lt;/p&gt;&lt;p&gt;　以下はUserAgentを元にマッチングするサンプルコードです。&lt;/p&gt;&lt;pre class="prettyprint lang-lisp"&gt;&lt;br /&gt;(defvar user-agent "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_6) AppleWebKit/534.28 (KHTML, like Gecko) Chrome/12.0.728.0 Safari/534.28")&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;　Common LispでUserAgentによるアクセス判定をしてみます。&lt;/p&gt;&lt;pre class="prettyprint lang-lisp"&gt;&lt;br /&gt;(import '(ppcre:scan ppcre:scan-to-strings ppcre:regex-replace-all ppcre:split))&lt;br /&gt;&lt;br /&gt;;; 通常のマッチング&lt;br /&gt;;; Macからのアクセスか判定&lt;br /&gt;(scan "\\(Macintosh;" user-agent)&lt;br /&gt;;=&gt; 12&lt;br /&gt;;   23&lt;br /&gt;;   #()&lt;br /&gt;;   #()&lt;br /&gt;&lt;br /&gt;;; マッチした部分を取り出したい&lt;br /&gt;;; クライアントのMacのバージョンを知りたい&lt;br /&gt;(scan-to-strings "Mac OS X ([^\\)]+)" user-agent)&lt;br /&gt;;=&gt; "Mac OS X 10_6_6"&lt;br /&gt;;   #("10_6_6")&lt;br /&gt;&lt;br /&gt;;; 文字列置換&lt;br /&gt;;; Chromeの部分をMSIEに変える&lt;br /&gt;(regex-replace-all "Chrome" user-agent "MSIE")&lt;br /&gt;;=&gt; "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_6) AppleWebKit/534.28 (KHTML, like Gecko) MSIE/12.0.728.0 Safari/534.28"&lt;br /&gt;;   T&lt;br /&gt;&lt;br /&gt;;; 文字列分割&lt;br /&gt;;; クエリを分解&lt;br /&gt;(split "&amp;" "name=Eitarow%20Fukamachi&amp;age=23")&lt;br /&gt;;=&gt; ("name=Eitarow%20Fukamachi" "age=23")&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;　Let Over Lambdaではリードマクロを使って関数適用のように正規表現を扱う方法が紹介されています。より簡単な表記をしたい人には参考になるでしょう。&lt;/p&gt;&lt;h2&gt;日付を処理したい - LOCAL-TIME&lt;/h2&gt;&lt;p&gt;　日付操作はお遊びプログラムなどで出てくる定番の一つです。年末になるとよくカウントダウンとかして、新年まであと何秒とかやりますね。Common Lispで日付を扱うには「LOCAL-TIME」を使います。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://common-lisp.net/project/local-time/manual.html"&gt;http://common-lisp.net/project/local-time/manual.html&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;　簡単なサンプル。&lt;/p&gt;&lt;pre class="prettyprint lang-lisp"&gt;&lt;br /&gt;(import '(local-time:now local-time:parse-timestring))&lt;br /&gt;&lt;br /&gt;;; 現在時刻 (返り値はTIMESTAMPオブジェクト)&lt;br /&gt;(now)&lt;br /&gt;;=&gt; @2011-04-11T18:57:23.493142+09:00&lt;br /&gt;&lt;br /&gt;;; 文字列からのparse&lt;br /&gt;(parse-timestring "2015-02-18")&lt;br /&gt;;=&gt; @2015-02-18T09:00:00.000000+09:00&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;　ちなみに2015/02/18は僕が生まれて10000日目らしいです(&lt;a href="http://hp.vector.co.jp/authors/VA014370/jscript/datecalc/dcalc.htm"&gt;日齢計算&lt;/a&gt;より)。実際に試してみます。&lt;/p&gt;&lt;pre class="prettyprint lang-lisp"&gt;&lt;br /&gt;(import '(local-time:timestamp-difference local-time:parse-timestring))&lt;br /&gt;&lt;br /&gt;(/ (local-time:timestamp-difference&lt;br /&gt;    (local-time:parse-timestring "2015-02-18")&lt;br /&gt;    (local-time:parse-timestring "1987-10-03"))&lt;br /&gt;   (* 24 60 60))&lt;br /&gt;;=&gt; 10000&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;　逆に自分の生誕10000日目を知るには以下の関数に自分の誕生日を渡せばよいです。&lt;/p&gt;&lt;pre class="prettyprint lang-lisp"&gt;&lt;br /&gt;(import '(local-time:timestamp+ local-time:parse-timestring))&lt;br /&gt;&lt;br /&gt;(defun your-10000th-day (daystring)&lt;br /&gt;  (timestamp+&lt;br /&gt;    (local-time:parse-timestring daystring)&lt;br /&gt;    864000000&lt;br /&gt;    :sec))&lt;br /&gt;&lt;/pre&gt;&lt;h2&gt;シェルコマンドを実行したい - trivial-shell&lt;/h2&gt;&lt;p&gt;　Lispコードからシェルコマンドを実行するには「trivial-shell」が使えます。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://common-lisp.net/project/trivial-shell/"&gt;http://common-lisp.net/project/trivial-shell/&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre class="prettyprint lang-lisp"&gt;&lt;br /&gt;;; シェルコマンドを実行&lt;br /&gt;(trivial-shell:shell-command "ls ~/Programs/lib/clack/")&lt;br /&gt;;=&gt; (#P"/Users/fukamachi/Programs/lib/clack/.git/"&lt;br /&gt;;    #P"/Users/fukamachi/Programs/lib/clack/.gitignore"&lt;br /&gt;;    #P"/Users/fukamachi/Programs/lib/clack/README.markdown"&lt;br /&gt;;    #P"/Users/fukamachi/Programs/lib/clack/clack-test.asd"&lt;br /&gt;;    #P"/Users/fukamachi/Programs/lib/clack/clack.asd"&lt;br /&gt;;    #P"/Users/fukamachi/Programs/lib/clack/src/"&lt;br /&gt;;    #P"/Users/fukamachi/Programs/lib/clack/t/"&lt;br /&gt;;    #P"/Users/fukamachi/Programs/lib/clack/tmp/")&lt;br /&gt;&lt;br /&gt;;; シェルをZshに変更 (デフォルトは "/bin/sh")&lt;br /&gt;(setf trivial-shell:*bourne-compatible-shell* "/bin/zsh")&lt;br /&gt;;=&gt; "/bin/zsh"&lt;br /&gt;&lt;br /&gt;;; 環境変数の値を取得&lt;br /&gt;(trivial-shell:get-env-var "PATH")&lt;br /&gt;;=&gt; "/usr/bin:/bin:/usr/sbin:/sbin"&lt;br /&gt;&lt;/pre&gt;&lt;h2&gt;ファイル操作をしたい - CL-FAD&lt;/h2&gt;&lt;p&gt;　日常の簡単なスクリプトなどを書くとき、Lispからファイルシステムにアクセスすることもあるでしょう。「CL-FAD」を使えばOSに依存しない可搬なプログラムが書けます。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://weitz.de/cl-fad/"&gt;http://weitz.de/cl-fad/&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre class="prettyprint lang-lisp"&gt;&lt;br /&gt;(import '(cl-fad:list-directory cl-fad:walk-directory cl-fad:delete-directory-and-files))&lt;br /&gt;&lt;br /&gt;;; ディレクトリのファイル一覧&lt;br /&gt;(list-directory #p"~/Programs/lib/clack/")&lt;br /&gt;;=&gt; (#P"/Users/fukamachi/Programs/lib/clack/.git/"&lt;br /&gt;;    #P"/Users/fukamachi/Programs/lib/clack/.gitignore"&lt;br /&gt;;    #P"/Users/fukamachi/Programs/lib/clack/README.markdown"&lt;br /&gt;;    #P"/Users/fukamachi/Programs/lib/clack/clack-test.asd"&lt;br /&gt;;    #P"/Users/fukamachi/Programs/lib/clack/clack.asd"&lt;br /&gt;;    #P"/Users/fukamachi/Programs/lib/clack/src/"&lt;br /&gt;;    #P"/Users/fukamachi/Programs/lib/clack/t/"&lt;br /&gt;;    #P"/Users/fukamachi/Programs/lib/clack/tmp/")&lt;br /&gt;&lt;br /&gt;;; ホームディレクトリ以下のMP3ファイルを再帰的に検索&lt;br /&gt;(walk-directory&lt;br /&gt;  #p"~/"&lt;br /&gt;  (lambda (file)&lt;br /&gt;    (when (string-equal (pathname-type file) "mp3")&lt;br /&gt;      (fresh-line)&lt;br /&gt;      (princ file))))&lt;br /&gt;;-&gt; /Users/fukamachi/nagaku.mp3&lt;br /&gt;;   /Users/fukamachi/narunode.mp3&lt;br /&gt;;   /Users/fukamachi/shoryaku/shimasu.mp3&lt;br /&gt;;   ...&lt;br /&gt;&lt;/pre&gt;&lt;h2&gt;HTTPリクエストを投げたい - Drakma&lt;/h2&gt;&lt;p&gt;　LispでHTTPリクエストを投げるには「Drakma」を使います。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://weitz.de/drakma/"&gt;http://weitz.de/drakma/&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;　&lt;code&gt;http-request&lt;/code&gt;にURLを与えるとコンテンツ、HTTPステータスコード、HTTPヘッダなどが多値で返ってきます。以下はGoogle翻訳のAPIを叩いてみたサンプルです。&lt;/p&gt;&lt;pre class="prettyprint lang-lisp"&gt;&lt;br /&gt;(import '(drakma:http-request))&lt;br /&gt;&lt;br /&gt;(multiple-value-bind (body status header)&lt;br /&gt;    (drakma:http-request "http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&amp;langpair=en%7Cja&amp;q=Hello%2C%20World")&lt;br /&gt;  (format t "~&amp;Status: ~A~%Body: ~A~%Header: ~A~%"&lt;br /&gt;          status body header))&lt;br /&gt;;-&gt; Status: 200&lt;br /&gt;;   Body: {"responseData": {"translatedText":"こんにちは、世界"}, "responseDetails": null, "responseStatus": 200}&lt;br /&gt;;   Header: ((CACHE-CONTROL . no-cache, no-store, max-age=0, must-revalidate) (PRAGMA . no-cache) (EXPIRES . Fri, 01 Jan 1990 00:00:00 GMT) (DATE . Thu, 07 Apr 2011 12:10:42 GMT) (CONTENT-TYPE . text/javascript; charset=utf-8) (X-BACKEND-CONTENT-LENGTH . 80) (X-EMBEDDED-STATUS . 200) (X-CONTENT-TYPE-OPTIONS . nosniff) (X-FRAME-OPTIONS . SAMEORIGIN) (X-XSS-PROTECTION . 1; mode=block) (SERVER . GSE) (CONNECTION . close))&lt;br /&gt;;=&gt; NIL&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;　&lt;code&gt;body&lt;/code&gt;がJSONで返ってきているので、これをパースすれば英語を翻訳した結果だけを受け取れそうです。パースはCL-JSONを使うのが丁寧でしょうが、今回はそこまでする必要も感じないのでCL-PPCREで翻訳部分だけ抜き取ります。&lt;/p&gt;&lt;pre class="prettyprint lang-lisp"&gt;&lt;br /&gt;(ppcre:scan-to-strings&lt;br /&gt; "(?&lt;=translatedText\":\")[^\"]*"&lt;br /&gt; (nth-value 0&lt;br /&gt;  (drakma:http-request "http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&amp;langpair=en%7Cja&amp;q=Hello%2C%20World")))&lt;br /&gt;;=&gt; "こんにちは、世界"&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;　余裕がある人はGoogle翻訳する関数を書いてみるといいかもしれません。&lt;/p&gt;&lt;h2&gt;単体テスト - CL-TEST-MORE&lt;/h2&gt;&lt;p&gt;　自動化されたテストがないプロダクトはレガシーだと言われるようになったのはどうも最近のように思われますが、Lispは意外にも自動テストに関して熱心な傾向があります。&lt;/p&gt;&lt;p&gt;　単体テストフレームワークもいくつか選択肢があります。ここでは「CL-TEST-MORE」というPerlのTest::Moreというモジュールに影響されたライブラリを紹介します。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="https://github.com/fukamachi/cl-test-more"&gt;https://github.com/fukamachi/cl-test-more&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;　関数などはほぼTest::Moreと同じです。&lt;/p&gt;&lt;pre class="prettyprint lang-lisp"&gt;&lt;br /&gt;(import '(cl-test-more:is cl-test-more:plan cl-test-more:deftest cl-test-more:run-test-all))&lt;br /&gt;&lt;br /&gt;(plan 9)&lt;br /&gt;&lt;br /&gt;;; check if first argument is true&lt;br /&gt;(ok (eq got expected) "Description")&lt;br /&gt;&lt;br /&gt;;; check if "got" equals "expected"&lt;br /&gt;(is got expected "Description")&lt;br /&gt;(isnt got expected "Description")&lt;br /&gt;;; with :test function&lt;br /&gt;(is got expected "Description" :test #'string=)&lt;br /&gt;&lt;br /&gt;;; rather than print *standard-output* "# This is just a comment\n"&lt;br /&gt;(diag "This is just a comment")&lt;br /&gt;&lt;br /&gt;;; macro expansion&lt;br /&gt;(is-expand (got macro) (expected :like "this") "Description")&lt;br /&gt;&lt;br /&gt;;; output&lt;br /&gt;(is-print (write-line "aiueo") "aiueo\n" "Description")&lt;br /&gt;&lt;br /&gt;;; functions always pass or fail&lt;br /&gt;(pass "Description")&lt;br /&gt;(fail "Description")&lt;br /&gt;&lt;br /&gt;(finalize)&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;　出力結果はみんな大好きTAP(Test Anything Protocol)です。&lt;/p&gt;&lt;h2&gt;ユーティリティ集 - Alexandria&lt;/h2&gt;&lt;p&gt;　最後に、Common Lispのユーティリティ集についてです。&lt;/p&gt;&lt;p&gt;　もし「Haskellの○○はCLにはないのか…」とか「こんな関数が標準的にあったらいいのになぁ」と思ったら、自分で実装する前に「Alexandria」を探すといいです。AlexandriaはCLの標準ユーティリティ集的存在を目指したものです。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://common-lisp.net/project/alexandria/"&gt;http://common-lisp.net/project/alexandria/&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;　欲しいコマンドは&lt;code&gt;apropos&lt;/code&gt;で探します(それかac-slime)。&lt;/p&gt;&lt;pre class="prettyprint lang-lisp"&gt;&lt;br /&gt;(apropos "plist" :alexandria)&lt;br /&gt;;-&gt;  ALEXANDRIA.0.DEV:ALIST-PLIST, Def: FUNCTION&lt;br /&gt;;    ALEXANDRIA.0.DEV:DELETE-FROM-PLIST, Def: FUNCTION&lt;br /&gt;;    ALEXANDRIA.0.DEV:DELETE-FROM-PLISTF, Def: MACRO FUNCTION&lt;br /&gt;;    ALEXANDRIA.0.DEV:DOPLIST, Def: MACRO FUNCTION&lt;br /&gt;;    ALEXANDRIA.0.DEV:HASH-TABLE-PLIST, Def: FUNCTION&lt;br /&gt;;   ALEXANDRIA.0.DEV::MALFORMED-PLIST, Def: FUNCTION&lt;br /&gt;;                     MAPLIST, Def: FUNCTION&lt;br /&gt;;   ALEXANDRIA.0.DEV::PLIST&lt;br /&gt;;    ALEXANDRIA.0.DEV:PLIST-ALIST, Def: FUNCTION&lt;br /&gt;;    ALEXANDRIA.0.DEV:PLIST-HASH-TABLE, Def: FUNCTION&lt;br /&gt;;    ALEXANDRIA.0.DEV:REMOVE-FROM-PLIST, Def: FUNCTION&lt;br /&gt;;    ALEXANDRIA.0.DEV:REMOVE-FROM-PLISTF, Def: MACRO FUNCTION&lt;br /&gt;;                     SYMBOL-PLIST, Def: FUNCTION&lt;br /&gt;;=&gt; nil&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;　僕はplistが好きなのでplist系の関数群や、with-gensymsなどの汎用的なマクロをよく使っています。&lt;/p&gt;&lt;h2&gt;まとめ&lt;/h2&gt;&lt;p&gt;　この他にも、こういったことがしたければこのライブラリだろう、というものはいくつもあります。面倒なので紹介はしませんが以下に名前だけ載せておきます。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Webサーバ - &lt;a href="http://clacklisp.org/"&gt;Clack&lt;/a&gt;&lt;/li&gt;&lt;li&gt;データベース操作 - &lt;a href="http://clsql.b9.com/manual/"&gt;CLSQL&lt;/a&gt;, &lt;a href="http://common-lisp.net/project/elephant/"&gt;Elephant&lt;/a&gt;, &lt;a href="http://common-lisp.net/project/rucksack/"&gt;Rucksack&lt;/a&gt;&lt;/li&gt;&lt;li&gt;テンプレートエンジン - &lt;a href="https://github.com/arielnetworks/cl-markup"&gt;CL-Markup&lt;/a&gt;, &lt;a href="http://common-lisp.net/project/cl-emb/"&gt;CL-EMB&lt;/a&gt;&lt;/li&gt;&lt;li&gt;文字エンコード - &lt;a href="http://common-lisp.net/project/babel/"&gt;Babel&lt;/a&gt;&lt;/li&gt;&lt;li&gt;暗号化ライブラリ - &lt;a href="http://method-combination.net/lisp/ironclad/"&gt;Ironclad&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;　また余談ですが、Quicklispのダウンロード数ランキングも公開されています。何かの参考になるかもしれません。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://blog.quicklisp.org/2011/02/project-download-stats.html"&gt;Quicklisp news: Project download stats&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;　さて、今回はCommon Lispライブラリを紹介しました。ライブラリの使用に関しては(Quicklispがあれば)特別困ることもないと思います。&lt;/p&gt;&lt;p&gt;　この連載は松山さんと交互に書いているため、今後話題が交互することになるでしょう。次の僕の回ではモダンなCommon Lispライブラリの作り方について説明します。&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5582672144555408512-4306541851512768510?l=modern-cl.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://modern-cl.blogspot.com/feeds/4306541851512768510/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://modern-cl.blogspot.com/2011/04/4-common-lisp.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5582672144555408512/posts/default/4306541851512768510'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5582672144555408512/posts/default/4306541851512768510'/><link rel='alternate' type='text/html' href='http://modern-cl.blogspot.com/2011/04/4-common-lisp.html' title='第4回 Common Lispライブラリガイド'/><author><name>深町英太郎</name><uri>http://www.blogger.com/profile/10400604075787200611</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-XkcknpZ6_Bk/TWSEhQy5bxI/AAAAAAAAAAc/anz9Z_tVr2w/s220/redhat.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5582672144555408512.post-4703286553860270144</id><published>2011-04-07T21:41:00.010+09:00</published><updated>2011-07-10T01:50:59.321+09:00</updated><title type='text'>第3回 SLIMEの使い方 基礎編</title><content type='html'>&lt;p&gt;前回はQuicklispによるライブラリ管理について説明しました。今回はSLIMEの基本的な使い方について説明します。&lt;/p&gt;&lt;h2&gt;SLIMEとは&lt;/h2&gt;&lt;p&gt;SLIMEは(Common) Lispのための統合開発環境(IDE)です。他のIDEとは異なり、対話的にプログラムを構築できるのが特徴です。一度ハマれば他の開発環境は使えなくなるでしょう。詳しい情報は次のURLを参照してください。&lt;/p&gt;&lt;p&gt;&lt;a href="http://common-lisp.net/project/slime/"&gt;http://common-lisp.net/project/slime/&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;インストールと設定&lt;/h2&gt;&lt;h3&gt;SLIME&lt;/h3&gt;&lt;p&gt;SLIMEのCVSスナップショット（本家推奨）をインストールします。OSはGNU/LinuxやMac OS XなどのUNIX系OSを想定しています。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ wget http://common-lisp.net/project/slime/snapshots/slime-current.tgz&lt;br /&gt;$ tar xvzf slime-current.tgz&lt;br /&gt;$ mv slime-* ~/.emacs.d/slime&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;展開したディレクトリは&lt;code&gt;slime-2011-04-07&lt;/code&gt;のような名前になりますが、ここでは&lt;code&gt;slime&lt;/code&gt;という名前で&lt;code&gt;~/.emacs.d/&lt;/code&gt;直下に移動します。&lt;/p&gt;&lt;p&gt;次にEmacsの設定を行います。次のコードを&lt;code&gt;~/.emacs&lt;/code&gt;に書いてください。&lt;/p&gt;&lt;pre class="prettyprint lang-lisp"&gt;&lt;code&gt;;; Clozure CLをデフォルトのCommon Lisp処理系に設定&lt;br /&gt;(setq inferior-lisp-program "ccl")&lt;br /&gt;;; ~/.emacs.d/slimeをload-pathに追加&lt;br /&gt;(add-to-list 'load-path (expand-file-name "~/.emacs.d/slime"))&lt;br /&gt;;; SLIMEのロード&lt;br /&gt;(require 'slime)&lt;br /&gt;(slime-setup '(slime-repl slime-fancy slime-banner))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;これで基本的な設定は完了です。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;2011/7/10追記&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;若干設定項目が足りなかったので補足します。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;;; SLIMEからの入力をUTF-8に設定&lt;br /&gt;(setq slime-net-coding-system 'utf-8-unix)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;popwin.el&lt;/h3&gt;&lt;p&gt;使い始めれば気付くと思いますが、SLIMEは事あるごとにEmacsのウィンドウを分割したり、他のウィンドウのバッファを切り替えたりします。これではせっかくの優れた開発環境も台無しです。そこで、拙作のpopwin.elをインストールすることをお勧めします。popwin.elはウィンドウの分割等を極力抑制し、プログラマが快適に作業することを助けてくれる優れものです。&lt;/p&gt;&lt;p&gt;インストール方法や使い方は次のURLを参照してください。&lt;/p&gt;&lt;p&gt;&lt;a href="http://d.hatena.ne.jp/m2ym/20110120/1295524932"&gt;http://d.hatena.ne.jp/m2ym/20110120/1295524932&lt;/a&gt;&lt;/p&gt;&lt;p&gt;インストールが完了したら次のコードを&lt;code&gt;~/.emacs&lt;/code&gt;に書いてください。&lt;/p&gt;&lt;pre class="prettyprint lang-lisp"&gt;&lt;code&gt;;; Apropos&lt;br /&gt;(push '("*slime-apropos*") popwin:special-display-config)&lt;br /&gt;;; Macroexpand&lt;br /&gt;(push '("*slime-macroexpansion*") popwin:special-display-config)&lt;br /&gt;;; Help&lt;br /&gt;(push '("*slime-description*") popwin:special-display-config)&lt;br /&gt;;; Compilation&lt;br /&gt;(push '("*slime-compilation*" :noselect t) popwin:special-display-config)&lt;br /&gt;;; Cross-reference&lt;br /&gt;(push '("*slime-xref*") popwin:special-display-config)&lt;br /&gt;;; Debugger&lt;br /&gt;(push '(sldb-mode :stick t) popwin:special-display-config)&lt;br /&gt;;; REPL&lt;br /&gt;(push '(slime-repl-mode) popwin:special-display-config)&lt;br /&gt;;; Connections&lt;br /&gt;(push '(slime-connection-list-mode) popwin:special-display-config)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;ac-slime&lt;/h3&gt;&lt;p&gt;ac-slimeはauto-complete.elのSLIME拡張です。SLIME(SWANKサーバー)の情報を利用するため、非常に高精度のコード補完が行えます。&lt;/p&gt;&lt;p&gt;ac-slimeは次のURLから入手できます。&lt;/p&gt;&lt;p&gt;&lt;a href="https://github.com/purcell/ac-slime"&gt;https://github.com/purcell/ac-slime&lt;/a&gt;&lt;/p&gt;&lt;p&gt;なおauto-complete.elをあらかじめインストールしておく必要があります。インストールしていない方は次のURLを参照してください。&lt;/p&gt;&lt;p&gt;&lt;a href="http://cx4a.org/software/auto-complete/index.ja.html"&gt;http://cx4a.org/software/auto-complete/index.ja.html&lt;/a&gt;&lt;/p&gt;&lt;p&gt;ac-slimeをインストールするには、先のURLからac-slime.elをダウンロードし、load-pathの通ったディレクトリにコピーします。install-elispやauto-installがある場合は次のコードを評価することでインストールできます。&lt;/p&gt;&lt;pre class="prettyprint lang-lisp"&gt;&lt;code&gt;;; install-elisp&lt;br /&gt;(install-elisp "https://github.com/purcell/ac-slime/raw/master/ac-slime.el")&lt;br /&gt;;; auto-install&lt;br /&gt;(auto-install-from-url "https://github.com/purcell/ac-slime/raw/master/ac-slime.el")&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;最後に&lt;code&gt;~/.emacs&lt;/code&gt;に次のコードを書いてインストール完了です。&lt;/p&gt;&lt;pre class="prettyprint lang-lisp"&gt;&lt;code&gt;(require 'ac-slime)&lt;br /&gt;(add-hook 'slime-mode-hook 'set-up-slime-ac)&lt;br /&gt;(add-hook 'slime-repl-mode-hook 'set-up-slime-ac)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;これで.lispファイルやREPLでauto-complete.elを使った自動コード補完が行えるようになりました。&lt;/p&gt;&lt;p&gt;&lt;img src="http://cx4a.org/pub/ac-slime.png" alt="" /&gt;&lt;/p&gt;&lt;h3&gt;cl-indent-patches.el&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;この節は2011/7/10に追記しました&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Emacs標準のインデント機能には若干問題があります。特に&lt;code&gt;loop&lt;/code&gt;マクロのインデントが変です。例えば次のようなインデントになってしまいます。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;(loop for x in lst&lt;br /&gt;      if (oddp x)&lt;br /&gt;      collect x)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;本来は次のようにインデントされるべきです。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;(loop for x in lst&lt;br /&gt;      if (oddp x)&lt;br /&gt;        collect x)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;このあたりに気をきかせてくれるのがcl-indent-patches.elです。次のURLから入手できます。&lt;/p&gt;&lt;p&gt;&lt;a href="http://boinkor.net/lisp/cl-indent-patches.el"&gt;http://boinkor.net/lisp/cl-indent-patches.el&lt;/a&gt;&lt;/p&gt;&lt;p&gt;このファイルを&lt;code&gt;load-path&lt;/code&gt;の通ったディレクトリに配置してください。後は&lt;code&gt;.emacs&lt;/code&gt;に次のような設定を書けばOKです。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;(when (require 'cl-indent-patches nil t)&lt;br /&gt;  ;; emacs-lispのインデントと混同しないように&lt;br /&gt;  (setq lisp-indent-function&lt;br /&gt;        (lambda (&amp;amp;rest args)&lt;br /&gt;          (apply (if (memq major-mode '(emacs-lisp-mode lisp-interaction-mode))&lt;br /&gt;                     'lisp-indent-function&lt;br /&gt;                     'common-lisp-indent-function)&lt;br /&gt;                 args))))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;SLIMEの使い方&lt;/h2&gt;&lt;h3&gt;SLIMEの起動&lt;/h3&gt;&lt;p&gt;インストールと設定が完了したら&lt;code&gt;M-x slime&lt;/code&gt;とやってみましょう。次のような表示の&lt;code&gt;*slime-repl ccl*&lt;/code&gt;というREPLバッファが表示されれば成功です。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;CL-USER&amp;gt; &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;SLIMEを使って開発するに際して、まずやることはこの&lt;code&gt;M-x slime&lt;/code&gt;です。これを行わなければ、後で説明するエディタコマンドやインデント、コード補完、その他諸々が全く機能しません。まず&lt;code&gt;M-x slime&lt;/code&gt;、これだけ覚えておいてください。&lt;/p&gt;&lt;p&gt;なお表示されたREPLバッファはちょっとした確認などを行ったりする場合を除いて基本的には使用しません。&lt;/p&gt;&lt;h3&gt;SLIMEの操作&lt;/h3&gt;&lt;p&gt;SLIMEを起動して次にすることはlispファイルを開くことです。試しに&lt;code&gt;foo.lisp&lt;/code&gt;などの適当なファイルを開いてください。&lt;/p&gt;&lt;p&gt;lispファイルのメジャーモードは&lt;code&gt;lisp-mode&lt;/code&gt;です。このモードには様々なキーが割り当てられていますが、今回はその中でも覚えておくべきキーバインドを紹介します。&lt;/p&gt;&lt;h4&gt;&lt;code&gt;C-c C-c&lt;/code&gt;&lt;/h4&gt;&lt;p&gt;&lt;code&gt;C-c C-c&lt;/code&gt;は現在ポイントしているトップレベルフォームをコンパイルします。例えば次のような関数を編集しているとします。&lt;/p&gt;&lt;pre class="prettyprint lang-lisp"&gt;&lt;code&gt;(defun f (a)&lt;br /&gt;  "Hello, World")&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;ここで&lt;code&gt;C-c C-c&lt;/code&gt;すると関数&lt;code&gt;f&lt;/code&gt;がコンパイルされます。実際にやってみれば分かると思いますが、上の関数をコンパイルすると、SLIMEは変数&lt;code&gt;a&lt;/code&gt;が未使用であると警告してくれます。もし警告があればそれを修正して&lt;code&gt;C-c C-c&lt;/code&gt;、というのが基本的な開発サイクルになります。&lt;/p&gt;&lt;h4&gt;&lt;code&gt;C-c C-k&lt;/code&gt;&lt;/h4&gt;&lt;p&gt;&lt;code&gt;C-c C-k&lt;/code&gt;は現在のファイルをコンパイルしてロードします。トップレベルフォームを一つずつ&lt;code&gt;C-c C-c&lt;/code&gt;するのが面倒なときに重宝します。また、&lt;code&gt;C-c C-c&lt;/code&gt;同様、ソースコードに問題があれば警告してくれるので、ファイルの最終的な確認にも利用できます。&lt;/p&gt;&lt;h4&gt;&lt;code&gt;C-c C-z&lt;/code&gt;&lt;/h4&gt;&lt;p&gt;&lt;code&gt;C-c C-z&lt;/code&gt;は現在接続しているサーバーのREPLバッファを表示してくれます。何か確認したいときや、前回紹介したQuicklispでライブラリをロードしたいときに&lt;code&gt;C-c C-z&lt;/code&gt;します。例えばCL-TEST-MOREというライブラリをロードし忘れていたとしたら、&lt;code&gt;C-c C-z&lt;/code&gt;でREPLバッファを表示して、次のように入力します。&lt;/p&gt;&lt;pre class="prettyprint lang-lisp"&gt;&lt;code&gt;CL-USER&amp;gt; (ql:quickload :cl-test-more)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;REPLは使いこなせば非常に強力なので是非活用してください。&lt;/p&gt;&lt;h3&gt;困った時&lt;/h3&gt;&lt;p&gt;より本格的な開発サイクルは次回で説明しますが、SLIMEにおけるEmacsの&lt;code&gt;C-g&lt;/code&gt;的な存在として&lt;code&gt;M-x slime-restart-inferior-lisp&lt;/code&gt;を紹介しておきます。&lt;/p&gt;&lt;p&gt;これは現在接続しているサーバーを再起動してクリーンな状態に戻すコマンドです。SLIMEで開発していると、変にシンボルがインターンされたり、おかしな値の変数ができたりします。また、正しく動作しているとしても、実は古い変数などが残っていて偶然動作しているだけだったりもします。そういった状態をリセットするのに&lt;code&gt;M-x slime-restart-inferior-lisp&lt;/code&gt;は非常に便利です。是非覚えておいてください。&lt;/p&gt;&lt;h2&gt;まとめ&lt;/h2&gt;&lt;p&gt;今回は「SLIMEの使い方 基礎編」ということで、SLIMEのインストールと設定、および非常に基本的な使い方を紹介しました。実際のところ、今回の内容だけでSLIMEで開発を行うにはかなり情報が不足しています。Common Lisperなら気付いていると思いますが、パッケージの扱いなど、様々な重要な点を端折っています。次回以降、より実際的なSLIMEの使い方を紹介していきたいと思います。&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5582672144555408512-4703286553860270144?l=modern-cl.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://modern-cl.blogspot.com/feeds/4703286553860270144/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://modern-cl.blogspot.com/2011/04/3-slime.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5582672144555408512/posts/default/4703286553860270144'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5582672144555408512/posts/default/4703286553860270144'/><link rel='alternate' type='text/html' href='http://modern-cl.blogspot.com/2011/04/3-slime.html' title='第3回 SLIMEの使い方 基礎編'/><author><name>m2ym</name><uri>http://www.blogger.com/profile/05102691172048785454</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5582672144555408512.post-4111082131600802561</id><published>2011-03-09T19:07:00.015+09:00</published><updated>2011-04-11T12:18:58.656+09:00</updated><title type='text'>第2回 Quicklispによるライブラリ環境</title><content type='html'>&lt;p&gt;　Common Lispのライブラリを利用するのに、以前は&lt;a href="http://www.cliki.net/ASDF-Install"&gt;ASDF-Install&lt;/a&gt;を使っていました。しかし、ASDF-Installは外部のシェルコマンドに依存するためWindowsでの利用が面倒だったり、接続先のサーバが落ちていてダウンロードできなかったり、ダウンロードできたとしてもビルドできないといったことが多くありました。&lt;/p&gt;&lt;p&gt;　これを解決するためにZach Beaneが開発したのが&lt;a href="http://www.quicklisp.org/"&gt;Quicklisp&lt;/a&gt;です。現在BETA公開中で、いくつか制限事項はありますが、誰でも利用できるようになっています。&lt;/p&gt;&lt;h2&gt;Quicklisp BETA&lt;/h2&gt;&lt;h3&gt;セットアップ&lt;/h3&gt;&lt;p&gt;　まずはQuicklisp自身をインストールします。以下のリンクからQuicklispをダウンロードしてください。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;&lt;a href="http://beta.quicklisp.org/quicklisp.lisp"&gt;Quicklispをダウンロードする&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;　あなたのLisp処理系 (きっとSBCL以外でしょうね) を起動し、以下のコードを実行してください。&lt;/p&gt;&lt;pre class="prettyprint lang-lisp"&gt;(load "quicklisp.lisp")&lt;br /&gt;(quicklisp-quickstart:install :path ".quicklisp/")&lt;br /&gt;(ql:add-to-init-file)&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;※注) もしプロキシを通す必要があれば&lt;code&gt;:proxy&lt;/code&gt;キーワードにURLを文字列で渡してください。例: (quicklisp-quickstart:install :path ".quicklisp/" :proxy "http://192.168.xx.xx:8080")&lt;/p&gt;&lt;p&gt;　これでセットアップは完了です。&lt;code&gt;~/quicklisp&lt;/code&gt;というディレクトリができていることを確認してください。&lt;/p&gt;&lt;p&gt;　もしインストール後にQuicklispのディレクトリを変更したい場合には、&lt;code&gt;~/quicklisp&lt;/code&gt;ディレクトリを移動したあと、処理系のinitファイル (Clozure CLならば&lt;code&gt;~/.ccl-init.lisp&lt;/code&gt;)の一部を修正します。&lt;/p&gt;&lt;pre class="prettyprint lang-lisp"&gt;;;; The following lines added by ql:add-to-init-file:&lt;br /&gt;#-quicklisp&lt;br /&gt;(let ((quicklisp-init (merge-pathnames "&lt;b&gt;.quicklisp&lt;/b&gt;/setup.lisp"&lt;br /&gt;                                       (user-homedir-pathname))))&lt;br /&gt;  (when (probe-file quicklisp-init)&lt;br /&gt;    (load quicklisp-init)))&lt;br /&gt;&lt;/pre&gt;&lt;h3&gt;ライブラリのインストール・ロード&lt;/h3&gt;&lt;p&gt;　Quicklispでライブラリのインストールをするには&lt;code&gt;ql:quickload&lt;/code&gt;を使います。このコマンドは試験に出るのでよく覚えておいてください。&lt;/p&gt;&lt;pre class="prettyprint lang-lisp"&gt;(ql:quickload :cl-ppcre)&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;　指定したライブラリがまだインストールされていなければ、サーバからダウンロードしてインストールします。ASDF-INSTALLと違って依存パッケージも同時にインストールしてくれるので非常に助かります。&lt;/p&gt;&lt;h3&gt;ライブラリを探す&lt;/h3&gt;&lt;p&gt;　Quicklispに登録されているライブラリを探すには&lt;code&gt;ql:system-apropos&lt;/code&gt;を使います。&lt;/p&gt;&lt;pre class="prettyprint lang-lisp"&gt;(ql:system-apropos "web")&lt;br /&gt;;-&amp;gt; #&amp;lt;system cl-webdav / cl-webdav-0.2.0 / quicklisp 2011-02-19&amp;gt;&lt;br /&gt;;   #&amp;lt;system hh-web-tags / hh-web-tags-20110219-hg / quicklisp 2011-02-19&amp;gt;&lt;br /&gt;;   #&amp;lt;system hh-web-tags-tests / hh-web-tags-20110219-hg / quicklisp 2011-02-19&amp;gt;&lt;br /&gt;;   #&amp;lt;system symbolicweb / symbolicweb-20101207-git / quicklisp 2011-02-19&amp;gt;&lt;br /&gt;;   #&amp;lt;system symbolicweb-examples / symbolicweb-20101207-git / quicklisp 2011-02-19&amp;gt;&lt;br /&gt;;   #&amp;lt;system symbolicweb-jquery / symbolicweb-20101207-git / quicklisp 2011-02-19&amp;gt;&lt;br /&gt;;   #&amp;lt;system webactions / portableaserve-20101006-cvs / quicklisp 2011-02-19&amp;gt;&lt;br /&gt;;   #&amp;lt;system weblocks / weblocks-20110219-hg / quicklisp 2011-02-19&amp;gt;&lt;br /&gt;;   #&amp;lt;system weblocks-demo / weblocks-20110219-hg / quicklisp 2011-02-19&amp;gt;&lt;br /&gt;;   #&amp;lt;system weblocks-demo-popover / weblocks-20110219-hg / quicklisp 2011-02-19&amp;gt;&lt;br /&gt;;   #&amp;lt;system weblocks-elephant / weblocks-20110219-hg / quicklisp 2011-02-19&amp;gt;&lt;br /&gt;;   #&amp;lt;system weblocks-elephant-demo / weblocks-20110219-hg / quicklisp 2011-02-19&amp;gt;&lt;br /&gt;;   #&amp;lt;system weblocks-memory / weblocks-20110219-hg / quicklisp 2011-02-19&amp;gt;&lt;br /&gt;;   #&amp;lt;system weblocks-postmodern / weblocks-20110219-hg / quicklisp 2011-02-19&amp;gt;&lt;br /&gt;;   #&amp;lt;system weblocks-prevalence / weblocks-20110219-hg / quicklisp 2011-02-19&amp;gt;&lt;br /&gt;;   #&amp;lt;system weblocks-s11 / weblocks-20110219-hg / quicklisp 2011-02-19&amp;gt;&lt;br /&gt;;   #&amp;lt;system weblocks-scripts / weblocks-20110219-hg / quicklisp 2011-02-19&amp;gt;&lt;br /&gt;;   #&amp;lt;system weblocks-store-test / weblocks-20110219-hg / quicklisp 2011-02-19&amp;gt;&lt;br /&gt;;   #&amp;lt;system weblocks-yarek / weblocks-20110219-hg / quicklisp 2011-02-19&amp;gt;&lt;br /&gt;;   #&amp;lt;system weblocks-yui / weblocks-20110219-hg / quicklisp 2011-02-19&amp;gt;&lt;br /&gt;;=&amp;gt; nil&lt;br /&gt;&lt;/pre&gt;&lt;h3&gt;リポジトリをアップデートする&lt;/h3&gt;&lt;p&gt;　Quicklispのリポジトリは毎月1回更新されます。ライブラリが更新されたり、追加されたり削除されたり。最新のライブラリにアップデートするには以下のコマンドを実行します。&lt;/p&gt;&lt;pre class="prettyprint lang-lisp"&gt;(ql:update-all-dists)&lt;br /&gt;&lt;/pre&gt;&lt;h2&gt;ASDF2 - 登録されていないライブラリを使う&lt;/h2&gt;&lt;p&gt;　Quicklispには既に多くのライブラリが登録されているとはいえ、まだ登録されていないライブラリもあります。また、自分が作ったライブラリやアプリケーションのロードには使うことができません。&lt;/p&gt;&lt;p&gt;　そこで、「ASDF2」を使ってローカルの指定のライブラリをロードできるようにします。ASDF2は多くの処理系で標準バンドルされているはずなので特にセットアップの必要はありません。&lt;/p&gt;&lt;p&gt;　まずはライブラリを置くディレクトリを作ります。ここでは&lt;code&gt;~/.lisp/systems&lt;/code&gt;にライブラリを置くものとします。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ mkdir ~/.lisp/systems&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;　そして&lt;code&gt;~/.config/common-lisp/source-registry.conf.d/01-add-local-lisp.conf&lt;/code&gt;に上のディレクトリパスを指定します。&lt;/p&gt;&lt;pre class="prettyprint lang-lisp"&gt;;; ~/.config/common-lisp/source-registry.conf.d/01-add-local-lisp.conf&lt;br /&gt;(:tree (:home ".lisp/systems"))&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;　これで準備完了です。ASDF2は&lt;code&gt;~/.lisp/systems&lt;/code&gt;の中を再帰的に見て、その中のライブラリをロードできるようになりました&lt;/p&gt;&lt;h3&gt;ライブラリのインストールと利用&lt;/h3&gt;&lt;p&gt;　たとえば&lt;a href="http://clacklisp.org/"&gt;Clack&lt;/a&gt;を使うには&lt;code&gt;~/.lisp/systems&lt;/code&gt;にソースをcloneします。&lt;/p&gt;&lt;p&gt;&lt;span style="color: red;"&gt;※追記(2011/04/11)&lt;/span&gt;: 現在ではClackはQuicklispに取り込まれているため、インストールするためにこの処理は必要なくなっています。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ cd ~/.lisp/systems&lt;br /&gt;$ git clone git://github.com/fukamachi/clack&lt;br /&gt;$ git clone git://github.com/arielnetworks/cl-annot&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;　Lisp処理系を立ち上げ、&lt;code&gt;ql:quickload&lt;/code&gt;してください。&lt;/p&gt;&lt;pre class="prettyprint lang-lisp"&gt;(ql:quickload :clack)&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;　これでClackが使えるはずです。以下のコードを実行して、&lt;a href="http://localhost:5000/"&gt;http://localhost:5000/&lt;/a&gt;にアクセスしてみてください。&lt;strong&gt;"Hello, Clack!"&lt;/strong&gt;と表示されるはずです。&lt;/p&gt;&lt;pre class="prettyprint lang-lisp"&gt;(clack:clackup&lt;br /&gt;  #'(lambda (req)&lt;br /&gt;      (declare (ignore req))&lt;br /&gt;      '(200 nil ("Hello, Clack!"))))&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;　使えなかった場合は&lt;a href="http://twitter.com/#!/nitro_idiot"&gt;@nitro_idiot&lt;/a&gt;に報告してくださいね。&lt;/p&gt;&lt;h2&gt;まとめ&lt;/h2&gt;&lt;p&gt;　今回はQuicklispとASDF2によるライブラリの導入について解説しました。PerlやRubyに比べるとそれほど良い環境とは言えませんが、以前と比べてLispのライブラリ環境も悪くなくなってきています。これから数もどんどん増えていくことでしょう。&lt;/p&gt;&lt;p&gt;　次回は&lt;a href="http://twitter.com/#!/m2ym"&gt;松山さん&lt;/a&gt;がEmacsとSLIMEの環境設定について書いてくれるはずです。&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5582672144555408512-4111082131600802561?l=modern-cl.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://modern-cl.blogspot.com/feeds/4111082131600802561/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://modern-cl.blogspot.com/2011/03/quicklisp.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5582672144555408512/posts/default/4111082131600802561'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5582672144555408512/posts/default/4111082131600802561'/><link rel='alternate' type='text/html' href='http://modern-cl.blogspot.com/2011/03/quicklisp.html' title='第2回 Quicklispによるライブラリ環境'/><author><name>深町英太郎</name><uri>http://www.blogger.com/profile/10400604075787200611</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-XkcknpZ6_Bk/TWSEhQy5bxI/AAAAAAAAAAc/anz9Z_tVr2w/s220/redhat.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5582672144555408512.post-8934488238673258470</id><published>2011-03-07T18:46:00.018+09:00</published><updated>2011-10-26T17:17:41.326+09:00</updated><title type='text'>第1回 Common Lisp処理系のインストール</title><content type='html'>&lt;p&gt;同僚の&lt;a href="http://twitter.com/#!/nitro_idiot"&gt;深町さん&lt;/a&gt;と「モダンCommon Lisp」シリーズを初めることになりました。今回はCommon Lisp処理系のインストール方法について解説します。&lt;/p&gt;&lt;h2&gt;どの処理系を使うか&lt;/h2&gt;&lt;p&gt;Common Lispには処理系が多数存在するため、プログラミングを初める前に、まずどの処理系を使うか決めなくてはなりません。商用なら&lt;a href="http://www.franz.com/products/allegrocl/"&gt;Allegro CL&lt;/a&gt;でほぼ一択のようですが、お金がかかりますし、プロプライエタリソフトウェアですから、今回は候補から除外します。&lt;/p&gt;&lt;p&gt;無料で手に入る（フリーな）処理系としては&lt;a href="http://www.sbcl.org/"&gt;SBCL&lt;/a&gt;が有名です。多くのライブラリでサポートされている処理系であり、コンパイラの品質が高い（速いコードが生成される）という強みを持っていますが、スレッドサポートがかなり怪しいらしく（未確認）、またコンパイルに非常に時間がかかるという問題を持っています（開発のテンポに影響）。&lt;/p&gt;&lt;p&gt;SBCL以外には、例えば&lt;a href="http://www.gnu.org/software/clisp/"&gt;CLISP&lt;/a&gt;などがありますが、今回は深町さんに教えてもらった&lt;a href="http://www.clozure.com/clozurecl.html"&gt;Clozure CL&lt;/a&gt;をおすすめしようと思います。&lt;/p&gt;&lt;p&gt;Clozure CLは、SBCLほどではないにしろ、多くライブラリでサポートされている処理系であり、また元々のサポートの対象であったDarwin系のOS以外にも、GNU/LinuxやFreeBSD、Solaris、Windowsに対応しています。深町さんはMac OS X 10.6で、僕はUbuntu 10.10でClozure CLを使っていますが、今までで致命的な問題になったことはないです。また、SBCLに比べて非常にコンパイルが速いのも重要な利点です。ただ、生成されるコードの品質はそれほど良くないので、開発時はClozure CL、運用時はSBCL、という使い分けが良いと思います。&lt;/p&gt;&lt;h2&gt;Clozure CLをインストールする&lt;/h2&gt;&lt;p&gt;&lt;span style="color: red;"&gt;※追記1&lt;/span&gt;: Clozure CLに加えて今後の連載で紹介するEmacs、SLIME、Quicklispもすべて含めた&lt;a href="http://common-lisp.net/project/lispbox/"&gt;Lispbox&lt;/a&gt;というプロダクトもあります。&lt;/p&gt;&lt;p&gt;&lt;span style="color: red;"&gt;※追記2&lt;/span&gt;: Macを使っていて、Homebrewを導入している人は&lt;code&gt;brew install clozure-cl&lt;/code&gt;で最新のClozure CLをインストールできます。&lt;/p&gt;&lt;p&gt;現在での最新安定板はv1.7です。一応、次のURLから最新版を確認してください。&lt;/p&gt;&lt;p&gt;&lt;a href="http://trac.clozure.com/ccl"&gt;http://trac.clozure.com/ccl&lt;/a&gt;&lt;/p&gt;&lt;p&gt;ここではGNU/Linux x86_64にClozure CL v1.7をインストールする手順を説明します。Mac OS Xでもほぼ同じ手順でインストールできると思います。&lt;/p&gt;&lt;p&gt;まず&lt;code&gt;~/opt&lt;/code&gt;にリリースをダウンロードします。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ mkdir -p ~/opt&lt;br /&gt;$ cd ~/opt&lt;br /&gt;$ # Mac OS Xならdarwinx86&lt;br /&gt;$ # Linuxならlinuxx86&lt;br /&gt;$ # 詳しくは上記URLを参照&lt;br /&gt;$ svn co http://svn.clozure.com/publicsvn/openmcl/release/1.7/linuxx86/ccl&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;ccl&lt;/code&gt;ディレクトリが作られ、その中に32bit用と64bit用の実行可能ファイルが置かれます。なぜSubversionなのかというツッコミはやめましょう。&lt;/p&gt;&lt;p&gt;実行スクリプトはscriptsディレクトリの中にccl (64bit用はccl64) という名前で入っています。実行する際は&lt;code&gt;CCL_DEFAULT_DIRECTORY&lt;/code&gt;に、checkoutした&lt;code&gt;ccl&lt;/code&gt;ディレクトリのパスを設定してください。&lt;/p&gt;&lt;p&gt;このスクリプトを&lt;code&gt;PATH&lt;/code&gt;環境変数の通ったディレクトリに&lt;code&gt;ccl&lt;/code&gt;という名前で保存します。ここでは&lt;code&gt;~/bin&lt;/code&gt;に置きます。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ cp scripts/ccl ~/bin/ccl&lt;br /&gt;$ chmod +x ~/bin/ccl&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;最後にターミナルで&lt;code&gt;ccl&lt;/code&gt;を起動して、正しく動作すればOKです。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ ccl&lt;br /&gt;Welcome to Clozure Common Lisp Version 1.7-r14925M  (LinuxX8632)!&lt;br /&gt;? &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;次回はQuicklispのインストール方法について解説します。&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5582672144555408512-8934488238673258470?l=modern-cl.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://modern-cl.blogspot.com/feeds/8934488238673258470/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://modern-cl.blogspot.com/2011/03/common-lisp1-common-lisp-common.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5582672144555408512/posts/default/8934488238673258470'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5582672144555408512/posts/default/8934488238673258470'/><link rel='alternate' type='text/html' href='http://modern-cl.blogspot.com/2011/03/common-lisp1-common-lisp-common.html' title='第1回 Common Lisp処理系のインストール'/><author><name>m2ym</name><uri>http://www.blogger.com/profile/05102691172048785454</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
