科学者が書いた質の低いコードが、ベストプラクティスに則ったコードに勝る理由

今ちょうど、科学者の手によるコードは質が低いという投稿を読み終えたところです。科学者の書いたコードは”ソフトウェア・エンジニア”が関与したコードと比べて質が劣るという内容でした。

私は10年以上同じ職場に勤めていますが、同僚の多くは数学や物理学が専門で、”ソフトウェア・エンジニアリング”の知識はほとんど持っていません。

そこでは、大惨事は必ずと言っていいほど、自分のことをいっぱしのプログラマだと思っている少数派によって引き起こされます。かくいう私も、少なくとも数件、いまだ解決を見ていない大きな不具合の原因を作ったことがあります。他にも大きめのバグをいくつか出しましたが、幸いその時のコードはお蔵入りしたため、私に無駄な給料を払わされた雇い主が被害をうけたくらいで、同僚の生産性を大きく損なうことはありませんでした。

その度(少なくともほとんどの場合)私は反省し、それまでにも増して退屈なくらいシンプルなコードを書くようになっていきました。そのおかげか、大勢の人たちの冷たい視線を浴びながら、自分の見当違いの浅知恵が生み出した産物に半日以上も向き合って過ごすといった事態は、ここ5、6年ないように思います。

もちろん、きちんと反省しないプログラマも少数ですがいます。同じように周りからは白い目で見られますが、彼らは自分たちが正しく、他の人たちがおかしいのだと思っているのです。

一方で、数学者や物理学者、アルゴリズム設計者、科学者といった”プログラマではない人々”が犯しがちな失敗があります。例をあげてみましょう。

  • 関数が長すぎる。

  • ネーミングが分かりづらい(m、k、longWindedNameThatYouCantReallyReadBTWProgrammersDoThatALotTooなど。ちなみに長すぎるネーミングに関してはプログラマもやりがち)。

  • 無制限なアクセス(global、singleton、いわゆる「神オブジェクト」の多用)。

  • クラッシュ(nullポインタ、境界外エラーなど)。多くはValgrindの使用やテストの徹底で軽減できる。

  • 並列処理に関するバグをまったく考慮しない(ツールの使用によりほぼ100パーセント回避可能)。

  • オーバーロードされた演算子やテンプレートなど、知識のあるプログラマが書いたライブラリをやみくもに使いたがる。

お気づきだと思いますが、こうしたミスならすぐに修正できます。デバッグを手伝ってほしいと頼まれて、彼らが何をしたいのかを理解できずに困ったという経験はほとんどありません。といってもこれはソフトウェア開発レベルの話です。アルゴリズムとなると完全には理解できないこともあります。しかし例えば、どの変数をどの関数に引き渡したいのかという類のことは、たいてい判断がつきます。

ところがソフトウェア・エンジニアの犯すミスは、全然異なるタイプのものなので、そう簡単にいきません。

  • 多重継承や仮想継承など、行き過ぎたクラス継承。

  • 基本的に薄いラッパーから成る7から14個のスタック・フレームのうち、いくつかは関数ポインタもしくは仮想関数、もしかすると内部割り込みハンドラか何かであるかもしれない。

  • 無数のディレクトリにファイルを展開する。

  • 動的プログラム構造を使ってname dictionaryのむちゃな検索を実行する。dictionary内で、ばらばらの要素を実行時に連結して名前を生成したりする。

  • 動的ローディングをはじめとする、grep泣かせのテクニック。

  • まぎらわしいネーミングの多用。ドライバ・コントローラ、コントローラ・マネージャ、ドライバ・マネージャ、マネージャ・コントローラ、コントロール・ドライバと、きりがない。すべて同じものを指している。

  • 多重定義されたオーバーロード関数を呼び出すテンプレートは、定義された場所を可視化してほしいが、そうなっていない。

  • デコレータやメタクラス、コードの生成など。

こうしたミスが重なった結果、どの処理がどの関数を何のために呼び出しているのか分からなくなります。それなりに使えたデバッガは、IDEやgrepの機能がしだいに発揮できなくなり、やがてまったく使えなくなります。ここまで来るともう泣きたくなって、バグの原因究明はあきらめざるを得なくなります。

もちろんこれは、意地悪く誇張した話であって、誰もがいつもこんな失敗をするわけではありません。私は”科学者”というより、基本的には”プログラマ”なので、やはり、純粋に高い生産性をあげるべきだと心から信じていますが、ふと疑問に思うことがあります。

科学者のコードは、より優れた”ソフトウェア・エンジニアリング”から、何か有益なものを得られるのでしょうか。おそらく、得られるでしょう。しかしその恩恵は、”ソフトウェア・エンジニア”によって与えられるものではないと、私は思うのです。

地獄行きのハイウェイを善意から舗装するような業務遂行の鬼となるくらいなら、無邪気で、のんきで、ちょっと役立たずくらいなほうがましです。コンピュータの外側の”現実の世界”には、そんな例はたくさんあります。

ここで一つ、あまりに真理を突いているので省略するにしのびない、ささやかな見解をお伝えしましょう。それは、怠惰は大きなトラブルの原因であるということです。科学者は、科学で頭がいっぱいなので、いたずらにコードを複雑にするひまがありません。一方、多くのプログラマは、仕事に対して本質的な意義など感じていません。たかが仕事です。だから彼らは時間を持て余しています。その時間を使って”APIデザイン”をあれこれと考え、その揚げ句に、奇怪な産物を生み出すのです。

(実際、プログラマの仕事が技術的・社会的に意義のあるものになれば、組んだコードは動くのか、使い勝手は良いか、コストパフォーマンスはどうかといった、目先のタスクにばかり焦点を絞った、うんざりする訓練は変わるでしょう。でも、かわりにプログラマがすることといえば、自分の手であり得ないほど複雑に加工してしまった、神聖なるAPIに対してだけは責任を持つと声高に主張することです。その割には、ほとんどうまく機能しませんが)