Elixir を使うようになった経緯 〜電力システム制御の現場から〜

（この記事は、[Elixir Advent Calendar 2018](https://qiita.com/advent-calendar/2018/elixir) の5日目です）
昨日は @piacere_ex さんの[【Gigalixir編①】Elixir／Phoenix本番リリース： 初期PJリリースまで](https://qiita.com/piacere_ex/items/1a9cbcc740ca3707eaec)でした。

# はじめに
Advent Calendar 初体験の @kikuyuta です。今年の頭に悩んだ挙げ句に Elixir を仕事で使うことに決定しました。そう、悩んだ挙げ句の決定だったのですが、その後は [fukuoka.ex](https://fukuokaex.fun) [#fukuokaex](https://twitter.com/search?q=%23fukuokaex) との出会いもあって、坂を転がり落ちるように（いい表現じゃないなぁ）Elixir 漬けになりました。ここでは、自分が今年を振り返るのと同時に、その様子を晒すことで Elixir 採用を検討しているみなさんの参考になる記事にするのを目指します。

## BGM
まずはこちら。なにやかにやと *Elixir* でネット検索するわけで、まずは音楽を。[youtube で探してみた](https://www.youtube.com/results?search_query=salad+drink+the+elixir) ら御機嫌なのを見つけたのでご紹介しておきます。[Salad](https://en.wikipedia.org/wiki/Salad_(band)) ってバンドの *Drink me* ってアルバムの *Drink the Elixir* って曲です。毒をくらわば皿まで、Elixir 飲むなら曲まで。ということで 

## 背景
私は2012年に志を共にする2名と[地域小水力発電株式会社](http://www.communalhydro.com/)を創りました。地域の人々が地域の資源を電気エネルギーという形にすることで疲弊する地域を支えることができるだろうと考えたからです。この組織は、地域コミュニティの依頼を受けて、小水力発電所を設置する適地の調査、基本設計、詳細設計、施工管理、そして運用支援の業務をやります。小水力発電所のライフタイム全体に対するよろずコンサルタントです。[^aboutCHE]

[^aboutCHE]: 2019年2月に地域小水力発電を退職してます。2019年3月に、より広く再エネと地域とを支援するコンサルティング会社「合同会社クラウドグリッド」を同士と2名で設立しました。

小水力発電所とはザックリでいうと1000kW以下の水力発電所を指すことが多いです。特に住民ベースで言うと50〜200kWぐらいの発電所です。我々がフルにコミットした案件として[馬路村小水力発電所](http://www.umaji-shp.org/)があります。これは145kWの発電所です。こんなのを住民ベースで作れるようにして、さらに全国に沢山作りまくるのが夢でありミッションでもあります。

# 古典的なPLCからの脱出

発電所の制御は通称 [PLC (Programmable Logic Controller)](https://ja.wikipedia.org/wiki/プログラマブルロジックコントローラ) と呼ばれるコンピュータで行います。これは電力回路の制御を、元々はリレーと呼ばれる電気部品だけでやってたのをプログラマブルにやるための機械です。CPUもメモリもI/OもありEthernetのインタフェースも付けられます。が、クラウドに繋いでなにかしようという発想がありません。IoT的にデータをアップしたり、つながってる全部の発電所を統合的に制御したり… といった応用は考えられてないです。

私達は全国に小水力発電所を作りたい、エンドユーザである住民が気持ちよく小水力発電所の管理運用をできるようにしたいという考えを持ってました。ですので、クラウド的に管理することが必要で、それは PLC だけでは困難だろうと思っているのです。ですので、先程の馬路村の小水力発電所は PLC で制御するのに加えて、PLC と通信するサーバを Rapsberry Pi で作って、各種のデータを遠隔で収集できるようにしてあります。

## データ収集だけでなく制御もやってみる
馬路村小水力発電所は、インターネット経由で各種のデータを収集できるというレベルに留まったので、その次の発電所はもう一歩踏み込んで、制御までやるように作り込んでみました。Rapsberry Pi では耐久性と信頼性に難があったので、Linux マシンを作りました。これは「いわゆる PLC」なマシンじゃないのですが、未来に対する希望も込めて bunkaPLC ver. 1.0 と名付けました。

![IMG_1206.JPG](https://qiita-image-store.s3.amazonaws.com/0/260320/d672e16e-8e38-2eeb-472c-81a7545d3540.jpeg)
（何か横向いてるから後で直す）

これは電力系な業界でいわゆる「盤」と呼ばれるラックの中に入ってます。以下が作りかけの小水力発電所で盤を設置してデバッグしてる風景です。

![IMG_9667.JPG](https://qiita-image-store.s3.amazonaws.com/0/260320/b571ea4a-e68c-4234-6638-0af1661144b3.jpeg)

（なんか逆さまになてるから後で直す）

これはソフトウェア開発のパートナーさんに実装をお願いしました。言語は相談して python を採用してます。1秒以下のキモい制御が必要なところは古典的なリレーに任せて、時間的にシビアでない部分は python で制御するようにしました。

# 次世代PLC向きの言語はなにか

しかし、これは問題をはらんでしまいました。I/O でなにかに引っかかる（A/D 変換に時間がかかるとか、インターネットの通信が緩慢になるとか）とそこから出てくるまで他に制御が渡らないのです。致命的ではないのですが、操作してもすぐに反応しなかったりという操作性に課題を残してしまいました。その緩慢な部分を並行動作させて、主となる制御部分とは独立に動かすのが良いのでしょうが python ではキレイに作り直すのが難しい状況でした。UNIX の別プロセスにして UNIX ドメインのソケットかファイルでやりとりするということもありえたんでしょうが、納期の関係もあってそこまで踏み込みませんでした。

## python に変わる言語を

じゃあ python はやめて次は別の言語を採用しようということになります。python での開発途中から、ポスト python は node.js と思っていました。しかし、発電所の建設現場であれこれ思うに違うかなと言う感じがして来てました。自分の頭を整理するのに言語への要求をまとめてみました。2018.05.10 の私から開発パートナーへのメールにこんなのが羅列してあります。

- 並行処理に対する記述が容易（重要）
 - これは並列処理を意味しません。例えばマルチコアに強いとかは要求しないです。
- 信頼性が高い
 - これはコンパイル時にかなりエラーをはねてくれるとかです。（コンパイラ型、強い型言語での型推論がある）
- 組み込み開発で使いやすい
 - 小さな資源で動く・開発できる（せいぜいラズパイ）
 - 新規の入出力デバイスのライブラリが簡単に作れる
 - 当たり前だけどターゲットマシンの CPU アーキテクチャで動く
 - クロス開発ができる、特にMacintoshで開発ができる
 - ターゲットマシンにOSがなくても（ベアメタルでも）動くとうれしい
- 開発のしやすさ
 - ドキュメントが充実していること、特に日本語
 - 安定して言語開発が継続されていること
 - コミュニティが元気なこと
 - 必要な機能が安定版に入ってること
- 社会に対するインパクト
 - 我々の成果で新しい境地を開けると嬉しい
 - 広く世間の役に立つような（出版なぞできると嬉しい）

これに対してパートナーさんからは以下の要求も出ました。

- 大手クラウドベンダーのSDKが対応している事、もしくは今後対応するであろう言語が良い。


### 形式性への要求
できるだけ信頼性を上げておくのと、現場でのデバッグを容易にするのに型に厳しい言語で、コンパイル型にしたいなとはかなり考えていました。ちなみに、実装に先立って形式的仕様記述とかを導入しようかとも思ったのですが、今回は大規模である困難さがあるのではないので、実装側の開発環境が厳しいことでクリアするのが妥当かなと考え直しました。

### OSに関する議論
あと、OSはどうするかの議論もありました。小水力発電ですと ms で、それも動作時間の保証がないとならないようなキモい制御はないので、とりあえず今回は組込系の OS は考えないことにしました。なお、当時のメールには「将来的には μI-TRON とかに載せたりできると楽しいかなとは思ってます。」というコメントが残ってます。
[μI-TRON の実装の一つ toppers](https://www.toppers.jp/)


# つぎの言語を決定する
上に挙げた条件を考えつつ、ざっといろんな言語をネットで眺めててこういう候補に絞りました。メール見ると、これが 2018.05.12 のことです。

- ラストリゾートとして node.js
 - 決め兼ねたら node.js にするということ
- 遡上にあがった言語
 - go
 - rust
 - haskell
 - erlang

## 大学の研究者たち
2018.05.23 に、いろんな大学のICT研究者とテレカンする機会があったので会議後に時間をもらって意見を聞いてみました。

- あまり大きなプログラムは作らないのでスクリプト言語しか使わない
- 並行プログラミング用の言語で自分も困っている
- お勧めは Go だ

最後の意見はサポートやコミュニティがしっかりしていることをあげてました。「プログラミング言語のいろいろな進化をきちんと取り入れてるのが rust、バッサリと捨て去ったのが go」という意見。ここの感想は当時の私も同感でした。

ちなみにスクリプト言語は python 利用者が圧倒的でした。

あと、某 TRON な研究者に言ってみたら「Itron に C でどうっすか？ arduino でも micro:bit でも動きますよ」って言われましたが、ハードウェアはそこまで小さいのを狙ってなかったのでスルーしました。あと C だと現代的ないろいろな果実を取り込めないだろうというのもありますしね。

## Elixir が候補に上がる
最初にメールで Elixir という単語が出たのが 2018.05.21 です。当時の私からのメールにはたった1行
*菊池です。備忘録で Elixir ってのを上げておきます。-- きくち*
とあります。正直このころは「他の言語に一皮被せたってあまり素性がよろしいようには思えない」と考えてました。なにかするたびに Erlang が顔を覗かせるようなら Erlang でやれば良いと思ったからです。で、Erlang はそのころは私のココロの上位にはいませんでした。

このころは[Qiita](http://qiita.com/)を始めとして、ネットの情報やら電子書籍やら物理書籍やら、片っ端からあたりました。それを元に言語別の星取表をつくってました。

いろいろやってるうちに Elixir にかなり良い印象を持つようになりました。これで、我々が使うハードウェアの I/O を旨いこと叩くことができるならこれにしよっかという気分になってきました。
Elixir でハードウェアっていうと [ALE](https://github.com/fhunleth/elixir_ale) とか [Nerves](https://nerves-project.org) とかぐらいが参考になりそうで、これは @takasehideki センセの [ElixirでIoT#1.0：IoTボードへのLinux環境の準備](https://qiita.com/takasehideki/items/9e3db412a40659233384) とかの記事が役に立ってます。

ハードウェア担当のパートナーさんからも「行けそうだよ」ってな反応をもらえたのが 2018.05.29 で、これでほぼ心が決まったというところです。

## コミュニティに出てみる
一旦、決めはしましたがまだ逡巡していました。一度決めて進んだら、相当しばらく戻れません。このときに大変助けてもらったのが fukuoka.ex と Sapporo BEAM です。

### fukuoka.ex に出てみた
ネットで elixir を検索すると tokyo.ex があって、一旦は行こうと思いました。でも、プログラムを見ると経験者向けな印象があって、自分が行って役に立つ情報が得られそうな気がしませんでした。そのちょっと後に fukuoka.ex というのがあって、それのプログラムは大変魅力的に見えました。高知からは朝夕2往復のJALがあります。夕刻のJALだと金曜の夜の会には間に合わないので、朝の便で福岡入し、天神近くのまずまず快適なレンタルスペースで時間を過ごしました。

夜からの fukuoka.ex の会は、それはそれは結構な衝撃的な時間で「今どきはこういうエコシステムがテクノロジーを進化させているのか！」と素直に感嘆しましたね。[^fukuoka.ex]

[^fukuoka.ex]: 2018.06.22開催の[【スポンサー枠で増席】fukuoka.ex#11：DB／データサイエンスにコネクトするElixir](https://fukuokaex.connpass.com/event/87241/)です。2019.06.22追記。

### Sapporo BEAM

ハードウェア作ってくれてるパートナー会社さんは札幌にありますので、打ち合わせで札幌出張ってのがありました。意図したわけじゃないのですが、それが木曜日。木曜の夜には [Sapporo BEAM](http://sapporo-beam.github.io) の定例会がある日です。「そうだ Sapporo BEAM に行ってみよう」

札幌生まれの私が札幌にいたのは浪人生までで、札幌グランドホテルなんてのにはまったく縁がなかったですね。そこのスタバが会場です。代表の @niku さんを探しました。twitter でやりとりしながら知らない人と会うというのも私には初めてです。そこでお会いできたというのだけでもまずまずドキドキな体験でした。

で @niku さんに自分の疑問を率直に話してみました。その反応「それなら大丈夫でしょう、きっとできると思います（意訳）」という発言を頂いて、ようやく point of no return を越える覚悟が固まりました。

私の心配は「状態」でした。関数型言語で状態をどう表現するのか扱うのか。それはトリッキーな方法でなく実現されているのか。そのときの心配はほぼその一点で、それが初めてお会いするそれまで他人だった誰かによって解決された瞬間でした。[^SapporoBEAM]

[^SapporoBEAM]: 2018.07.26(Thu) の夜。2019.06.22追記。

## Elixir 漬けになる
それからは、まとまった時間を見つけては Elixir 修行に勤しみました。Qiita 投稿ってのも初めてで、七転八倒の記録を[「はじめてなElixir」](https://qiita.com/kikuyuta/items/3c1798d15508040ccaaf)として残しています。今、Elixir で次の制御システムのプロトタイプを作っています。ハードウェアも bunkaPLC ver. 2.0 ってのを試作しました。それはもう少し熟したら公開します。もう戻れないところに来てしまっています。いずれみなさんに Elixir で制御する、おそらく世界ではじめての小水力発電所をご紹介できるでしょう。


# Elixir である理由
私のポエムをここまで読んで頂いて、ありがとうございました。参考になる点はございましたでしょうか。

ここであらためて Elixir を採用した理由をまとめておきます。こんな項目を作って星取表を作成してウンウン唸ってました。ここで「型推論による信頼性向上」とか書いてありますが、まだ型チェックによる恩恵に預かるまでには私が精進してません。

「コミュニティが元気なこと」は「まあ重要」という優先度でしたが、結果的にはこれがかなり重要なポイントではありましたし、いまでも本当に重要です。fukuoka.ex の @piacere_ex さん、@zacky1972 さん、Sapporo BEAM の @niku さんに出会わなかったら、twitter や Qiita でのやりとりをしたみなさんがいなかったなら、今はまったく別の道だったでしょう。

「遅延評価を持ち」ってのは「あまりこだわるな」とありますが、結局相当こだわりました。rust でも haskell でもなく elixir なのは、「遅延評価がいい塩梅」ってのが結構大きいんじゃないかと思ってますし、学術的な場所でコメントを求められたときに、経緯をきちんと話すのが面倒だったら「遅延評価がなくても困るし、完全に何もかも遅延評価でも困るので、Elixir です」と答えるつもりでいます。

でもね、なんで Elixir にしたかというと、よくわかんないんです。「何でか惹かれたので」というのが自分の気持に最も近いんですね。Elixir は引っかかる点が細かくあるんです。なんでこんなになってるんだろうって。でも惹かれるってなんだか長続きしそうな関係な感じがしませんか。

明日は @koyo-miyamura さんの[【Phoenix1.4】（後編）パスワード認証＆リレーションあり「ブログチュートリアル」](https://qiita.com/koyo-miyamura/items/8b17893fb99b4ac71cec)です。お楽しみに！

![20180526-language-for-bunka.jpg](https://qiita-image-store.s3.amazonaws.com/0/260320/cab33dc0-3197-dcda-0296-47f503da454a.jpeg)



# 参考

- なぜ小水力発電に関わってるかについてはこちらを
 - [小水力発電による地域活性化スキーム](https://www.slideshare.net/YutakaKikuchi1/a-scheme-for-regional-revitalization-with-small-hydro-power)
- Elixirで七転八倒してる様子はこちら（七転八起ではない）
 - [はじめてな Elixir(0)](https://qiita.com/kikuyuta/items/3c1798d15508040ccaaf)
- この記事は以下の記事に書ききれなかった考えを大幅に加筆したものです。
 - [はじめてなElixir(7) なぜElixirにしたのかを振り返る](https://qiita.com/kikuyuta/items/6d61b907d2cd1ce3aeea)

## その他の言語候補
こんなのにも一瞬興味を持ってはいました。備忘録として残しておきます。
[mruby](http://mruby.org/)
[イケてないのに人気がある golang vs イケてるのに人気がない Nim](http://wolfbash.hateblo.jp/entry/2017/10/02/163017)
[第二プログラミング言語として Rust はオススメしません Nim をやるのです](http://wolfbash.hateblo.jp/entry/2017/07/30/193412)
[Nim引退](http://akiradeveloper.hatenadiary.com/entry/2015/02/18/223351)