Cusp は Common Lisp プログラミング言語のための開発環境です。Lisp を使うと、Web アプリケーションをはじめとする、あらゆる種類のアプリケーションを開発することができます。Lisp は、今日でも相変わらず広く使われている、(Fortran に次ぐ) 2 番目に古いプログラミング言語であり、そして最初の関数型言語として知られています。Lisp の作成は 1950年代後半に始まり、最初に実装されたのは MIT による 1958年の AI (Artificial Intelligence: 人工知能) プロジェクトです。Lisp の強みはリストの処理、つまり AI と記号計算にあります。実際、Lisp は「list processor」の略であり、以下の段落で説明するように、このプログラミング言語はリスト処理のために作られたのです (Lisp の歴史に関しては「参考文献」を参照してください)。
すぐにおわかりになると思いますが、Lisp は他の一般的なプログラミング言語とはまったく異なります。例えば、大部分の一般的なプログラミング言語で乗算を行う際には、紙の上で計算する場合とまったく同じように、int times = 5 * 5; のようにします。
Lisp では、(* 5 5 3) とすると 75 が生成されます。(MAX 9 8 7 6 20) というリストがあると、最大値として 20 が返されます。
ここで「最初の関数型言語」という言い方が当を得ていることに注目してください。すべてが関数に基づいているのです。各関数が持つパラメーターの数は変更可能です。上記のようなリストを、再帰と、car や cdr などの Lisp 関数を使って処理できることを見ると、Lisp を使ったリスト処理が強力なことがわかります。
Lisp の歴史は古いため、Lisp 用の開発環境は数多くあります。しかし同時に、古いプログラミング言語にありがちなことですが、ツールのサポートは大部分がテキスト・ベースであり、慣れない人には直感的ではありません。従って Cusp を試す 1 つの理由は、Cusp のインターフェースがテキスト・ベースの「すべてのコマンドを覚えて使う」種類のものではなく、初めての人でも Lisp を学べ、Lisp で開発できる直感的な GUI であるためです。また Cusp には、Eclipse の GUI フレームワークに特有の、優れたプロジェクト管理機能があるという利点もあります。
先に進む前に、Eclipse.org から最新の Eclipse Classic のバンドルをダウンロードする必要があります。ダウンロードが終わったら Cusp のインストールと設定の方法を学ぶことができます。
圧縮された Eclipse Classic バンドルのアーカイブを入手できたことと思いますので、アーカイブを解凍し、eclipse.exe を実行します。
最新バージョンの Cusp を入手するには、Help > Software Updates > Find and Install をクリックします。Search for new features to install (インストールする新規フィーチャーを検索) オプションをクリックします。今度は New Remote Site ボタンをクリックします。リモート・サイトの名前として Cusp update site と入力し、URL には http://www.sergeykolos.com/cusp/update と入力し、OK をクリックします (図 1)。
図 1. Cusp 用のリモート・サイト情報を入力する
追加した新しいリモート・サイトの隣にあるチェックボックスをクリックし、Finish をクリックします (図 2)。
図 2. Cusp Eclipse Update Site を選択する
別のウィンドウが表示されるので、そこで Cusp Eclipse Update Site を展開して Cusp を選択します (図 3)。
図 3. インストールするフィーチャーを選択する
Next をクリックします。次に使用許諾契約書を読み、I accept the terms in the license agreement (使用許諾契約書に同意します) をクリックして使用許諾契約書に同意し、Next をクリックします。すべてのライブラリーが選択されていることを確認し (図 4)、そして再度 Next をクリックします。
図 4. オプションのフィーチャーを選択する
最後のページには、これからインストールしようとしているフィーチャーのインストールの概要が説明されているので、Finish をクリックします。すると、プラグインとそのコンポーネントがダウンロードされ、インストールされます。ダウンロードが終わると、署名されていないフィーチャーをインストールしようとしています、という内容の警告が表示されるので、Install all をクリックします。インストールの最後では Eclipse をリスタートするように促されるので、Yes をクリックします。
これで Eclipse の Cusp プラグインをインストールできました。次に Lisp プロジェクトを設定します。
Lisp 開発を始める前に、新しい Lisp プロジェクトを設定する必要があります。そのためには、File > New > Project と進みます。Lisp フォルダーを展開し、Lisp Project をクリックし、Next をクリックします。新しいプロジェクトの名前として my_new_lisp_project と入力し (図 5)、Finish をクリックします。
図 5. 新しい Lisp プロジェクトに名前を付ける
Finish をクリックすると、新しいプロジェクトが作成され、Lisp パースペクティブが開きます (図 6)。
図 6. Lisp パースペクティブ
Lisp パースペクティブをよく見てください。Lisp Navigator ウィンドウは、開いているプロジェクトと、そのプロジェクトの関連ファイルを表示しています。Outline ウィンドウは現在開いているファイルの概要を表示しています。最上部右のウィンドウ (main.lisp を示しています) が Lisp 開発ウィンドウです。最下部右のウィンドウ (REPL) はコマンドラインの Lisp インタープリターであり、ここで Lisp コマンドを実行することができます。
Eclipse を閉じてから再度開いた場合には、プロジェクトの .asd ファイルをロードする必要があります (図 7)。
図 7. ASD ファイルをロードする
my_new_lisp_project フォルダーの下にある my_new_lisp_project.asd ファイルを右クリックし、Load asd を選択する必要があることに注意してください。これは要するに REPL ウィンドウで Lisp プロジェクトをコンパイルし、新しいコードを使用する Lisp コマンドを入力できるようにしているのです。
次に、Cusp を使った Lisp 開発を試してみましょう。
まず、単純なカスタム関数を定義し、その関数のテストも行います。main.lisp ファイルを開き、defun (define function) コマンドを使って下記を追加します。
... (defun first_howdy_function () "howdy ho") |
Save the file. To export the function from within the package, type the following code in defpackage.lisp:
... ;; Exported symbols go here first_howdy_function )) |
このファイルを保存します。この関数をパッケージ内部からエクスポートするには、defpackage.lisp 内で次のコードを入力します。
この関数は、パッケージの外部から使うことができます。新しい関数をテストするためには、REPL の下側のウィンドウで (my_new_lisp_project:first_howdy_function) と入力します。
この場合では、これは (my_new_lisp_project::first_howdy_function) と入力することと同じであることに注目してください。これを入力する必要があるのは、この関数を defpackage.lisp 内でエクスポートしなかった場合です。
Send をクリックし、出力を確認します。上記のどちらかのコマンドを入力すると、出力は次のようになります。
COMMON-LISP-USER> (my_new_lisp_project:first_howdy_function) "howdy ho" |
これで、最初の Lisp 関数 Howdy ができあがりました。
入力を持つ echo 関数を試してみましょう。
... (defun first_echo_function (echoval) echoval) |
先ほどの関数と同じように、これを defpackage.lisp 内でエクスポートします。この first_echo_function をテストするには、REPL ウィンドウの下の方の部分に (my_new_lisp_project:first_echo_function '("howd" "y h" "o")) と入力します。'("howd" "y h" "o") の部分がリストを定義する構文であることに注意してください。まず、括弧の前に単一引用符が必要であり、そしてその括弧の中でリスト要素が定義されます。この出力は次のようになります。
COMMON-LISP-USER>
(my_new_lisp_project:first_echo_function '("howd" "y h" "o"))
("howd" "y h" "o")
|
今度は、各リスト要素を個別に処理するメソッドを作成します。このメソッドが Lisp の真の実力を示すのです。これを次のように定義します。
(defmethod concat2 ((str1 string) (str2 string)) (concatenate 'string str1 str2)) |
上記のメソッドが実際にはストリング型を定義していることに注意してください。ここまでは、ほとんど型を持たない言語として Lisp を使ってきました。二重引用符でデータを暗黙的にストリング型にすることもできますが、上記のメソッドは concat2 関数の入力と出力の両方を明示的にストリング型にします。またこのメソッドは、組み込みの連結関数を使って 2 つのストリングを結合させ、それらを 1 つのストリングとして返します。
concat2 をテストするためには、concat2 をエクスポートし、(my_new_lisp_project:concat2 "howd" "y ho") と入力します。その出力は次のようになります。
リスト 7. 2 つのストリングを連結した出力
COMMON-LISP-USER>
(my_new_lisp_project:concat2 "howd" "y ho")
"howdy ho"
|
これでできあがりです。ストリング「howd」と「y ho」が「howdy ho」になります。今度はもっと一般的な連結関数を、car と cdr という 2 つの関数を使って作成します。Lisp は、この 2 つの関数で有名です。
リスト 1. リストの中の 3 つの要素を連結する
(defun concat3 (args_list)
(concat2 (car args_list)
(concat2 (car (cdr args_list))
(car (cdr (cdr args_list))))))
|
この関数も先ほどと同じく concat2 関数を使っていますが、入力としてパラメーターのリストを使っていることに注意してください。連結される各部分が、どのように args_list から取得されるのかを見てみましょう。car はリストの最初の要素を取得します。cdr は最初の要素を除いたリストを返します。最初の要素を取得するには、単にリストに対して car 関数をコールすればよいことがわかります。2 番目の要素を取得するためには、リストに対して cdr をコールし、次に新しいリストに対して car をコールする必要があります。3 番目の要素を取得するには、リストに対して cdr を 2 回コールし、最後のリストに対して car をコールします。
上記の関数をエクスポートした後の関数の出力は次のようになります。
COMMON-LISP-USER>
(my_new_lisp_project:concat3 '("howd" "y h" "o"))
"howdy ho"
|
これでできあがりです。3 つのストリングは正しく連結され、「howdy ho」になりました。次に、再帰関数を作成します。
最後に作成する関数は、再帰を行います。Lisp を使ったリスト処理の真の実力は、ここにあります。Lisp でリストを処理する方法としては、繰り返しも (各項目を 1 つずつループすることで) 可能ですが、Java 言語などの一般的な言語とは異なり、何と言っても再帰が最も容易なのです。このセクションを最後まで読むと、再帰とは一体何かを正確に理解できるはずです。
まず、再帰的な concat 関数を作ります。
リスト 2. 再帰的な連結 (無限のパラメーター)
1 (defun concat_recursive (args_list)
2 (if (equal (cdr args_list) nil)
3 (car args_list)
4 (concat2 (car args_list)
5 (concat_recursive (cdr args_list)))))
|
再帰は理解しにくい概念なので、順を追ってこの関数を見ていきましょう。
- 上記の関数に任意の引数リストが渡されたとします。
- リストの中に 1 つの要素しかない場合 (2 行目の
(cdr args_list)の部分は nil を返します) には、1 つの要素 (3 行目の(car args_list)) を返します。 - リストの中に複数の要素がある場合には (つまり 2 行目の
(cdr args_list)がnil を返さなかったら)、リストの最初の要素 (4 行目を見てください) と、(cdr args_list) の結果をパラメーターとして使って再帰的にconcat_recursiveをコールした結果 (5 行目を見てください) とを (concat2を使って) 連結した結果を返します。
'("ho" "wd" "y" " h" "o") というリストをパラメーターとして渡したとすると、出力は次のように行われます。
- 初めて 2 行目に達した時には
if文は偽であり、「ho」と「(concat_recursive '("wd" "y" " h" "o"))」 を引数としてconcat2がコールされます。 - 2 回目に 2 行目に達した時には、
if文はまたも偽であり、「wd」と「(concat_recursive '("y" " h" "o"))」を引数としてconcat2がコールされます。 - 3 回目に 2 行目に達した時には、
if文はまたも偽であり、「y」と「(concat_recursive '(" h" "o"))」を引数としてconcat2がコールされます。 - 4 回目に 2 行目に達したときには、
if文はまたも偽であり、「h」と「(concat_recursive '("o"))」を引数としてconcat2がコールされます。 - 5 回目は、再帰が終わる魔法の時です。今度は 2 行目の
if文は真であり、単純に「o」が返されるからです。この再帰を「巻き戻し」してみると、次のようになります。
- 4 回目: 「
h」と「o」が連結されて返されます。 - 3 回目: 「
y」と「ho」が連結されて返されます。 - 2 回目: 「
wd」と「y ho」が連結されて返されます。 - 1 回目: 「
ho」と「wdy ho」が連結され、そして最終的な結果として返されます。
- 4 回目: 「
そして、これでできあがりです。次のように、最終的に「howdy ho」が返されます。
COMMON-LISP-USER>
(my_new_lisp_project:concat_recursive '("ho" "wd" "y" " h" "o"))
"howdy ho"
|
これで、Cusp 開発の兵器として再帰を追加できました。次にデバッガーを試します。
concat_recursive が処理に失敗し、デバッガーが役立つような入力条件を考えてみてください。そうした条件の 1 つとして、ある数字をストリングの中に混在させて送信し、何が起こるかを調べてみましょう。concat2 を使った連結には 2 つのストリングが必要なことを思い出してください。そのため、数字があると、この関数は再帰の中で処理が中断します。
コマンドとして (my_new_lisp_project:concat_recursive '("ho" "wd" "y" 55 " h" "o")) と入力します。二重引用符で囲まれていない数字 55 はストリングではなく、これによってデバッガーが表示されることに注意してください (図 8)。
図 8. デバッガーを起動する
デバッガーを起動する主なエラーが、(55 " ho") というリストに対して concat2 をコールできないというエラーである点に注目してください。また、エラーがトリガーされる前に「 h」と「o」が既に連結されていたことにも注目してください。
デバッガーのウィンドウには、==Backtrace== も表示されています (図 8)。その下にある各行 (この場合は 0 から 19) は、Send をクリックした時から発生している障害までの詳細なトレースを表示しています。このバックトレースでは、障害のトリガーとなった数字の 55 までさかのぼって再帰を調べ、追跡することができます。
追跡が終了したら、今度は何をするのでしょう。上記のケースでは、デバッガーの終了方法と、関数への入力の変更と検証の方法として、3 つの選択肢があります。コマンドを強制終了して通常の REPL ウィンドウに戻る方法、(テストによって) 接続を閉じる方法 (この方法を選択した場合には Eclipse をリブートして Lisp プロセッサーをリスタートする必要があります)、あるいは単純にデバッガーを強制終了して通常の REPL ウィンドウに戻る方法、の 3 つです。デバッガーを終了するために一番良い方法としては、必ずコマンドを強制終了して通常の REPL ウィンドウに戻ることです。
これで完了です。再帰関数を Lisp で実装することができました。
Eclipse の Cusp プラグインを使った、この Lisp による開発を無事に完了することができました。なぜ Lisp が強力なのか、これでよく理解できたことと思います。Lisp では単純な再帰文を使うことで、記号とデータのリストの強力な処理を容易に行うことができるのです。また Cusp は Lisp の機能を補完してくれます。その際に使用するのは、組み込みの Cusp デバッガーや、プロジェクト管理機能を持つ安定した GUI、対話型の Lisp エディター、そしてコマンドを入力でき、コードをテストできる、Lisp プロセッサーとのコマンドライン・インターフェースなどがあります。さらに詳しくは「参考文献」を参照してください。
| 内容 | ファイル名 | サイズ | ダウンロード形式 |
|---|---|---|---|
| Cusp article sample code | os-eclipse-lispcusp.code.zip | 28KB | HTTP |
学ぶために
-
Eclipse 用の Lisp プラグイン、Cusp を詳しく学んでください。
- 1979年2月12日にスタンフォード大学の人工知能研究所の John McCarthy が書いた「History of Lisp」を読んでください。
- Cusp の中から HyperSpec と LispDoc を使う方法を、Sergey Kolos 著による「Programming In Lisp With Cusp」という標題の文書で学んでください。
-
Wikipedia で Common Lisp について学んでください。
-
Paul Graham による Lisp に関するエッセイを読み、Lisp の歴史と使い方を理解してください。
- Eclipse のプラグイン・アーキテクチャーの基本とプラグインの作成方法が「Eclipseプラグインの開発」に説明されています。
- プラグインの開発に関する詳しい情報は、Eclipse.orgを見てください。
- Eric Clayberg と Dan Rubel の共著による『Eclipse: Building Commercial-Quality plug-ins』には Eclipse のプラグインの作成方法が詳しく説明されています。
-
Eclipse 用のプラグインの完全なリストを見てください。
-
Eclipse Project には Eclipse のドキュメンテーションや記事、ダウンロードなどが用意されています。
- 「Eclipse の推奨読み物リスト」を調べてみてください。
- developerWorks には他にも Eclipse に関する資料が豊富に用意されています。
- Eclipse が初めての人は、developerWorks の記事、「Eclipse Platform 入門」を読み、Eclipse の起源やアーキテクチャー、そしてプラグインを使った Eclipse の拡張方法を学んでください。
- IBM developerWorks の Eclipse project resources を利用して Eclipse のスキルを磨いてください。
-
developerWorks podcastsでは、ソフトウェア開発者のための興味深いインタビューや議論を聞くことができます。
- Eclipse プラットフォームへの入門として、「Eclipse Platform 入門」を読んでください。
- developerWorks の Technical events and webcasts で最新情報を入手してください。
- IBM とオープンソース技術、そして製品機能を調べ、学ぶために、無料の developerWorks On demand demos をご覧ください。
- IBM オープンソース開発者にとって関心のある、世界中で今後開催される会議や業界展示会、ウェブキャスト、その他のEventsについて調べてみてください。
- developerWorks の Open source ゾーンをご覧ください。オープンソース技術を使った開発や、IBM 製品でオープンソース技術を使用するためのハウ・ツー情報やツール、プロジェクトの更新情報など、豊富な情報が用意されています。
-
Cusp Eclipse Update Site を訪れ、Cusp をダウンロードしてください。
製品や技術を入手するために
- Eclipse.org で Eclipse をダウンロードしてください。
-
alphaWorks に用意された最新の Eclipse technology downloads を調べてください。
- Eclipse Foundation から Eclipse Platform やその他のプロジェクトをダウンロードしてください。
-
IBM 製品の評価版をダウンロードし、DB2® や Lotus®、Rational®、Tivoli®、WebSphere® などのアプリケーション開発ツールやミドルウェア製品を試してみてください。
- 皆さんの次期オープンソース開発プロジェクトを IBM trial software を使って革新してください。ダウンロード、あるいは DVD で入手することができます。
議論するために
- Eclipse に関する質問を議論するための最初の場所として、Eclipse Platform newsgroups があります (このリンクをクリックすると、デフォルトの Usenet ニュース・リーダー・アプリケーションが起動し、eclipse.platform が開きます)。
-
Eclipse newsgroups には、Eclipse を利用し、拡張することに関心を持つ人達のために、さまざまなリソースが用意されています。
-
developerWorks blogs から developerWorks のコミュニティーに加わってください。