- 更新日: 2017年03月09日
- 公開日: 2016年02月01日
人工知能で大活躍!今熱い「LISP」の成り立ちとこれから
LISPという言語をご存知でしょうか。
「カッコ。とにかくカッコ」「独自路線」「古い」「とにかくカッコ」などの印象が一般的でしょうか。あまりメジャーな言語ではないというのが、正直な位置づけでしょう。
本エントリでは近年の人工知能の発達に伴ってLISPが見直されていることから、LISPのこれまでの歴史を振り返り、今後の動向を占ってみることにしましょう。
LISPの生い立ち
LISPは1958年に開発された、現在広く使われているプログラミング言語の中で最も古いものの1つです。
開発者のジョン・マッカシーは、実は「人工知能:Artificial Intelligence」という言葉の提唱者でもあります。このような出自から、LISPは人工知能プログラムに多く使われました。人工知能ブームにも乗ったこともあり、急速に普及していくことになります。
しかし長く使われる言語の常として、多くの方言が生み出されてしまいました。方言が多いというのは、ある面では困った状況です。多数の言語仕様と処理系が生み出されるため、汎用性が失われ、中長期的に見ると効率が悪くなるのです。このような状況の中、LISPにも標準化が必要になりました。
2つの主流・Common LISPとSchema
標準化の効果はJavaの成功を見ると分かりやすいと思います。Javaは、言語仕様から処理系、果てはライブラリまで標準化することで、一度書いたプログラムがどこででも動作する、という究極の汎用化を実現しようとしました。そしてある程度これは実現され、現在では世界で最も広く使われているプログラム言語の1つとなりました。
LISPにおける標準は1984年と1994年に、ANSIによって制定されました。これがCommon LISPです。
Common LISPは多機能であることが特徴です。「提案された機能を原則すべて導入する」というのがCommon LISPの姿勢です。このため、Common LISPの言語仕様はかなり大きなものとなっています。
これに対し、LISP本来のシンプルさを重要視して進化を続けているのがSchemeです。1975年に開発され、最新の仕様は2013年7月に成立しています。Schemeの仕様はIEEEが制定しています。
Schemeは当初、Schemerという名前だったそうです。しかし当時のOSではファイル名が6文字までという制限があったため、末尾の r が削られてSchemeになってしまったとか。今では考えられない話ですね。
Common LISPとSchemeは、現在のLISPの主流となっています。ただ、共に仕様であって、実装には多くの種類があります。手軽に試せるのはSchemeの方で、特にGauche実装は日本人が開発しており利用が簡単なので、興味を持った方はこれから始めてみてはいかがでしょうか。
LISPのスタイル
さて、ここで少しLISPで書かれたプログラムを見てみましょう。「LISP」という名前が「LIStProcessor」の略であるように、LISPのプログラムは全てがリストです。なおLISPではリストのことをS式とも言うようですが、この辺りの厳密な話は今回は省略します。
なお、ここではScheme、中でもGauche実装で動作確認を取ったコードを掲載します。
リストを得る
まずはリストを作ってみましょう。リストは()で複数の値を括ったデータ構造です。
[code]
(list 1 2 "foo")
[/code]
LISPではリストを作るのにlist関数を使います。あるいはシングルクオートで括ることでリストを作ることもできます。
[code]
'(1 2 "foo")'
[/code]
関数呼び出し
関数呼び出しは、1番目の要素として関数を持つリストを作ることで実現します。
[code]
(+ 2 3)
[/code]
上記は足し算(+関数)を呼び出しています。
関数定義
LISPで関数を定義するには、define関数を使います。
[code]
(define sum (lambda (x y) (+ x y)))
[/code]
上記は足し算を行うsum関数を作っています。
実はdefineという関数は値を変数に格納するのにも使えます。例えば変数xに10を格納するには、次のように書きます。
[code]
(define x 10)
[/code]
実は関数も、変数に格納された処理(ラムダ、lambda)に過ぎません。LISPのような関数型プログラミング言語にとって、関数とは値でもあるのです。
LISPと人工知能
さてLISPの文法をSchemeを通して少しだけ見てみました。特徴を挙げるならば
- 変数に型がない
- 全てはリストである
- 関数は値でもある
- 関数定義は関数呼び出しで行う
といったところでしょう。これらの特徴から、LISPは「実行と定義の区別がない」「関数とデータの区別がない」という性質を持っています。
このことは、実行時にどんどん新しい処理(=関数)を作り出せ、またそれを記録できるということですから、人工知能のように「自身を拡張していくプログラム」にとても向いているのです。
\AIエンジニアに必要なスキルが身に付く/
LISPのこれから
ここまで、LISPの文法を垣間見て特徴を把握することで、LISPの強みをまとめてみました。
ところで、関数型プログラミングという考え方をご存知でしょうか。これは大雑把に言えば「関数を値として扱えるプログラミング言語を使って堅牢なプログラムを作ろう」というスタイルのことです。
数年前から重要視されるようになってきており、今では関数型のエッセンスのないプログラミング言語は時代に取り残されていると言っても過言ではありません。
このような状況にあっては、「関数とデータの区別がなく」「関数定義、あるいは実行をデータと同様に扱える」というLISPの性質は、ある意味最先端を行っています。また2007年に登場したClojureのようにLISPをベースにした新たなプログラミング言語が未だに生まれてきています。
誕生から50年以上を経過してもなお、最前線で活躍し続けている驚異の言語LISP。一度触ってみてはいかがでしょうか。
- この記事を書いた人
- tomo