六月の開発局

「業界の人」じゃないよ

一番大切なのは人生をプログラミングに注ぎ込まないこと

なにこれ~同じ世代の気分が暗くなる例のアレ

突発的に技術ブログ書きたくなって書くんだけど、なんか「技術ポエムAdvent Calender」みたいなのに投稿すればよかった。

「この業界は日進月歩なんだ。生き残りたければ、寝食忘れて勉強しろコード書け」みたいな話はよく聞く。で、これを鵜呑みにして「俺はもうダメなんだこの業界じゃやってけない」って真っ暗になった同世代を何人も見てきた。とにかく「勉強しなくちゃ」「勉強会に出なくちゃ」「技術ブログ書かなきゃ」みたいな。「あんなヤツらの言うことなんか無視しろ、全部無視しろ」って言ったこともあるんだけど、もうちょっとそれっぽいことを書きたい。

Lisperはどうすべきか

以前、JSのW氏とタクシーの中で話したとき、「PHPだとこの先やってけなくない?」みたいな話をされた。まあ、それは別にどうでもいいんだけど(本当にどうでもいいと思っている)、Shibuya.lispでオフレコだから話すとして、「Lisperはどうすべきか」って話をしたことがあって、そのことをざっくり話した。よりざっくり話すと「Lispを広めてみんなに使ってもらおうなんて考えるのはやめよう。そんなことやるだけ無駄だ。そんなことをやるより、Lispを使って必要なアプリを書けばいい。その方がずっと大事だ」ってことを話した。一応断っておくと、僕は自分の言ったことだし、今でもこう言い続けてるけど、それがすべてだとは思ってない。宣伝という行為がある程度必要なのは僕だって知っている。で、それでも言っているのには理由があるのだけど、残念ながらこれも今の本題じゃないので端折る。

僕が言いたいのは「弱いやつは必要なアプリを書け」ということだ。それはマイノリティであるLisperでも変わらないし、電算技師としての能力に自信がない人でも同じだ。僕はどちらにも所属しているので(最近あまりこういうことを言うべきでないということに気づいたけど言っちゃうね)、やはりアプリを書き続けようと思う。

教科書などの問題点、とはいいたくないのだけれど……

プログラミングを勉強しようというとき、たいていの人はとりあえず本を買ったり、チュートリアルを検索したり、あるいはどこかのクラスに入ってコースを受講すると思う。まあ、まっとうなやり方だ。ところが、これにはもう古典的に言われてる一つの問題がある。すごい嫌な言い方をすると「会社と学校は違うんだよ」「実際の現場では」だ。こういう紋切り型の言い方は大嫌いなんだけど、でもこれはある意味真理だ。

なぜ、真理かというと、優れたプログラマであればあるほど、流れや方、美しさに気を使うようになる。それは、他人に教えるときもそうだ。だから、「ここをこう教えて、次にこう教えて、こう成功を掴ませてやればいい」というように大変美しい教科書を作る。当然エラーハンドリングも教えるのだけど、そのエラーも流れに沿って教えられる。そしてその流れの中には「前に一度教えたことはちゃんと覚えているはず」とか「こういう固有のトラブルについて割り込みで教えると混乱するから、こうやって原則を伝えていこう」といった、大変思慮の深い配慮がなされている。

全然悪くない。だから問題だ。だっていきなり複雑なことを教えたら混乱するし、原則に沿ってりゃ間違いないからだ。ところが、実際にコードを書き始めれば複雑に解決しなきゃならない問題が山程でてくる。Hello Worldのビルドすら通らない。どないせっちゅーねん。

原則を無視するとき

優れたプログラマは結構原則を無視する。例えば、エラーメッセージを勝手に解釈するプログラマは多い。「んな馬鹿な」と思うかもしれないが「プログラムが不正な処理を行ったため強制終了しました」と出た時に、パーミッションを洗うプログラマは稀だ。ほとんど「あ、開放したメモリにアクセスしてしもた」と疑うだろう。厳密にはメモリ保護違反だから、正しいのだけれどね。もっとひどいのになると、Aborted.だけしか出てなくても、「メモリ保護違反や」とかかる。

そして、最初からブレークポイントを仕掛けてじっくり腰を据えて探そうとするプログラマも少ない。「多分このへんやろ」と野生の勘で場所を特定して、それでもつかめないなら、前後に適当にprintfを挟んで、最後の最後でデバッガを引っ張り出す。そして高級言語で書いているのに、アセンブラレベルでステップ実行して、最後の段階ではスタックを読み始めて「本物のバグ」を見つけ出す。

最適化でも、慣れてるプログラマと慣れてないプログラマではやり方が全く違う。慣れているプログラマは、最初から「ここらへんだろ」と決めてかかる。そして往々にしてそれは当たっている。なぜ当たるかというと、自分が書いている間に頭のなかでプログラムが走っていて「ここらへんは重いから、遅かったらここだなー」とか考えてるからだ。初心者がよくしらないことの一つに、strlenは重い、というのがある。当たり前だけど、ループの中に条件判定が入っているので文字列の長さを図る関数はかなり重い種類の関数だ。でも、だからといって「文字列の長さ求めてるからここは重いだろ」とかかると、罠にハマる。文字列リテラルの持ち方によっては、長さをキャッシュしていることもあるからだ。ところが「慣れてるプログラマ」はそれもわかっている。そのあたりの細かい事情が全部頭に入っていて「ここらへんだろ」と決めてかかって、そして当ててしまう。もう殆ど魔術の世界である。もっとわかりやすい話をすると、時間を計測するときに、計測点の置き方が違う。「おそらく山はこことこことここだろ」みたいに入れていくので、解決の速度が早い。

というわけで、教科書などが教えていることはたしかにそうだし、間違ってはもちろんいないのだけれど、教科書をトレースして答え合わせをする高校までの学習スタイルで行くと、かなり辛いことになると思う(やったことないのでわかんないけど)。

原則をどう実用に持っていくか

それから問題なのが、原則をどう実用の世界に持っていくか、という話だ。

算数の文章問題が苦手だった人はいるだろうか。まあかける数とかけられる数みたいな論争には参加したくないが、原則たる式と現実問題としての文章問題は明確に違うもので、同様に現実に解決すべき問題と教科書が教えてくれる原則も違う。

この問題を手っ取り早く理解するにはGoFが便利だ。GoFデザインパターン、Factoryパターンって、俺が今直面してる、会議室の予約をさばくシステムのどこで使えばいいんだ?結論から言ってしまえば、GoFデザインパターンはわかりやすいし、あれを理解すると謳っている教科書を突破するのは簡単だ。基本的なオブジェクト指向の知識があればすぐに突破できる。しかし、あれを実用するとなると、とてつもない経験値が必要になる。得体のしれない問題、定式化されていないあやふやな要求の中で「あ、これってもしかしたらあのパターンかも」と気づいて、無理なくハメこむには相当の経験値がいる。よくあるミスとして「きっとこれはあのパターンに違いない」 問題の方を変形してしまって、意味不明なコードができてしまうことがある。そうすると悲惨だ。みんなの底力をあげようと思って教育を施したのに、明後日の方向に使ったためにみんなが不幸になる。

なんでアプリを書くべきなのか

もうわかったと思うけど、こういう問題を解決するにはアプリ、つまり、自分や誰かが使うプログラムを書くしかない。とにかく書くんだ。動かないならどんな汚い手を使ってでも動かす。使えるけど汚いプログラムを書く奴は悪党だが、使えるプログラムを書けないやつは能無しだ。どんな言語で、どんな汚い実装でも構わない。アプリを書くんだ。汚いプログラムでも使えるプログラムには価値がある。使えないプログラムに価値はない。

やっていくと、経験値が溜まって、なんとかなる。それしかない。僕の知ってる限り。なんだ雑に終わらせる気だなと思ったかもしれないけど、すまないそのとおりなんだ。なんでいま偉そうにこんな文章を書けているかというと、やっぱり俺は書いてきたからだと思うし、周りを見ていても、使えるプログラムを書いてきたやつはとてつもなく強い。だからこういう結論に至った。

で、最後の問題とそれの解決策

が、ここに最後の問題がある。「アプリを書け、って言われても、何を書けばいいんだ?」。

そう、これが問題なのだ。なんのアプリを作ったらいいかわからない。素質もある、コードを書く能力もある。そして書くことは好きだ。なのに書くべきアプリが見つからない。

選択肢は2つある。1つめは誰かの軍門に下ることだ。2つは、プログラミング以外の趣味を大切にすることだ。そして、その問題をプログラムに解決させる。これが一番いい。だから、一番大切なのは人生をプログラミングに注ぎ込まないこと、というわけ。