今日は…いろいろありすぎ!
GNUプロジェクトが開始された日であり、Googleの誕生日であり、ラリー・ウォールの誕生日であり、アラン・シュガートの誕生日でもある。
アランシュガートは、ハードディスクの研究者で、フロッピーディスクの開発者で、Seagate の創始者ね。
彼がいなくては今の生活はないとは思うけど、僕の知識不足であまり語れることがない (^^;
GNU と Google は誰かが書きそうだから、僕はラリーについて書こう。
(もっとも、彼についてもそれほど知らないので、Perlの話と雑文だらけになるけど)
ラリーウォール(Larry Wall)は、Perlの作者だ。
プログラムの差分を配布する際に使用されるツール、patch の作者でもあるし、rn の作者でもあるし、国際難解Cコードコンテストで2回も入賞している。
簡単に言えば、「凄腕のハッカーだ」となる。
まずは rn から行こうか。僕は、rn の実物は使ったことがない…とおもう。
もしかしたら、大学のころに少しくらい使ったかもしれない。
その昔(今でもあるが)インターネット上には、「ネットニュース」と呼ばれるシステムがあった。
掲示板みたいなものなんだけど、どこかにホストがあるのではなく、分散してデータを保持していた。
rn は、このニュースを読んだり書いたりするためのソフト。
Usenet 用の…という表記をよく見るけど、Usenet とネットニュースが同一視されていた時代がある(いまも、WEBとインターネットを同一視する場合があるでしょ?)ために混同されているだけ。
Usenet は ARPANET とは「別に」インターネットの母体となったもう一つのネットで、いつか話をしたいところだけど今日は割愛。
そしてまた、ラリーは patch も作った。
これは、ソフトウェアを配布するときに、劇的な圧縮をかけてくれるツールだ。
…といっても、圧縮ツールではない。
2つのファイルの差を見つけ出し、出力してくれる、と言うソフトは以前からあった。
だから、ラリーはその逆をやったんだ。
差を見つけ出すソフトが出力したファイルを patch に入力すると、「以前のソフト」を元に「新しいソフト」を作り出してくれる。
プログラムを配布するときは、以前と変わった部分だけを配布すればよいことになる。
これは、劇的な圧縮方法だった。
patch は今でも UNIX の重要なツールとして使われている。
ところで、僕は rn のソースコードを読んだことはないのだが、「えぐい」ものだったらしい。
出来の悪いコードだという意味ではなく、感動的だったというのだから、おそらくは常軌を逸した方法で最適化されていたのだろう。
というわけで、ラリーのもう一つの顔、国際難解Cコードコンテンスト(The International Obfuscated C Code Contest : 以下 IOCCC と表記する)の入賞のお話に移ろう。
IOCCCは、C言語ハッカーたちのお祭り。Wikipediaによれば、お祭りと言っても「奇祭」だそうだ。
単にC言語でプログラムが組める、と言うレベルではなく、C言語の仕様の詳細まで知り尽くしたばかりか、その仕様の本当の意味を理解し、故意に変な書き方をしたプログラムを作る、というコンテストだ。
目的の一つには、Cの奥深さを引き出すことがある。別の側面としては、どうすれば「読みにくいコード」になるかを示すことで、読みやすいソースコードの普及を促す、という皮肉がある。
とにかく、単に難解なプログラムを書くのではなく、審査を行う凄腕ハッカー達をうならせるほどの技法を見せつけなくてはならない。
ラリーはこのコンテストで1986年と1987年に入賞している。
ソースコードも公開されているのだけど、見てもさっぱりわからない(笑)
ちなみに、ANSI C ができたのは 1989年なので、プログラムは K&R で書かれている。
1987年の作品は Linux 上の GCCでワーニングが出たがコンパイルできた。1986年のものは、コンパイルすらできなかった。
GCC は K&R のプログラムでもコンパイル可能なように作られているが、ここまで変態だと厳しいようだ。
そして、修正しようにも中身が理解できていないので修正できない (x_x)
1987年の作品、コンパイル後を wall と言う名前だとして
wall | bc | wall
として起動すると、ローマ数字計算機になる。
x*x (10*10の意味)を入力すれば c (100) と出るし、c^2 とすれば mmmmmmmmmm (1000*10)と出る。
ところで、UNIX コマンドの bc は計算機だ。つまり、wall はローマ字数字を算用数字に直しているに過ぎない。
じゃぁ、wall | bc とすると、今度は 100 、 10000 と普通に答えを出してくれる。
面白がって mcmlxxxvii と入れると、 1987 と出た。
#ローマ数字でこの文字列を思い出す人は、往年のナムコマニアに違いない。
ところで、最初の例を見る限り、wall は bc の値を受け取ってローマ数字に変換する役割も負っているようだ。
そこで、今度は wall だけを起動し、1987 と入力してみる。mcmlxxxvii と出力される。
なるほどなるほど。おそらく、入力がアルファベットか数字かで動作を変えているのだな、と推測し、再び mcmlxxxvii と入れてみる。
…あれ、何も出ない。x と入れても、 c と入れても何も出ない。
いったいどうなっているの?
実は、ここら辺が、このプログラムが入賞した理由。ローマ数字と算用数字の相互変換くらい、ちょっとしたハッカーなら簡単に作れるし、そのコードをあえて難解にするのも難しくはない。
それだけでは入賞なんてしない。
このプログラム、動作の切り替え方法がちょっと変わっているのだ。
入力された文字によって動作を切り替えるのではなく、標準出力がリダイレクトされているかどうかで動作を変えている。
だから、 wall | cat として x や c を入れると、何をやっているか見える。
ローマ数字から数字への変換はかなりスマートだが、こちらは bc への入力を前提にしているため、かなり強引だ。そして、この強引さを普通は見えないように隠しているわけだ。
すごいプログラムだ。でも、参考にしてはいけない。
IOCCC は、「やってはいけない」技法を競うコンテストなのだから。
さぁ、最後に perl の話をしよう。
少し前なら、perl はネット上のいたるところで使われていた。だから説明は不要だったけど、今だと少し説明した方がいいかな。
perl は、ラリーが作ったプログラム言語だ。
もちろん、IOCCCで入賞するような「イカレた」ハッカーが作ったものなので、普通ではない。
perl はテキスト処理のための言語だ。
たとえば、テキストファイルで書かれた、なんらかのデータベースがあったとする。
自分なりに書式を定めて作ったが、テキストなのでかなり自由に記述しているとしよう。
このテキストのデータベースから、特定の条件に合ったデータだけを取り出して、必要な部分だけをまとめたい。
テキストが小さければ自分でエディタで頑張ればいいのだけど、10万件もデータが入っていると現実的ではない。
そういう時、perl があればすごく役に立つ。
実は、同じ目的で作られた言語に awk がある。awk は非常に便利なのだけど、基本的に「1行1データ」で、「項目はタブやカンマで区切られている」ことを前提にしていた。
また、ファイルとしては1つだけ、を前提にしている。
実は、今でもこの前提に当てはまるときは awk の方がずっと簡単に処理ができるのだけど、制限を超えたとたんに awk では扱いが難しくなる。
perl は、そういう時に役立つ言語だ。
perl が「イカれてる」と僕が感じたのは、文法構造が無茶苦茶で、大胆な省略が可能なところだ。
perl は、様々なソフトから、便利だと思う機能を持ってきてくっつけてある。
その際、「機能を」追加するだけではなく、コマンドなどもそのまま持ってきてある。だから元のツールを知っていれば、習得時間が最小限で済む。
その反面、文法構造がツギハギだらけで無茶苦茶だ。それを強引にまとめ上げ、非常に強力な言語に仕上げているあたりがすごい。
さらにすごいのが、perl は省略がいろいろと可能だと言うことだ。
普通プログラムと言うのは細かな部分まで指定してやらないと動かない。コンピューターは基本的にバカなもので、教えたこと以外出来ないのだから。
でも、perl を使うと、当たり前にやっておいてほしいことは、省略して構わない。
省略された部分は perl の方で勝手に察して、よきに計らってくれる。
もちろん、これを使いこなすには省略のルールをある程度把握していないといけないのだけど、これが使っていて非常に便利なのだ。
今は少し下火になったとは言え、perl が一時期もてはやされたのは、強引にいろんな機能をまとめ上げ、大胆な省略を可能にしたセンスが非常によかったからだと思う。
#もちろん、WEB 黎明期の時流に乗った、という要素も大きいけど。
CPAN と perl 6 の話もしたかったけど、長くなりすぎたのでここらへんで一区切りにしよう。
今日はラリーウォールの誕生日祝いで、perl の話ばかりにしたいわけではないから。
これらの話は、またいつか。
公開から1時間後に追記
書こうと思っていた「プログラマ3大美徳」を書き忘れていた。
ラリーウォールが提唱したもので、次の3つのものは、プログラマが心がけるべき美徳である。
・怠惰
・短気
・傲慢
怠惰であれば、面倒くさいからコンピューターにやらせてしまえ、と考えてよいプログラムを作り出すし、後で質問が来るのを嫌がってドキュメントを残す。
短気であれば、今目の前にあるコンピューターの動作に怒り出し、「もっと良いもの」を作り上げるし、まだ起こってもいない問題を想定して将来性のあるプログラムを書く。
傲慢であれば、自分の作ったプログラムを素晴らしいと考えて公開するし、人に見せつけてやるつもりで保守性の良いプログラムを作り出す。
プログラマーはみな、怠惰で、短気で、傲慢であるべきだ。
僕がそうなれているかと言えば、なろうと努力しているけどなかなか難しいですね (^^;
同じテーマの日記(最近の一覧)
関連ページ
プログラム言語における「デフォルト動作」【日記 15/01/29】
別年同日の日記
申し訳ありませんが、現在意見投稿をできない状態にしています。 |