Clojureだと生産性が上がるわけ

私は新たな言語を学ぶのが好きなのですが、しばらく使うとどうしてもその言語の魅力は色あせてきてしまいます。そして結局は、ツールボックスの中のありふれた言語の1つになってしまうのです。

しかしClojureは例外でした。私は今でも、最初に学んだ時と変わらずこの言語を使うのが好きです。その理由は、この言語の持つ能力とシンプルさの絶妙なバランスにあります。

能力のバランス

一部の言語はシンプルであっても同時に冗長だったりします。冗長さは大した問題ではないと言う人も、中にはいます。そういう人たちは、全ての言語がチューリング完全であるとか、特定の言語では少し多くコードを書く必要があるだけだとか力説するでしょう。

でもそれは的外れだと思います。原理上何かを表現できるかということが大事なのではありません。解こうとしている問題にどれだけうまく言語を対応づけられるかということです。あなたの問題領域の観点から考えさせてくれる言語もありますが、一方でその問題を言語の構成概念に翻訳しなければならない言語もあります。

後者はつまらない場合が多くて、楽しいと思うことはめったにありません。たくさんの決まりきったコードを書き、絶えず同じことを繰り返す羽目になります。反復的なコードを書かなければならない状況にはある程度の皮肉さがあるということに皆さんも同意してくれるといいのですが。

また別の言語は、冗長さがなく問題解決のための様々なツールを提供しています。でも残念ながら、そういった言語でプログラミングをするのは、大型工具店でどのドライバーのセットを買うか決めようとするのに近いものがあります。

こっちのブランドとあっちのブランドを比べたり、セットに付いている先端パーツの数をチェックしたり、どれがお買い得かを見たりしているうちに、そもそもなぜドライバーが欲しいと思っていたのかを忘れてしまうのです。

特徴が多ければ多いほど、その言語を効果的に使うために覚えておかなければならないことが増えます。多くの言語の場合、様々な特徴を全て思い出し、それが互いにどう影響し合っているのかを考えることで自分自身に余計な精神的負荷がかかっているなと思うことがよくあります。

私にとって言語で大事なのは、そういったことを考えずに使えることです。表現力に欠ける言語を使っていると、私は自分が無駄にコードを書いていると感じます。一方で、言語に非常に多くの特徴がある場合、圧倒されてしまったり言語で遊んでしまって気がそれてしまったりすることがよくあります。

数学に例えると、個々の問題に応じて膨大な数の公式を暗記するよりも、他の問題にも応用できる汎用性のある公式が1つある方が便利です。

Clojureもこれに当てはまります。Clojureであれば、コンパクトで汎用性のあるパターン一式から、特定の問題に対する解決策をいつでも容易に導き出すことができます。覚えておく注意事項も大した数ではありません。

生産性を上げるには、シンプルなコンセプトと構文をいくつか学べばいいのです。しかし、あらゆる問題を解決する上で、コンセプトの結び付き方の数というのは無限にあるように思えます。私は何年もClojureを書いていますが、既にある知識の新しい組み合わせ方を毎日発見しています。

マクロがこのいい例です。言語そのものを使って言語を変換できることによって、様々な固有のツールや言語の特徴が必要とされるような幅広い領域の問題に取り組むことができるのです。

インタラクティブな開発

Clojureで問題に取り組んでいる時、私は要点をきれいにはっきりと表現する、洗練された解答をどうしても書きたくなります。その主な理由は開発プロセスがインタラクティブであるという事実にあります。

REPLを使っていると、実験的にいろいろといじって解答を探すことで意味が分かるようになります。いったん問題を内在化すると、新しく得た理解を使ってすぐに解答を書くことができます。

またREPLは、常に解決策を見つけようとする助けにもなります。何かを試して、そのフィードバックをすぐに受け取れるのは楽しいものです。コードが思ったとおりに動かない場合でも、進み具合を見ることができるので十分にモチベーションを維持できるのです。

REPLのもう1つの重要な特徴は、リファクタリングを推奨している点です。私は仕事の流れを止めずに簡単にテストできる時は、コードのリファクタリングをよく行います。

仕上げる

ですがインタラクティブであるだけでは十分ではありません。妥当な時間内に問題を解決することができなければ、どんなフィードバックも意味がありません。

私はプロジェクトにしばらく関与していると、ある時点で生産性ががっくりと落ち込みます。あなたにもこのような経験がありませんか? プロジェクトの開始当初はワクワクして、計画が少しずつ形になっていくのを見るのが楽しいものです。

しかしある程度の時間をプロジェクトに費やしてしまうと、当初の興奮が冷めてきます。そのうちコードに再び手を付けるのが怖くなることさえあるかもしれません。この状況に陥る前に、主要な機能を構築してしまうことが重要だと私は考えます。

私はプロジェクトの特定の問題が解決すると、実際に使ってみます。この時点でそれまでつぎ込んだ労力が報われます。また、使用することによって、欠けている機能に気付くこともできます。実際に使用しているプロジェクトであれば、機能を追加しようというモチベーションは高まります。

ごく最近、Selmerでの作業をしている時にこれがそのケースだと気付きました。私はほんの数日で基本パーサを実装でき、その間、協力者のcesarbpがフィルタ用のロジックを実装しました。

テンプレートの継承ロジックを構築するのにさらに数日かかりました。そして思いがけず、1週間足らずの取り組みで便利なライブラリが出来上がったのです。私は実作業のためにこれを積極的に利用していて、必要が生じるたびに新しい機能が少しずつ追加されます。

SelmerのGitHub活動グラフは次のとおりです。

ご覧のように、最初に大きく急上昇し、その後急激に落ち込んでいます。clj-pdf
Luminusなど、他のプロジェクトでも同様のパターンが見られます。


プロジェクトが進展するにつれて当然ながらバグが検出されたり、新しい機能が追加されたりしますが、グラフのところどころにある山は、それに対応しています。ただし、プロジェクトの最初の段階をタイミングよく完了できないと何も起こりません。

私の経験では、作業を始めて数日以内に何か面白いものを構築できないと、プロジェクトを実質的に完成させる可能性が急激にゼロに近付きます。

Clojureを使えば、物事を迅速に終わらせることができます。当初の興奮がなくなる前に何かを構築するのに十分な速さです。Clojureがまだ新しい言語であるのにもかかわらず、素晴らしいライブラリが数多く存在するのは、ひょっとしてこれが理由なのではないかと私は思っています。