2015/01/14

どのようにして僕はプログラマになったのか思い出してみた

一番最初に僕がプログラミングをしてみたいと思ったのはコンピュータを手にする前からだったと思う。

あるとき小学校高学年の頃に読んでいた子供向けの雑誌の巻末に、巡回セールスマン問題のような懸賞問題が載っていて、最高得点を出した読者に景品が当たるなどというものをみて、それを手でひたすら試行していた。それを見た親が「これはコンピュータでバーッと計算するんじゃないか」みたいなことを言った。そのとき、そうか、こういうのはコンピュータを使えば手でやらなくていいんだ、機械的にパターンを試していくだけなんだからな、と思ったのだった。

その懸賞には相当時間を費やしたのだけど、結局景品はもらえなかった。当然だれかがプログラムを書いて、僕の手で求めた解よりよい解を一瞬で見つけてしまったんだろう(しかし僕は今でも、人間がやるかコンピュータでやるか微妙なくらいの問題をひたすら手でやるのはなぜかかなり好きではある)。

子供の頃から本を読むのが好きだったので、僕は毎週図書館に通っていた。ある時、セルオートマトンの本を読んで、このシミレーションは無茶苦茶面白いなと思った。いまだに僕はコンウェイのライフゲームが動いていくのを眺めていてずっと飽きないのだけど、別にセルオートマトンは抽象的なレベルでも面白いというか、実際にパタパタ動いていくのを見なくても、本で仕組みを学ぶだけでわくわくしてたまらないのだった。ノートを使ってセルオートマトンを手で一世代ずつシミュレーションしてみたりした。

問題はコンピュータを持っていないことだった。

最初にPCを手にしたのは14〜15歳くらいの頃だったと思う。入手したのはコンパックのノートPCで、HDDは80MB、メモリは4MBという代物だった。しばらくはゲームなどをして遊んでいたが、すぐにそれに飽きたらずもっと違うことをしてみたくなった。中学生なのでお金はなかったが、本屋の雑誌コーナーでパソコン雑誌をだいたいすべて立ち読みしていたので、なにがいま面白いのかという情報はわりとよく知っていた(いまでもネットのニュースは超くだらないものから真面目なものまでだいたい何でも読んで知っているが、そこもあまり変わらない)。そこで当時目新しかったLinuxをインストールしてみようと考えた。

1994年〜1995年のLinuxは今よりもっとマイナーだった。当時はSlackware Linux + 日本語拡張パッケージJEという組み合わせがメジャーだったので、それをインストールしようと思ったのだが、なにしろHDDが80MBしかなかったので、WindowsとLinuxのデュアルブートは厳しかった。そこでWindowsはきっぱり諦めてLinuxをインストールしようと思った。

まずは40枚くらいフロッピーディスクを用意して、ネットからダウンロードしてきたフロッピーイメージを書き込んで、インストールメディアを用意した。CD-ROMドライブは持っていなかったのでフロッピーだけが自分で使えるメディアだった。

フロッピーディスクは信頼性の比較的低いメディアで、よく読み込みエラーが起こった。インストール途中に30枚目くらいで読み込みエラーが起きると面倒くさくてめげそうになった。30枚目を再作成するためには、まずWindowsを再インストールして、ネットに接続し、30枚目のディスクイメージを再ダウンロードするところからやり直さなければいけなかった。それでまた35枚目くらいにエラーがおきると本当にめげそうになった。

当時はやたらOSのインストールばかりしていた。ただのインストール厨だったといってよいと思う。

とはいえインストールもマニュアルがすべて基本的に英語なので、中学生には大変だった。いまではアメリカで仕事をしているくらいには英語ができるようになったけど、当時はコンピュータを使いたいだけなのになぜ英語を覚えなければいけないんだと、納得できない気持ちになったのを覚えている(いまだに僕はコンピュータのために英語を覚えている面があるので、同じようなことはいまでも思っているけど)。

高校生になってもそのあたりは変わらなかったが、インストール厨はある程度脱して、ある程度まともにコンピュータに取り組むようになった。当時もまたお金はなかったので、本屋に行ってコンピュータサイエンスの本をひたすら立ち読みしていた。例えばAndrew Tanenbaumの分散オペレーティングシステムの本を夏休みに立ち読みで読みきったりしていた。分厚い本を立ち読みすると手が疲れた。いまから考えてみるとある意味勤勉で感心な奴なのだが、当時はこんなことをやって一体俺はどうなるんだろうかという、ある種の鬱屈した感覚があったように思う。

プログラミングも徹夜で取り組んだりしていた。途中までできると中途半端なところで寝る気にはならないし、一つ機能が完成するとそこでも寝る気にならないので、結局朝になるのだった。これもまた頑張っているというよりは、たんに面白いからやっているだけで、本来はまともな勉強をするべきだと思っていた。2010年台の現在でははむしろいわゆる「意識の高い」人たちがプログラミングしてるふりをしたがるくらいなのかもしれないが、昔はそういう雰囲気はなかった。誰かメンターがいてそれでよいのだと言ってくれればよかったのかもしれなかったが、そういう大人も周りにはいなかった。

その頃に覚えたことで今でも役に立っていることは驚くほどたくさんある。一方でまったく役に立っていないこともたくさんある。UnixとかCとかネットワークとか、コンピュータ関連の雑多だが膨大な知識は大変役にたっている。一方で、例えば大変分厚いオライリーのDNS&BIND本は何度も覚えるくらい読み返したけど、そのDNSとかBINDの知識はいまほとんど役に立っていない。DNSの設定なんて普段しないからね。

フルスタックエンジニアというのが、スキルがいろんなところで過剰なエンジニアという意味なら(特定の状況においてぜんぶピッタリ必要なだけのスキルを最初から持っているのはありえない)、そういうムダ知識も完全に無駄とは言えないとは思う。

いずれにせよ当時は原因不明のやる気があったので、Unixコマンドの一覧の本を買って全部のコマンドを覚えようとしてみたり、Perlの本(ラクダ本)を買って何度も繰り返し読んでなにもかもを覚えてようとしてみたりしていた。実際本の中のちょっとした言い回しすら覚えるレベルで覚えてしまった。

そういうふうにやたらとコンピュータには詳しくなったが、プログラマとしてのレベルでいうと、いまよりずっと低かった。

一気にプログラマとしてのレベルが上がったのは、言語処理系のソースコードを全部読んでみたときだと思う。

2000年代前半のあるとき、日本語が自然に扱えるスクリプト言語を探していて、なんとなくGauche Schemeにたどり着いた。PerlやRubyに比べてマルチバイト文字の処理がGaucheはずっと自然に思えたので、試しにと思って使い始めたのだった。それで結構はまって、ユーザでいるのには飽きたらずに処理系を理解しようとソースコードを読み始めた。

言語処理系のソースコードを通して読むのは予想外に勉強になった。よくできたスクリプト言語にはリッチな標準ライブラリがついてくるわけだけど(リストとかハッシュテーブルとかトポロジカルソートとか)、そういうライブラリはある意味メジャーなアルゴリズムのカタログ+実装みたいなものなわけだから、それを通しで読んで100%理解することで、コンピュータサイエンスをわりと広くカバーしたことになるのだった。

本当のプログラムは実際にどういうふうに書くのか、ということを学ぶこともできた。本を読んでいるだけでは大きなプログラムを迷いなしに書くのは難しいのだけど、お手本とすべきものを理解すると、少なくとも主観的には迷いが少なくコードをずっとサクサク書けるようになった。

Gaucheというのも偶然だが学ぶ対象としては大変よかった。その後いろいろなオープンソースプロジェクトのソースコードを読むことになったが、Gaucheほどに細部に至るまでキレイに書けているものはほとんどなかったように思う。これはひとえに川合史郎さんのスキルの高さによるものだと思うけど、その意味でいきなりよいお手本に当たれたのは運が良かった。

いまだったらGoのコードを読んで勉強するのもよいと思う。GoはRob Pike先生ほかレベルの高い人たちが書いた大変よいコードからできていてお手本にしたいクオリティだからだ。

その後は特に僕のプログラミング力は劇的には向上していない気がする。収穫逓減の法則というものがあるから当たり前なのだが 、当時から10年かけていろんなところで地道に良くはなっていると思うけど、当時ほどの上昇曲線は描けていない。

詳細を省けば僕のプログラマとしてのステップはこれで現在に至る。

僕はプログラミングをしたいと思ったきっかけなどは特にない。それがどういう仕組みなのかよくわからないけど、僕のようなある種の人間にとって、プログラミングというものは損得抜きにやらずにはいられないものであるように思う。生まれつきのやる気(あるいはやらずにはいられない気持ち)があるとしか思えない。こういうのはわからない人にはわからないと思う。

まじめにソフトウェアエンジニアリングを志す人には、言語処理系のソースコードを上から下まで全部覚えるのは大変知識が増えて面白いし、実用面でも大変役に立つので、おすすめしたい。

Rui Ueyama @rui314