なぜReactでもVueでもなくElmを使っているのか

# はじめに

Leverages（レバレジーズ）Advent Calendar 2019 22日目担当の坂田です。

お仕事では自社メディアである、フリーター、第二新卒向け就職エージェントサイトのシステムや人材情報の管理システムの新規開発、保守運用などをしています。

今回は自社メディアのエントリーフォームを開発するにあたりフロントエンドフレームワークであり、言語でもある`Elm`という技術を利用した経緯について書きます。

かなりの人がElmに関して知っていることが少なかったりElmという言葉を聞いたことがないかと思われますが、参考程度に聞いてやってみたいと思う人が増えればと思います。

この記事ではElmの技術的なお話や、具体的なお話は一切しません。

# 結論

`Elm`はアンチパターンを実装できない。人の目を介さず、人的リソースを使わずにソフトウェア品質の最低ラインを強力な形で担保できるため。

# なぜReactでもVueでもなくElmを使っているのか

## 仮定

### 仮定1. 各コンポーネント等に状態を持たせることは問題である

> 大規模なアプリケーションは、多くの状態が色々なコンポーネントに散らばったり、コンポーネント間の相互作用のために複雑になりがちです。この問題を解消するために ...

*引用元 https://jp.vuejs.org/v2/guide/state-management.html*

### 仮定2. 関数型、型付けは強く、静的であるほどバグが減る

言語のカテゴリ毎の不具合の作りやすさの調査

|指向|動的静的|型付けの強さ|メモリ管理の有無|低いほど高得点|
|:---:|:---:|:---:|:--:|:--:|
|関数型|静的|強い型付け|有|-0.25|
|関数型|動的|強い型付け|有|-0.17|
|手続き型|静的|強い型付け|有|−0.06|
|スクリプト|動的|強い型付け|有|0.001|
|スクリプト|動的|弱い型付け|有|0.04|
|手続き型|静的|弱い型付け|無|0.14|

> Functional-Static-Strong-Managed −0.25 (0.04) ∗∗∗
Functional-Dynamic-Strong-Managed −0.17 (0.04) ∗∗∗
Proc-Static-Strong-Managed − 0.06 (0.03) ∗
Script-Dynamic-Strong-Managed 0.001 (0.03)
Script-Dynamic-Weak-Managed 0.04 (0.02) ∗
Proc-Static-Weak-Unmanaged 0.14 (0.02) ∗∗∗

>各カテゴリに属する言語は以下のとおりです。

>Functional-Static-Strong-Managed： Haskell、Scala
Functional-Dynamic-Strong-Managed： Clojure、Erlang
Proc-Static-Strong-Managed： C#、Java、Go
Script-Dynamic-Strong-Managed： Python、Ruby
Script-Dynamic-Weak-Managed： Perl、PHP、JavaScript
Proc-Static-Weak-Unmanaged：C、C++、Objective-C

*引用元 https://developers.srad.jp/story/14/11/08/081210/*

但しこの記事の仮定では各言語の具体的なポイント数は考慮しないものとして、カテゴリ毎のポイント数のみ見ることにします。

### 仮定3. Nullを他の型の一部として扱うのは問題である

>2009年のカンファレンスでNull参照を発明したことについて謝罪している。
>>それは10億ドルにも相当する私の誤りだ。null参照を発明したのは1965年のことだった。当時、私はオブジェクト指向言語 (ALGOL W) における参照のための包括的型システムを設計していた。目標は、コンパイラでの自動チェックで全ての参照が完全に安全であることを保証することだった。しかし、私は単にそれが容易だというだけで、無効な参照を含める誘惑に抵抗できなかった。これは、後に数え切れない過ち、脆弱性、システムクラッシュを引き起こし、過去40年間で10億ドル相当の苦痛と損害を引き起こしたとみられる。

*引用元 [アントニー・ホーア - wikipedia](https://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%B3%E3%83%88%E3%83%8B%E3%83%BC%E3%83%BB%E3%83%9B%E3%83%BC%E3%82%A2)*

これら上記の3つの仮定に関して、一般的にエンジニアの皆さんには共通した意識があると思います。

## 仮定1について

#### 仮定1. 各コンポーネント等に状態を持たせることは問題である

`Elm`というフレームワークは`Vue`で言うところの`vuex`、`React`でいうところの`Redux`などに用いられているアーキテクチャを標準搭載 & それ以外のアーキテクチャを利用できない仕組みになっており、基本的に状態を一元管理することしかできません。
**なおvuexとReduxはElmアーキテクチャに触発されたものであり、公式に記述しています**
https://jp.vuejs.org/v2/guide/state-management.html
https://github.com/reduxjs/redux
リンクに飛んでブラウザでElmと検索してみましょう

そして現在の時刻を取得する関数やhttp通信などの関数は毎度同じ関数とは言えず、状態保有した関数と言えます。
Elmはそれらを関数として使うことができません。(便利に使えて関数とは違う仕組みとして利用することはできます)

ReactやVueでElmアーキテクチャを利用していたとしても、JSやTypeScriptの言語仕様として、状態の保持を頑張ればできてしまうんですね。

最大の違いは上記の、状態を保持することができないこと、純粋関数以外を記述できないという点を、**言語仕様**として厳しくコンパイラがチェックしている点にあります。

その為、コードレビューやコーディング規約などの人的リソースを使う必要なく、品質の高いソフトウェアを記述できるという利点があります。

## 仮定２について

#### 仮定2. 関数型、型付けは強く、静的であるほどバグが減る

VueとReactは最大でこれらの条件に近づくには、Any型を含み、手続き型であるTypeScriptを利用することがJavaScriptからの精一杯の解決法です。

Elmは関数型であり、強い型付けであり、静的です。

## 仮定３について

#### 仮定3.Nullを他の型の一部として扱うのは問題である

仮定２に近く見えるかもしれませんが、強い型付けだとしても、Javaのような言語ではNullが存在します。これらは仮定２の論文では分類されていません。その為違う話題として取り上げています。

ElmではJavaScriptとは異なり、Nullが存在しません。Intという型と、IntとNullの直和の型を完全に別のものとして捉えており、問題を解決しています。

なお、TypeScriptでもこの問題は解決しています。
しかしanyがあるのでやはりコードレビューリソースが追加でかかることや書き手によりコードの質が大きく変わってしまうのではという問題が付き纏います。

# つまり

全体的にElmという言語は開発者やコードレビューの質に依存せず品質を向上させ、ソフトウェアの品質の最大値を上昇させるというものではなく品質の最低ラインを担保するという性質がありそうです。

仮定を真とし、これらの課題を解決することに絞るとするならば、Elmに帰結することは常と言えます。
(ここではReactやVueをディスっているように見えますが、任意の仮定と課題に絞り勝っている部分があるというだけです。)


# 現実的には

しかし、実際にElmを実戦投入するとなるとReactにはあるパッケージがElmにはなかったり、そもそも記法がML系言語だったりと大多数のエンジニアには受け入れがたい現実があります。

パッケージに関してはそこそこ数も揃っている上に、JSと純粋さを保ちつつ連携できる機能がElmには備わっています。

そして慣れてしまえばML系の記法は個人的にはAlgol系よりも書きやすいものですし、DXも非常に高いと思ってはいますが、チームで開発する以上は他の人の慣れも考慮する必要がありますね。

その為、今回新たに開発したElmを利用したプロジェクトに関しては、全てのページをElmで置き換えるようなことはなく、適材適所で特にロジックや非同期が複雑になりがちなページに絞ってElmを利用することにより、チームとして最大限の効果を享受しようと試みています。
(なお、Elmは非常に言語機能がコンパクトかつシンプルに纏まっており、非常に学習コストの低い言語と言えます。)

Elmは小さく始めることも可能なのです。

# 個人的には

存在しないパッケージを自分で開発したりとか、フレームワークや言語にバグが存在すれば自分で治せるし、そんなことよりもそもそも直しようがない言語の構文や機能自体から波及するメリットの優位性を重視して他の言語やフレームワークではなくElmを利用しています。

さらに、最近のオブジェクト指向への懐疑的な流れから流行っているモダンな言語機能をもつRustやScalaなどといった言語と同じような代数的データ型やnullの扱いについても学べ、開発者自身の市場価値や技術力を向上させることも利用した動機の一つになっています。

個別具体的な用法についてのコード他の言語とは異なりネットに転がってないので、コピペして機能開発をすることはできませんが、正しく理解していれば、開発可能性(計算可能性に掛けた今作った言葉)はReactやVueと全く同じなので、ぜひ挑戦してみてください。

# まとめ

Elm、はっきり言ってコードレビューの工数減るし、実行時エラー出ないし、新規開発や修正時のバグ出ないし、技術的負債がたまりにくいので競合他社は絶対に使わないでください。