目次

Common Lispとはなんぞや

Lisp(LISt Processor)は仕様が小さいために、さまざまな方言が生まれてしまった。

そこで、これらの方言を統一しようという事で生まれたのがCommon Lispだ。

ANSIで標準化されていることにも注意していただきたい。これは、実装があって仕様が付いてくる言語(Python,Ruby,VB......etc)とは違い、仕様があるのに合わせてさまざまな処理系が作られている。

このように、仕様が先にあって実装が後に来るということは今日書いたコードが10年後もそのまま動く可能性が高いということである。

これはC/C++やCommon Lispにしか見られない特徴なんじゃないかな?

Schemeでよくね?

実用という点では、Schemeはあまり適しているとはいえない。 また、両者には学習段階でも変数の扱いや関数名の差異が見られる。両方やって好きな方をやるよろし。

始めるには

まず、処理系を選ばなくてはならない。 代表的なものとして、

名前詳細ライセンス
sbclネイティブコードコンパイラで、使っている人も一番多いと思われる。フリーの処理系では最速。修正BSD/パブリックドメイン
Clispバイトコードコンパイラ。sbclの次くらいに人気GNU GPL

が、お手軽だ。学習用ならどちらも大差は無い。*1

UNIX/Linux

Debian/Ubuntu

apt-get install sbcl
apt-get install clisp

のどちらかを実行すれば、インストールできるはず。
ただし、Debianのパッケージは結構古いので
特にsbclに関しては、公式サイトから最新版を落としてインストールすることを勧めたい。

他のOS

上を参考にどうぞ

Windows

Clispとsbclでググれば公式サイトが出てくるからそこでダウンロードすればいい。
インストールはほぼ自動だから楽チン。
Windows用のsbclは、まだテスト段階だからClispの方がいいかも

インスコおわったお

起動してみよう!

コマンドプロンプト等でsbclかclispと入力したら起動するはず *2

[1]>

とか

*

とか出ていれば成功だ。
この状態は、対話式の入出力環境でREPL(Read-Eval-Print-loop)と呼ばれる。

ハロワ

早速、REPLに入力してみよう。
;よりあとはコメントを表すので入力しなくてよい。(ここでは出力をメモしておいただけ)

(format t "Hello world") ; Hello world

format関数は出力をするのに非常に強力で便利な関数なのだ。

四則演算

足し算/引き算

(+ 98 1) ; >> 99

演算子が頭にある。これこそがLispの特徴だ。
ここではとりあえず関数は() ......すなわちリストの頭に表記して引数をその後に入力するという事を覚えてもらいたい。
尚、次のような表記も有効だ。

(        +           3      8   ) ; >> 11

このように、スペースが二つ以上になると無視される。

引き算は次のようにする。

(- 30 14) ; >> 16
(- 3 6) ; >> -3

掛け算/割り算

(* 5 7) ; >> 35
(/ 3 2) ; >>  3 / 2
(/ 3.0 2) ; >> 1.5
(mod 3 2) ; >> 1
(mod 10 4) ; >> 2
(/ 1 0) ; -----エラーが表示される。


掛け算は他のプログラミング言語と大差ないだろう。(演算子の前置記法以外は)
問題は割り算だ。2番目の例を見れば分かると思うが、Common Lispでは分数を使う事ができる。
ただし、小数を割る時には成り立たない。
また、モデュラー算術も可能だ。
このほかにも、さまざまな算術のための機能が実装されている。

関数を作ろう

関数の定義には、defun関数を使用する。
構文は、

(defun 関数名 (引数1 引数2 ......) 実行してほしい処理)

だ。さっそく例を見てみよう。

>>(defun 3jo (x) (* x x x))
3jo
>>(3jo 2) 
8
>>(defun 3jo (x) (* x x x) () )
3jo
>>(3jo 8)
nil

二つの例を見比べてみると、実行してほしい処理のところが
(* x x x) と (* x x x) () との2通りがある。
実は、defunで作られた関数は最後に実行した処理によって出てきた値を返り値として返すのだ。
これは実は関数プログラミングの根幹を成すものである。
Common Lispでは、Return文は必ずしも必要ではないのだ。

ところでこの nil というのはなんだろうか。
これは否定の論理演算子だ。(nihilのことじゃないかな)
nilとt (trueのこと)は変数として使用する事が出来ない。

変数と定数

グローバル変数

(defparameter *oppai* 99)

とすると、グローバル変数が定義できる。
今回は、*oppai*という変数に99を代入している。

*oppai*

とREPLで入力すれば、99が返ってくる。
この変数の周りの *(アスタリスク)はグローバル変数であることを強調するための、Common Lispにおけるマナーのようなものだ。*3


他にグローバル変数と定義する方法として、

(defvar *foo* 10)

とする方法がある。

(defvar *foo* 10)
(defvar *foo* 8)

としても、*foo*の値は10のままであるから注意が必要だ。

(setf((setqというのもあるが、setfの方が新しい。また、setfの使用が推奨されている。)) *foo* 8)

とすれば、値を変更できる。

定数の定義

(defconstant お名前 値)

でできる。 setfで値を変更する事は出来ない。


*1 ClispはTABキーで関数の名前を保管してくれたりするが、sbclにデフォルトでそのような機能は無いので、初心者の使いやすさという点ではClispが勝る
*2 PATHの設定とかは、Windowsならインストーラーが自動でするはず。UNIX系は/usr/bin/にでも入っているだろう
*3 *のことを特に、earmuffと呼ぶ