さよなら CoffeeScript

prototype.jsjQuery に置き換えられた時、開発者が気づいたのは、自分に本当に必要だったのはprototypeのメソッド拡張などではなく、クエリエンジンだったということ。

coffeescriptが当初、熱狂的に支持された背景はなんだっただろう。今思えば、それはアロー記法とクラス構文だったと思う。

javascriptの関数型への憧れ、prototypeベースの限界

javascript は断じて関数型言語ではないが、他の言語と同じぐらい関数型言語に憧れていたのも、また事実だろう。しかしビルトイン関数が高階関数を要求するデザインにしては function というキーワードはながすぎたし、その function が暗黙に作り出す this スコープの複雑な振る舞いも開発者の悩みの種だった。「あらゆる関数スコープで状態を持つことが"できすぎる"」という割れ窓だった。

ES5 で Array.prototype.map / Array.prototype.reduce が採用され、より関数型っぽく(正確に言えばRubyっぽく、なのだが)書けることになったが、それに対してESの文法はまだ冗長だった。

2011年ほどから2つの理由で JavaScript への要求が増大した。一つはHTML5と呼ばれる仕様群でブラウザのポテンシャルを上げていこうと言う動きに伴って、JSの記述量が増えつつあったこと。もう一つは Node.js でサーバーサイドスクリプティングを行なうためだ。さらに突き詰めるとGoogleChromeFirefox、V8エンジンの存在がある。

コード量の肥大化はクライアントサイドMVCという発想を産み、prototypeベースの限界、というか需要の無さをJavaScriptに突きつけた。現実的に、現代の開発者が獲得しているGUI実装パターンは、クラスやコンポーネントベースだった。そう、やっとWebはGUIになった。

JSの肥大化とCoffeeScriptの登場

そのような背景でCoffeeScriptが登場したと記憶している。クラスとアロー記法とインデントブロック。== の排除などの JavaScript バッドパーツを踏ませない設計。Backboneに始まるJavaScriptMVCとともに、大規模開発での採用が増えていた。Rubyを髣髴とさせる設計は、元々Rubyユーザーが多かったNode.jsとも相性がよく、またRubyらしさが買われてRails標準になったりした。

CoffeeScriptの一番の成果は、現実の仕様が追いつかない部分はプリコンパイラで先取りしてもいいんだ、という雰囲気を作ったことだと思う。typescriptも6to5(現babel)もそういう雰囲気の中で生まれたものだと記憶している。

CoffeeScript の衰退

CoffeeScript が用いたクラス構文や継承ポリフィルはほぼそのままES6の仕様として採用された(正確にはstatic継承はオミットされた)。() => のアロー関数もだ。これによって将来的にはピュアな javascript でも将来的にはクラス構文やアロー関数が使えることが約束されている。

これは coffeescript にとっては 勝利であると言えるかもしれない。coffeeで書いたコードが将来的にもjsでそのまま継承できるようになるからだ。

僕はこのまま coffeescript は先進的な仕様を実装しESのオピニオンリーダーの一人になると思っていたのだけど、現実は違った。ユーザー数が多くなった CoffeeScript は保守的になり、ES5の互換性志向が強くなった。いや、具体的にそう明言されたわけではないのだが、リポジトリを眺める限り、僕はそのように感じた。また開発者のjashkenasも理由がわからないが、ある時点からやる気を失ってるように見えた。Issueは消化されなくなり、PRのマージ速度も目に見えて鈍化した。もともとコードが綺麗ではなかったのも理由の1つだとは思う。

言語からイノベーションが失われた。これが僕がCoffeeScriptを見限る理由となった。

「その場に居続けるには全力で走り続けなければならない」

最近 typescriptやbabel でasync/await を試していたのだけど、これは今のJavaScriptを大きく変化させるだろうなあ、という実感がある。ただ、coffeescript でそれが使えるようになるのはいつになるだろう、と考えてげんなりした。CoffeeScript に付き合っていると変化に追いつけないだろうという予感がある。とくにES7は。

Typed CoffeeScript の副目的

そういうものを作っていた時期もあるのだけど、その目的はTypeScriptの猛追で雲行きが怪しくなり始めたCoffeeScriptを殺さないため、外部から何かしらのイノベーションを起こしたかった、というのがあった。結果は、一人でやるにはまったく時間が足りず、とある設計変更を見積もった結果、まったく時間を捻出することが不可能で、放置されることになった。僕の型システムに対する勉強不足、実力不足もあるが、この手のことをやるにはパトロンがいるという認識に至った。次に何かこの手のものを作る必要があれば、フルタイムの時間を捻出するために、そうしようと思っている。

(今回の記事とは関係ないけど、宮下さんのリクルートテクノロジーズ Advanced Technology Lab の技術顧問就任とか、OSS支援でそういう選択肢を提供してくれるかもしれない会社が増えるのはいいことなんだろうな、と思っている http://mizzy.org/blog/2015/10/01/1/ )

なぜこの記事を書いたか

僕は coffeescript を推進していたし、それで技評で本も書いたし、国内に限ればGithubCoffeeScriptプロジェクトのスター獲得数も一位だし、本家にコミットはしてなかったものの、勝手に責任を感じている。だからこういう表明も必要だと感じた。自意識過剰かもしれないが。

好きな言語・技術が腐っていくのを見るのは、これが最後ではないだろう。でもいつだって心構えが必要なんだと思う。全ての技術は生まれながらに腐っていくといってもいい。なるべくそうならないものを選ぶのも技術者としてのスキルの1つだろう。

書き捨てのスクリプトやgulpfileはまだ多分もcoffeeで書くだろうが、今後新しく書くものはbabel か typescript を必要に応じて選んでいくことになると思う。