コードの汎用性と規模の相転移点

On the quality of academic software | Daniel Lemire's blog

同僚がSlackに貼り付けたこの記事に同意しすぎて気絶している。

この記事の主張は、略しすぎるくらい略すと、「プログラミングをあまりせず、プログラミング技術の高い人を評価する仕組みもない業界では、業界内のプログラミング技術はいつまで経っても向上しない」「簡単なスクリプトを書いて自分のために消費することと、多機能なソフトウェアを書いて他人に使ってもらうことの間には想像を絶する隔絶がある」というようなところだろう。記事のトピックはアカデミア生まれのソフトウェアだ。研究者の仕事は研究であってプログラミングではないので、皆プログラミングに時間を費やさず、よって誰も技術が向上せず、ソフトウェアを評価できる仕組みも生まれず、ずっと酷い(awful)コードを生み出し続けているし、改善の兆しもない、との主張だ。

私の狭い観測範囲でも同じ現象が起きている。件の記事では情報科学を焦点に置いているようだが、私の焦点は計算科学にあるのでより顕著だ。アカデミア発の有名ソフトウェアのコードをたくさん読んできて、感心したことは数えるほどしかない。むしろ平気で(多分知らずに)未定義動作を踏みぬき、バッドプラクティスを実践していくそれらのコードにめまいを覚えたことの方が多い。ただ、個人的には最近出てきたコードはまだ安心できるものが比較的多い(ユニットテストをしている、それなりに新しい安全で高速でわかりやすい新機能が使われているなど)という感覚があるので、私はこの記事ほどには悲観的ではないが。それに、彼らの本業がプログラマではないことは確かだし、教員にニンジャ級やロックスター級のプログラマがいなかったり、ただでさえ競争が激しく運要素が強い研究業界であまり評価されないプログラミング技術を磨く余裕があるのかなど、構造上仕方のない部分はあるとも思っている。結局完全に解決するには、一人で全部やろうとせずに、サイエンティフィックソフトウェアエンジニアなどを雇って分業するのが一番だと思うのだが。


話は変わるが、アカデミアの話は置いておいて、かのブログ記事の「簡単な自分用のスクリプトを書くのに比べて、複雑で汎用のソフトウェアを書くのは桁違いに難しい」という主張を見て思い出したことがある。私も以前、自分用の木の椅子を不格好でいいからノコギリとトンカチでチョイチョイと作ることと、高層ビルをおっ立てるのが質的に違うように、ちょっとしたスクリプトと汎用のライブラリの間には質的な違いがある、と主張したことがあった。今も同じように考えている。一応、誤解を防ぐために、整った形の椅子を光の速さで作れることもまた極めて高い技術の証左であり、ビルの建築とは方向が違うだけだと言い添えておきたい。片方ができることはもう片方ができることを包含しないし、むしろその「包含しない」ということが一番重要な部分だ。自分用の椅子を作るときに基礎を地中深く打ち込むのは不便なだけだし、高層ビルを作るときにログハウスを積み上げると崩壊する。

何が言いたかったのかというと、プログラミングの難しい点の一つは、ちょっと手元でファイルを読んでちょっと面倒な変換をかけてから統計解析をしてプロットするみたいなスクリプトを書くことと、巨大で沢山の機能を備えた汎用のライブラリやアプリケーションを作ることの間に質的な差がある、ということだ。前者はまあ100行から長くて1000行で済み、後者は一万から数十・数百万行にも至るが、前者を100回書いても後者を書くやりかたがあまりわかってこない。多機能で汎用のソフトウェアを作る方法を身につけるには、多機能で汎用のソフトウェア(のようなもの)を自分で何度も書いてみたり、質のいいプロジェクトに参加して技術や態度(人間関係ではなく、何を考えて書くか)を学ぶしかない。難しいのは参加するべき質のいいプロジェクトを見つけることだが、それが難しいなら小規模なライブラリを書いてみて自分のスクリプトで使ってみるのも良いかも知れない。

一番不幸なのは、一方の技術しか磨いてこなかった人が、他の全ても完全に理解したと思い込むことだろう。プログラミング技術は思っているより細分化していて、なんとなく「これくらいできるだろ」と思ってやってみようとすると思った以上にめちゃめちゃになることは多い。だが、学習と実践をやめてしまうと、万能感に浸った面倒な人になってしまう。人間が自分の習熟していない分野を軽く見てしまう特性は、人材の分野間の移動に貢献してきたこともあるのかもしれないが、常に意識して自省していかなければならないだろう。自分が何かをできないことを認めるのは難しいことだが、意識してやっていかなければならない。自分の成長を止めないため、後進から厄介者扱いされないために。