東京Node学園#20でtry-catch使うなという話をしてきました

東京Node学園#20「Don't use try-catchというタイトルで話してきました。

option-tの話

最初は手前味噌なoption-tの話を主題にするつもりではあったんですが、そんなライブラリの話とかしたって特にトリッキーな実装をしているわけでなし、全然面白くないし、別に特定のライブラリを使わなくても実現できる内容なので、もう少し広めの話題ということでtry-catchを安易に使うのをやめようという話にしました。

宣伝がてらoption-tの話も入れていますが、option-tのREADME.mdにも書いている通り、これのみが正解というわけでもないし、TypeScriptなどの静的型付けな支援が無いと使いにくいこともままあるし、依存関係を増やす元になるので、無理して使う必要も無いでしょう。インスタンスメソッドを組み合わせて使うとか、そういったことに魅力感じる場合に、選択肢の一つとして選んでいただければ幸いです。

質疑応答

当日は質疑応答の時間が取れなかったので、懇親会で聞かれた内容について。

Promiseの型定義次第で解決されるのでは無いのか?

これについては、Twitterでも回答させていただいておりますが、私個人の認識としてはノーだと思います。

もちろん一定の緩和にはなりますが、Promiseコンストラクタに渡すexecutor内でのthrowに対してもPromise.prototype.catch(e)は動作してしまうので、type paramterを増やしても制約として機能しませんし、むしろ特殊化したE以外の値が実行時に飛んできた場合に各種制約の前提が崩れるので、全体としてはむしろ状況が悪化してしまいます。なので、ES6 Promiseのdesign上, catch()any型がわたってくるというTypeScriptの定義は正しく、これに基づいて対応策を考えるしかないのではないかと。

もちろん、ES6 Promiseとは異なるdesignになっているPromiseを使う場合は、この限りでは無いですが、そこまでしてcatch()でハンドリングしたいかというと、微妙かなーと。

なんかLintとかでbanできないの?

↑で。

ESLintの/*eslint-disable*/~/*eslint-enable*/の良いところは、限定解除の明示化すなわちRustlangのunsafeブロックなので、使いたい場合をopt-in化できるのは、まあアリなのでは無いかと思います。

バグは積極的にクラッシュさせて洗い出すほうがいいというけど、そうは言っても何でもかんでもバグはクラッシュって厳しくない?

厳しいケースもあると思います。

ただ、そういう要求がなされる場合(たとえソフトウェアのバグがあっても回復を試みなければならないシステムとか)、

  • 本当にエクストリームなアプリケーションは、そのような問題の解決についての研究などを元にしたdesignで構築されるべき
  • そうでないアプリケーションに関しては、だいたい殺したほうがいいが、それでも「もしかしたら死ぬかもしれない処理は別立てのプロセスで処理する」などのように、影響範囲を分割するなどして対処するべき
    • この手の非同期イベント駆動にしたほうがいい箇所こそNode.jsの強みでは。

ではないかと思います。 (そんなに詳しく無い分野なので、具体的にどの研究が良いなどの突っ込んだ話はできません……)

あと、そもそも何かしらのアプリケーションはリリース前にQAとかデバッグやるんだから、その期間に可能な限りバグを発見できるようにしたほうが良いというスタンスです。

これを守るとオブジェクトの生成とかで遅いケースってあるよね

あると思います。 ですが、全体・通常としては表現の明瞭さを重視するスタイルを取るべきで、ハイパフォーマンスを要求されるモジュール・アプリケーション・プロジェクトに関しては、それを重視した規約にする、というのが現実的ではないかと思います。

どうせ遅かったら究極的にはCとかアセンブラ書くしかないんだよ!

Joe Duffy - The Error Modelは読んで面白い?

読みたいと思ってるなら読んで損は無いと思う。 別に無理して読むほどじゃ無いけど、新卒の子とかには前半部分だけでも読ませたい

まとめ

大体こんな感じ