みずりゅの自由帳

主に参加したイベントやソフトウェア技術/開発について記録しています

「GenServerは状態を持っているからオブジェクト?」な話題も出てきたElixirDI会#2の参加レポ

2020年11月10日に、『Elixir Digitalization Implementors #2:通信テスト込の愛でる会』(略称はEDI会)に参加しました。

イベントの詳細はこちらを参照。
fukuokaex.connpass.com


このイベントの中で、タイトルにもあるように「GenServerの"状態"」の話題も挙がりました。
なお、今回ブログを書こうと思ったきっかけがコレ。

ここから発展していった話題も面白かったので、あわせてご紹介します。

Elixir Digitalization Implementorsについて

fukuoka.exの主催の一人である、piacere氏が発足されたイベントです。

イベントの趣旨は以下の通り。

「Elixir Digitalization Implementors」、略称「EDI」は、「Elixir実装の芽」をみんなで愛でるコミュニティです

そうした芽から、「身近な仕事や生活をElixirでデジタル化して、良くしていこう」というのが、この会の狙いです

参加した印象としては『個々人のElixirの熟練度云々は置いといて、Elixirが好きな人たち集まって話そうよ』な雰囲気が感じられ、気楽に参加できるイベントだと思っています。
LTをする側にとっても、「I-IZM」「M-IZM」「S-IZM」と発表形式を選べるので、色んな楽しみ方もできるのではないでしょうか。

なお、ハッシュタグは「 #ElixirDI 」です。
これをみて雰囲気を掴むのもありですね。


余談ですが、第一回目の参加では自分もLTをしてきました。

mzryuka.hatenablog.jp

LT会について

イベントでは、以下に関する発表が行われました。
今回の特徴としては、「I-IZM」形式(登壇者の発表を参加者もワイワイしながら進める形式)の発表が多かったです。

  • Phoenix LiveView + WebViewでのスマホアプリ実装
    • LiveViewだけだと審査が落とされるので、スマホ用オブジェクトを配置することで回避されたとか。なるほどと思いつつ、それだけでいいんだ感も(笑)
  • Nerves GenServer Lチカ
    • Nerves内でGenServerを使ってLチカする場合の実装説明。GenServerについての解説も。
  • LiveUploadsプルリクレビューに参加して取り込んでもらえた話
    • タイトルの件以外に複数の話題でお話されていました。Phoenixを使った"湯婆婆"にはクスリw
  • AtCoder用nimixタスクを提供するライブラリの話
    • mixタスクについてのお話。"mixタスクには2種類ある"には、思わず反応してしまいました(後述)
  • リベンジ:Phoenix WebSocketで「VRの世界」を現実にAR投影
    • 前回のリベンジ。今回はうまくいきました(笑)。NeosVR の世界を見せてもらっただけでもお腹いっぱいなのに、Elixirとも組み合わせられたということで、ニヤニヤしながら見ていました。VR空間内で、ネットの画面を切り貼り出来たのは驚きました。(後述)


いやー、どれも楽しかったです。

"mixタスクには2種類ある"、についてはこんな反応をしました。

なるほど、「単体で実行可能なmixタスク」と「mixプロジェクト配下で実行可能なmixタスク」があるのか。
話を聴いてて、"今度、mixタスクを自作してみよう"と思った次第。古賀さんのツイートも参考になる。

また、"VRの世界"については画像がある方がわかりやすいので、こちらのツイートをご紹介。

GenServerは状態を持っているからオブジェクト?

最初にも触れたましたが、これが本記事を書くことにしたきっかけ。

GenServerのわかりやすい&詳しい説明はこちらを参照。

elixirschool.com

端的に言えば、「状態を持っており」「メッセージの送受信で処理を行う」動きをするGenServerは、(オブジェクト指向における)"オブジェクト"とも言えるのでは?という提議がLT会中に出てきました。

LT会中では、「状態持ち+メッセージパッシングを"アクター"と呼ぶか"オブジェクト"と呼ぶかの違いでは?」の結論となりました。

自分も、同じようなことを考えたことがありました。
しかし、アクターモデルの概念を知り、関数型言語オブジェクト指向言語の差異から、「オブジェクトとは異なるよなぁ」と考えるようにはなっていました。

関数型言語の特徴は、同じ引数を渡した場合は必ず同じ結果が返ってくる、です。
これに対して、"状態"を保持しているとその"状態"によって返ってくる値が異なる可能性がある、のでオブジェクトのようにも見えてしまいます。
しかし、これはDBやファイルの中身のような"副作用"に関係する部分です。
この副作用の部分だけをみて、"オブジェクト"と呼ぶのには違和感が出てきました。

お茶会で出ていた話

EDI会のお茶会(≒懇親会)では、上述の「GenServerは状態を〜」に関連した話も出ていました。
いくつかを簡単にご紹介します。
※それぞれの詳しい話については、piacereさんが、elxiir jp Slackのelixirdiチャンネルに記載してくださっています。多謝。



副作用と状態について

関数型の利点は、「同じ入力に対して、同じ出力を返す」=「テストが容易でバグりにくい」があります。
一方で、"状態"があると「同じ入力に対して、出力が異なる」が発生します。つまりは副作用です。
しかし、人間の使うシステムでは、副作用とは無関係ではいられません。それは、DB/ファイル/画面やUI、などに当たります。

本質的な課題は、「状態/副作用をいかに状態/副作用が無い領域と切り分けるか」である、と。

副作用のある箇所と密結合な作りになれば、バグの要因にもなります。
そうならないよう、モジュール分離/ライブラリ化、TDDを行って、安全設計していくのが良いとのこと。

型安全について

Elixirは型については割と制限が緩い言語です。
しかし、近年では型定義のしっかりした言語(もしくは、型定義をしっかりする仕組み)が人気です。JavaScriptにおけるTypeScriptが顕著ですかね。
Elixirと同じ関数型言語だと、Haskelも型安全な言語です。

型定義により型安全となることで、コンパイルでコーディングレベルのミスがはじけたり、エディタ補完もできるようになるため非常に利点が大きいです。

しかし、そこを踏まえた上でも、副作用によって問題が発生してしまいます。
Elixirは"エラーは必ず発生する前提"の思想が背景にあるため、型には緩い部分があるようです。

https://speakerdeck.com/piacerex/elixirtohaskellfalsegen-di-niarutong-zimofalse-sosite-elixirgachan-tutadao?slide=79

上記URLのスライドから抜粋した思想は以下です。

  • プログラムは人が書くものだからバグは避けられない
  • システムは、支配下以外にも存在する
  • よって、すべてのエラーを把握してコードを書くことは不可能である
  • なので、「エラーは必ず発生する」を前提とする

なお、スライドで述べているElixir/Erlangの哲学は、「すごいErlangゆかいに学ぼう!」に書かれているそうです。

アラン・ケイオブジェクト指向

クラス/継承では無いオブジェクト指向についてのお話。

qiita.com

Erlangオブジェクト指向?

Erlangオブジェクト指向かも、という話があがっているというお話。

tokoma1.hatenablog.com

これ以外にも

Slack上で、pojiroさんから次のようなコメントをいただけました。

  • 関数を状態と分離してテスタブルにすることが大事
  • GenServerモジュールがファットにならないように、必要に応じて別モジュールに分離

テスタブルについては、こちらの本が参考資料になるとのこと。

pragprog.com

また、OTPのデザインパターンが載っている書籍についても教えていただきました。

www.manning.com

まとめ

こんなわけで、EDI会イベントへの参加で、面白い話に触れることができました。

ElixirやそのフレームワークPhoenixやNervesなど)に興味のある方は、EDI会に参加してみるのもいいんじゃないでしょうか。