プログラマの実力は経験だけであがらないことがレベル格差につながる

プログラマというのは、道具に慣れることが、実力があがることにならないのですよね。だから、勉強せず業務経験だけだとレベルが低いままということになってしまう。

Javaを10年さわり続けて、Strutsを5年さわり続けても、それだけでは、与えられた画面を手際よく作成できるようになるだけで、たとえばStrutsすらよりよく使えるようになるわけではなかったりする。
Javaにしても、「volatileってなんですか?」という問いに、まあ知らないのはしかたないとしても、解説を見ながらですら答えられない可能性がある。

プログラムの反復生産は、プログラミング能力の向上にあまりつながらない。設定や記述に慣れるだけだ。そして、この「慣れ」というのには「難しいからそもそも実装を回避する」というようなものも含まれる。実力の向上は、作業ができるレベルで止まってしまう。

プログラマとしての実力をあげるための勉強が自発的・組織的に行われないひとつの要因として、そういった勉強は、まったく業務に関係なくみえることがあるんじゃないかと思う。自然、プログラムの勉強としても、ツールやライブラリの使い方ばかりの勉強になりがちになる。
ぼくのエントリで「アルゴリズムの勉強をしましょう」というのは数年前からたびたび書いてるのだけど、SIの衰退が目に見えるようになる前は「そういうのは業務アプリでは必要ない」というコメントが毎回ついていた。というか、何か書くたびに「業務アプリでは〜」「大規模開発では〜」というコメントがついてた気がする。だいたい「プロジェクト管理のほうが大事」という感じだった。

勉強で人気があるのは、コードの内容についてではなくて、コードの生産のしかたのほうで、オブジェクト指向設計→プロセス改善→XP→アジャイル→テスト→継続的インテグレーション(イマココ)のようなものが流行り続けてる。
ただ、これらの勉強は、ともするとルールとツールと名言集のようになってしまって、頭でっかちを産むだけの逆効果にもなりうる。こういった「どのように作るか」だけの勉強では、やはりプログラマのレベルはあがりにくいと言える。
最終的には「純粋なオブジェクト指向とは」「これはアジャイルといえるか」「TDDではなくBDD、いやxDD」のような言葉遊びになって流行が収束する。

レベルの高いプログラマというのは、よりよくコンピュータリソースを扱えるプログラマだと言えるので、「どのように作るか」ではなくて「どのようにコンピュータを動かすか」という分野の勉強をする必要がある。対して「どのように作るか」というのは、「どのようにプログラマを動かすか」という勉強だといえるので、そのことによってはプログラマのレベルはあがりにくい。

もちろん、明示的に勉強してなくてもできる人はいるし、残念ながら勉強してもできない人*1はいる。ただ、そういう特例をあげてもしかたなくて、プログラマ人口の多くを占める「勉強すればできるようになる人」が勉強してできるようになることが大事なんじゃなかろうか。

ここまで書いて「大事なんじゃなかろうか」で締めくくろうと思ったのだけど、やはり、では何をどのように勉強するか、という考えもまとめておく。
ここで、基本的な考え方として、次の3つの柱をあげておきたい。
1. どのようにコンピュータに命令を与えるか
2. どのようにコンピュータへの命令を記述するか
3. どのようにコンピュータは命令を受け取るか

1.の「どのようにコンピュータに命令を与えるか」というのは、計算理論やアルゴリズムの分野になる。
いままでアルゴリズムの本はさんざん挙げてきたので、ここでは計算理論の本をあげておく。

計算理論の基礎 [原著第2版] 2.計算可能性の理論
計算理論の基礎 [原著第2版] 3.複雑さの理論

計算理論は、ようするに計算量とか複雑さとかの話で、アルゴリズムの話に輪をかけて実務に役立つように思えない。オートマトンの話はともかく、クラスPとかの話が今後書いていくプログラムに結びつくとすら思えない。そういう意味で非常に勉強しづらいのだけど、アルゴリズムなどの話では、ここに出てくることは知っているとして解説されているし、いろいろな本を読んでいくと必要性や重要性がわかってくる。だからこそ基礎だと言える。
3分冊だけど、トータル500ページで、実のところ文章量は少ない。あと計算理論の本の中では、文章が読みやすいと思う。3巻が一番大事なので、読むとしたら全部よみましょうw。
あとは、数学ガール 乱択アルゴリズム とか プログラミングコンテストチャレンジブックだとかで、実用に近づけていくといいと思う。

2. 「どのようにコンピュータへの命令を記述するか」というのは、ここではインデントをそろえましょうとか人間に見やすくする話ではなくて、数学的理論と命令をどのように対応付けていくかという話。簡単にいうと、プログラム言語の話。
この本が、論理学から計算可能性、ラムダ計算という話をつなげていて読みやすい。

そうしてプログラミング言語の基礎概念を読むと具体的なプログラム言語につながっていく。

3. 「どのようにコンピュータは命令を受け取るか」は、コンピュータの物理的な構成の話で、まあパタヘネ本を読みましょうという話になる。

コンピュータの構成と設計 第4版 下 (Computer Organization and Design: The Hardware/Software Interface, Fourth Edition)

といいつつ、パタヘネ本4版はまだ見てなかったり。付属CDのPDFが充実していて本編よりオススメと教えてもらった。
ただまあ、ちょっと内容的にはともかく物理的にちと重いので、プロセッサを支える技術が手ごろだと思う。

あと、コンピュータがどのように命令を受け取るかという話ではネットワークも欠かせないので、ネットワークはなぜつながるのかあたりは目を通しておいたほうがいいと思う。

*1:そういう人はこのエントリにたどりつかない