PR
1960 年生まれ,独身フリー・プログラマの生態とは? 日経ソフトウエアの人気連載「フリー・プログラマの華麗な生活」からより抜きの記事をお送りします。2001年上旬の連載開始当初から,現在に至るまでの生活を振り返って,週1回のペースで公開していく予定です。プログラミングに興味がある人もない人も,フリー・プログラマを目指している人もそうでない人も,“華麗”とはほど遠い,フリー・プログラマの生活をちょっと覗いてみませんか。
※ 記事は執筆時の情報に基づいており,現在では異なる場合があります。

 Lispという言語がある。プログラミング歴が長い人なら,カッコをたくさん書く言語ということぐらいはご存じではないかと思う。1980年代にエキスパート・システムと呼ばれる技術がブームになり,その手のプロジェクトで利用されたため,仕事で使ったことがある人もいるかもしれない。

 何を隠そう,私もその一人である。しかし,実を言うと私がLispに出会ったのは,それよりもう少し前―― 高校2年の頃であった。Lispが動くマシンが身近になかったので,書籍に載っていたわずかなソースコードを読み解くだけで満足していた。

 メインフレームに触るチャンスが訪れたのは,その2年後である。最初はFORTRANやPL/Iでちょこまかと遊んでいたのだが,Lisp 1.5と呼ばれる古典的な仕様の処理系が利用できることを知ってからは,Lisp一辺倒になった。

 ちょうどその頃,スタンフォード大学などが利用していたInterlispやマサチューセッツ工科大学(MIT)で開発されたMaclispといった,Lispの中でも先進的と言われる処理系のマニュアルを目にする機会があった。それと同時に,いわゆるコンピュータ・サイエンス系の先進的な研究者や,(当時でいう)ハッカーと呼ばれる人種が“教養”としてLispを習得していることを知った。

 例えば,Javaの生みの親と言われるジェームズ・ゴスリング(James Gosling)の代表的なソフトにGosling Emacsと呼ばれるテキスト・エディタがある。このエディタは機能拡張用スクリプト言語として,MocklispというLisp系の構文を持つ言語を備えている。GNUプロジェクトで有名なリチャード・ストールマン(Richard, M. Stallman)は,Gosling Emacs の仕様を手本に,より本格的なLisp処理系をベースにしたGNU Emacsを開発した,とまあこんな具合である。

 こういった話題を数多く耳にするうちに,私の中ではいつしか「Lisp=インテリあるいはエリートの言語」といった図式が出来上がっていった。もちろんPascalやC言語のような,当時としては新しい言語に触れる機会もあった。だが,突き詰めていくと結局はアセンブラに変換され,ライブラリと呼ばれるブラックボックスを呼び出すという点ではFORTRANとたいして変わらないように思えた。それに引き換え,Lispはその言語仕様の単純明快さと,インプリメントの透明度という意味でとても魅力的に感じられたのだ。

 仕事でソフトウエア開発をするようになってからも,Lisp系の言語に対する憧憬は私の中に深く根付いたままになっていた。そして,1年に1度か2度ぐらいは,ネットを探し回って誰かが作った処理系をダウンロードして動かしていた。しかし残念ながら,納得できるものには出会えなかった。

 そんなことが続いたあるとき,一念発起して,無いのなら自分で作るしかない,と外部仕様から検討を始めた。Lispといえば主力はCommon Lisp系かScheme系である。ざっくり言えば,Common Lispは基本仕様が重く,必要なものはひととおり揃っているかわりに,自分で一から作るのは大変そうである。

 一方Schemeは,基本仕様がコンパクトで,パフォーマンスを抜きにすれば,そこそこのものが出来そうだ。こんなことを考えながら,Schemeの言語仕様を改めて読み返すと,いままで気にしていなかった点が目につきはじめた。

 一番気になったのは,継続処理といって,関数の処理中にreturnした次のコードから処理を継続できる仕組みである。継続処理の機能があれば,大域ジャンプや構造化例外,コルーチンなどがすべてこれで実装できるというのが「教科書」の教えである。

 しかし,あらゆる局面を想定した完璧な継続処理を効率よく実装するのは,大変そうだ。そもそも,すべての制御を継続処理でまかなうことにどれだけの意味があるのだろう,と感じたのが最初だった。言語仕様を読めば読むほど,私の感覚に合わない部分が出てきたのである。

 例えば末尾再帰の処理。これは,再帰呼び出しのコードを内部的にジャンプ処理で実装する手法のことである。こうすることで,例えばフィボナッチ数の計算を再帰的にコーディングしても,スタック・オーバーフローが起こらなくなり,一般的なループ処理をすべて再帰で書くことも可能になる,と教科書には書いてある。しかし,ループで書けるものを,わざわざ誰が再帰でコーディングするだろうか。

 一度疑問を感じると,どんどん不満が出てきた。空のリストとnilとfalseが異なるデータ型として定義されているといった基本的なことから始まり,関数の引数としてキーワード・パラメータを与える仕様がないといったわがままに近いもの,ライブラリのコードを取り込む部分の標準仕様が直感的でないといったほとんど言いがかり的なもの,まである。

 気に入らないところを納得できる仕様に変えてしまえばいいのだろうが,そうして出来上がったものは元の言語の方言でしかない。そんな言語をいったい誰が使ってくれるだろう。

 こういう悩みを抱えたときは,試しにプログラムを書いてみるに限る。ある程度実用的なアプリケーションを想定して仮コーディングをして,ソースコードを眺めて雰囲気をつかむのである。こうしてどれだけの時間を費やしただろう。結論から言うと,私はこのプロジェクトをお蔵入りにした。そして同時に,私が未熟なころに刷り込まれ,30年近く抱えてきたLisp系言語への憧憬も捨て去ることに決めた。

 新しい言語を開発する人はきっと,余計なことはあれこれ考えずに,アイデアを実現するパワーを持っているのだろう。優柔不断な私には,プログラミング言語開発の道はかなり遠そうである。