Lisp系の言語「Qi」をインストールしてみる

パターンマッチ、カリー化などの機能があり、オプションで静的型付けも使えるLisp系のプログラミング言語「Qi」というのがあるのですが、情報が少ないので、
インストールしてみることにしました。
Ubuntuにインストールします。


QiはCommon Lispで作られているので、Common Lisp処理系をインストールしておく必要がありますが、
前回インストールしたECLには対応していないので、対応しているSBCLもインストールしました。

SBCLのインストール

Qiが対応している処理系は、CLISPCMUCLSBCL、LispWorks、Allegro CLだけなので、
フリーで、インストールしやすい処理系の「SBCL」を選びました。
SBCLは、公式でバイナリが配布されていて、簡単にインストールできます。


まずは、SBCLのダウンロードページ(http://sbcl.sourceforge.net/platform-table.html)から、tar.bz2ファイルをダウンロードします。
OSとCPUの種類が表になっているので、「Linux」の行の、「X86」の列にある「1.0.38 newest」と書かれているところをクリックしてダウンロードします。
ダウンロードしたファイルは、ホームディレクトリに保存しておきます。
次に、端末を起動して、解凍します。

tar jxvf sbcl-1.0.38-x86-linux-binary.tar.bz2

というコマンドを実行すれば解凍できます。
解凍して出てきた「sbcl-1.0.38-x86-linux」というディレクトリに、

cd sbcl-1.0.38-x86-linux/

で移動して、

sudo sh install.sh

というコマンドを実行すればインストールが始まります。
インストールの最後のほうで、「cp: stat `doc/manual/*.info'を実行できません: No such file or directory」のようなエラーがいくつか出ることがありますが、無視しても大丈夫でした。
これでSBCLのインストールは終わりです。一旦、exitコマンドで端末を終了しておきましょう。

Qiのインストール

SBCLをインストールしたので、ここからは、Qi言語をインストールします。


まず、Qiのダウンロードページ(http://www.lambdassociates.org/download/download.htm)の「Source Code」のところにある、一番上の「Download」と書かれたボタンを押して、
「QiII1.07.zip」をダウンロードします。
ダウンロードしたzipファイルは、ホームディレクトリに保存しておきます。
次に、端末を起動して、ダウンロードしたzipファイルを解凍します。

unzip QiII1.07.zip

というコマンドで解凍します。
解凍したら、出てきたディレクトリに、

cd QiII1.07/

で移動します。
さらに、その中にある「Lispディレクトリに

cd Lisp/

で移動して、

sbcl

として、SBCLを起動します。
SBCLを起動したら、

(LOAD "install.lsp")

というLispの式を入力して実行して、Qiをコンパイルします。
コンパイルが終了すると、自動的にSBCLも終了し、シェルに戻ります。
コンパイルが終了してシェルに戻ったら、起動用のシェルスクリプトを実行できるようにするのですが、
起動用のシェルスクリプト「Qi-Linux-SBCL」は、改行コードがWindows用になっているので、

sed -i "s/\r//g" Qi-Linux-SBCL

として、改行コードを変換しておきます。
そして、

chmod +x Qi-Linux-SBCL

で実行権限を付けて、実行できるようにします。


さらに、いつでもすぐに起動できるように、「.bashrc」の最後に

alias qi="sbcl --core ~/QiII1.07/Lisp/Qi.core"

という行を追加して、

source ~/.bashrc

としておくと、「qi」というコマンドを実行するだけですぐにQiを起動できるようになります。


これで、Qiのインストールは終わりです。

Qiを使ってみる

実際にQiでプログラムを実行してみます。
Qiを起動して、

(output "Hello world!~%")

と入力してエンターを押して実行すると、「Hello world!」と出力されます。

(+ 10 20)

のようにして計算もできます。
関数の定義は、パターンマッチを使えます。例えば、階乗は

(define fact
  0 -> 1
  N -> (* N (fact (- N 1))))

のようになります。

(fact 10)

として実行すると、「3628800」という答えが出ます。
Haskellのようなカリー化も使えます。例えば、

((+ 10) 20)

とすると、30が返ります。
最後に、Qiを終了するには、

(quit)

とします。

詳しいことはよくわからないので、もう少し調べて、また今度書こうと思います。