以下斜め読んだ内容

pseudo translation of useful posts, book reviews, remarks,etc. twitter: feeddict

Evan Czaplicki「脱FRP。またはThe Elm ArchitectureからSignalを消した件」

elm-lang.orgの2016.5.10のブログエントリ farewell-to-frp

ElmクリエータのEvanによる最新版0.17のアナウンス

  • 「Reactiveとか、非同期データストリームとかObservableとか、まあええけど、敷居上げすぎじゃね?」
    • 「じゃあSignal外して」「脱FRPしとくか」(今回)
  • 「WebAssembly来るかも?」
    • 「じゃあサクッと移行できるようにJSとのインフェース最小にしとくか」
    • 「いつでもどこでも脱AltJSできるように準備しとくか」
    • 「クロスコンパイルとかはいいわ」
  • OSS化しましたので皆様使って頂けたら。。。。」

というノリで、「使える言語」「使いやすい言語」ために手を打っていくところが面白い

以下斜め読んだ内容

  • The Elm Architectureのおさらい
    • webアプリ作るためのシンプルなパターン
    • Elmでコード書くときの標準的やりかた
    • 他言語に輸出された
      • reduxとか
      • JS界隈でも広まってきてる
    • 「成功した」と呼べるレベルに到達
  • Q:The Elm Architectureに沿って、websocketやGraphQLやgeolocationどう使う?
  • A:Subscription使え
    • コミュニティ内でこういう声は耳にしてきた
    • Subscriptionは自信作。いい感じににwebsocketつかえる
    • 今日(=2016.5.10)リリースするElm 0.17で追加した
  • Subscription入れると。。。

    • コンポーネントはメッセージを待受するだけに
    • ライブラリが裏で大量の手強いリソース管理をやってくれてる
    • Subscriptionでwebsocketが手軽に使える点は、エントリで後述する
  • Elmの学びやすさ・使いやすさの飛躍的な向上

    • Subscriptionなどが入った)Elm 0.17リリースの意味
  • 少し前までElmには、SignalAddressPortというのがありまして。。。
    • こいつらがElmの敷居を高くしていた。
    • Subscriptionを次のリリースでElmに入れてみようか、と考えてるときに気付いた
    • Signal(とかの難解なコンセプト)は無くてもいいじゃん
    • もっとシンプルなコンセプトに分解していけば、Signal引退できる
    • (補足)
  • 「Elmを使いこなす」ために理解しないといけないコンセプトの数
    • Signalが引退すれば、この数をぐっと減らせる
  • 「使いやすさ」のためにElmをデザインしてる
    • これは思いがけず開けた道筋。かなりうれしい展開。
  • 「皆さん注目!」的な言い方を敢えてしてみると。。。
    • Signalに関係してるもの全部引退
    • もっとシンプル、もっと優れたものに置き換え。
  • Signal引退をElm界隈でアナウンスしてみた
    • 2パターンの反応
    • 反応1:クレージー。コードは動くのか
    • 回答1:95%(俺調べ)のコードはそのままで動く
    • 反応2:お前は何言ってるんだ? FRPとかSignalとか何それ
    • 回答2:「知らん」でOK
      • 今回のリリース(0.17)に直結する話。
      • Elmには不要になった
  • あれこれ回答するよりも、新しいElmがどう動くかを見せた方がいい。
  • 閑話休題
    • subscription以外の0.17のおすすめ紹介
    • HTMLレンダリングを高速化(ベンチマークは後で出す)
    • web platformのテクノロジーを簡単に使えるライブラリを追加
      • geolocation
      • Page Visibility API
      • websockets
    • コンパイル最適化
      • outputのjsのサイズをダウン
      • outputされるjs
        • closure compilerに通せる
        • RequireJSサポート
        • CommonJSサポート
    • GraphQLやPhoenix(Elixir)のようなサービスと連携するための機能
    • ドキュメント改善:Gitbookベースに
    • JSONデコードエラー時のメッセージ出力の改善

subscription例その1。現在時刻の待受

  • コンポーネントがメッセージ待受をサポートできるようにするための方法
    • subscriptionが一つのやりかた
  • コンポーネントがsubscribeする対象
    • 現在時刻
    • 位置の変化
    • websocketメッセージ
    • etc..
  • SVGによるアナログ時計を使って説明する
    • SVG時計の基礎は、時間へのsubscribe
    • subscriptionの最もシンプルな例
    • とりあえずSVG時計のソースコードをざっと見てもらいたい
      • 典型的なElmコード
-- 0.17以前と違う箇所はこの3行だけ
subscriptions : Model -> Sub Msg
subscriptions model =
  Time.every second Tick       
  • 与えられたmodelに対して、アクティブなsubscritpionがこれだけで記述されてる
  • 関数Time.everyを使って、現在時刻へのsubscriptionを記述
  • 現在時刻は毎秒更新
  • 新しい時刻(ex Tick 1462487781991)はupdate関数に渡される
  • (補足)
    • subscriptionは、Sub msg型(Sub = Platform.Sub
    • 関数Time.everyの型定義は、Time.every : Time -> (Time -> msg) -> Sub msg
    • なので、Time.every second Tickは、Sub msg
    • あと、secondTime.secondは)Time
    • Ticktype Msg = Tick Timeという型定義から、(Time -> msg)
      • Tick 1462487781991Msg
    • Tickは冗長にかけば、(\time -> Tick time)、となる
    • つまり、Time.every second (\time -> Tick time)
  • subscription以外の部分はすべては0.17以前と同じまま
  • 何かを待受してるだけなので、一番簡単な例
  • 次は、もうちょっと複雑なシナリオで

例その2。websockets通信

  • シンプルなchatクライアントdemo
    • 送信されたメッセージを表示するだけの機能(荒れても困るので)
  • ソースコード
    • SVG時計と見比べると大変よく似てる
    • よく似たコードだけど、このコードだけでwebsocket通信を管理してる
-- ソースコードで注目すべきはこの2行だけ
-- こっちはメッセージを送信
WebSocket.send "ws://echo.websocket.org" input
-- こっちはメッセージをsubscribeしてる 
WebSocket.listen "ws://echo.websocket.org" NewMessage
  • 送信してるコード、subscribeしてるコードの共通してること
    • chatサーバのアドレスを渡してる点
    • 通信を助ける値を渡してる
  • WebSocket.listenでは渡されてるNewMessageMsg型のタグを返す関数
    • (補足)
      • Msg型の型定義は、 type Msg = Input String | Send | NewMessage String

        Union Types使って定義されてる

      • Input StringSendNewMessage Stringをタグと言う(らしい)
      • なのでUnion Typeと呼ばずに、Tagged Unionと言う人がいる
  • サーバーから「hi」というメッセージを受け取り、NewMessage "hi"、をupdate関数に渡す
  • (補足)
    • WebSocket.listenの型定義は、String -> (String -> msg) -> Sub msg
    • NewMessageは、String -> msg型の関数
    • NewMessage "hi"Msg
  • 自慢できること
    • あれこれ細かい制御のためのコードを書かなくてもチャット機能を提供できてること
    • sendしてlistenする。それだけ
  • チャット機能をjsでやろうとすると。。。
    • ひとつはブラウザAPIを直接触る
      • new WebSocket(...するところから
      • コネクション開く
      • onerrorリスナーつけ忘れない
      • 切断されたら再接続するように書く
        • いわゆるExponential Backoffの仕組みもいる
      • 切断されてたらメッセージ送らないようにしないといけない
        • ランタイムエラーになるから
      • キューイングシステムも実装必要
        • 切断時にpostされたメッセージを貯めとく
      • さらに
        • どのコンポーネントがwebsocket通信するかを考えて設計しないといけない
        • 接続の切断についても適切な時間でやれるようにしないといけない
    • JSライブラリを使う手もある
      • 調べると2,000以上はある。npm検索で
      • 最初の1、2個で当たりが出ることを祈りましょう
  • ElmのWebSocketパッケージを使うと。。。。
    • websocket通信のための細々とした管理は自動的に行われる
    • subscriptionが発生すれば自動接続
    • subscribeがゼロになれば自動切断
    • メッセージのキューイング、再接続はバックグラウンドで処理され、意識しないでいい

さらに学ぶためのリソース

  • 公式ガイド
    • http://guide.elm-lang.org/
    • Elmと The Elm Architectureがやろうとしてることを知りたい人
      • The Elm Architectureのセクションを一読してほしい
      • 順序立ててSuscriptionを使った実装をやるとこまで書いてる
    • 他にもいいサンプルある
  • Elm経験者にはアップグレードガイド用意してる
  • Slackチャンネル作った。活用してほしい
    • Elm初心者が質問する場所、何か学ぶ場所として
    • 0.16以前のアプリを0.17に移行させたい人の質問する場所として

さらばFRP

  • このraycasterみたいな、楽しくなるプロジェクト
  • シェアしたくなるプロジェクト
  • プログラミングすることに熱中させてくれるプロジェクト
  • Elmは、こういうプロジェクトを作っていける何か
  • Elmを作ってる自分が自問してきたこと
    • どうすればElmがもっとシンプルになるか
    • どうすればElmが学びやすくなるか
    • どうすればもっと楽しくなるか
    • どうすればもっと素早くプロトタイプを作れるようになるか
    • どうすればもっと信頼できる言語になるか
  • こういった自問し続けてることが、Elmの設計哲学の中心にあり、Elmの成功の根幹にある
  • 2011年頃に自分が卒論を書いてた頃の話
    • http://elm-lang.org/papers/concurrent-frp.pdf
    • たまたま"Functional Reactive Programming" (FRP)と呼ばれるニッチな学問領域に突入した
    • FRPの手法をシンプルな形に落とし込むことを考えていた
    • 結論として類似の関数型言語よりも学習しやすいものを作ることができた
    • Signalは難解なコンセプトが折り重なったもの
    • Elmには必要ではなかった
  • SignalはElmにある数少ない躓きポイント」
    • Elmを教えた経験のある人なら同意してくれるところ
  • SignalによってElmは使やすくなった」
    • 類似言語との比較でならそうとも言える
    • SignalはElmそのものを「やさしい」言語にはしなかった
  • The Elm Architecture導入後
    • Elmでのプログラミング体験の大部分で、Signalを考えないといけない時間を消し去った
    • start-appパッケージ
      • これは実験だった
      • Signalは「後から学べばよい」という位置付けに変えたらどう変化するか?
      • かなりよい結果がでた
        • 素早くElm入門できるようになった
        • すばやく上達し、Elmでのプログラミングを楽しんでくれた
        • Signalについて多くの事柄を学習してなくても、素晴らしいElmプログラマをたくさん生み出せた
        • Signalにまつわる事柄は必須ではなかった
        • 0.17 のリリースでこの流れを一歩先に進めただけ、とも言える
  • 結構前からSignalはElmから削除可能だった
    • 「Elmはconcurrency重視」に舵を切っていたから
    • cocurrency重視のアイディアの原型は自分の卒論に確認できる
    • 0.15でElmにTaskを導入してから、Elmの実装レベルでこの方向に進み出した
  • 0.15で導入されたスケジューラ
    • スケジューラはwork(?)の切り替えをサポートし、必要なときだけ実行させることができる
    • 0.17で大幅に改善された箇所
    • スケジューラはeffect managerの基盤
    • さらに、effect managerがSubscriptionの基盤
    • (補足)
      • Elmでは、Effect(作用)はデータとして表現され、Elmランタイムが実行し、実行時に最適化を行う
      • Effectの例:httpリクエスト、乱数取得、時刻取得、DB書込、etc..
      • データとして表現され、Elmランタイムが最適化しながら実行するEffectは、SubscriptionCommandの2種類
    • ドキュメントをもっと書き換えたいところ
    • スケジューラ、effect managerの内部のことを深く知る必要はElmのエキスパートになるのに必要でない
    • concurrencyの利点を即座に享受できることを目標にしてる
      • この点は私の卒論Concurrent FRPの頃から変わってない
  • ElmはFRP的ななにか?
    • かつてそうだったが、今はそうでない
  • Elmはconcurrencyに真剣に取り組む関数型言語であり、フレンドリーな関数型言語であるだけ

  • 閑話休題

    • この辺に興味持ってる人だとLucid Synchroneという言語も面白いと思うかも
    • 自分がElmで考えてることと、同期的プログラミング言語の間にはたくさん共通点がある
      • 自分が卒論書いてる当時は知らなかったこと
      • Elmと同期的プログラミングのつながりは自分にとって衝撃だった
      • ElmはFRPな何かであったことは一度もなかった、付け加えておく

Elmの今後

  • Elm 0.17開発初期の自分のヴィジョン
  • Elm 0.17はこのヴィジョンの基礎になるリリース
  • 次に取り組む問題
    • 1 webプラットフォームの全てをサポート
    • 2 GraphQL, Elixir Phoenix, Firebaseなどのバックエンドのサポート
    • CommmandsSubscriptionでは全てのケースはハンドリングできる
      • The Elm Architectureできちんと使えるパッケージを組み合わせて、一貫性をもたせることもできる
    • これからこのへんの開発がどうなっていくのかが楽しみ
  • 次の問題へどうアプローチするか
    • ちゃんとみれば、the web platformはそれほど巨大じゃない
      • 残ってるAPIをサポートしていく
    • 「jsにコンパイルされる」という部分は将来無くなるかも。WebAssemblyが来たら
    • Elmとjsのインターフェースは小さくしていく
      • そうすればjsから別のプラットフォームへの切り替えはスムーズに
    • ロスコンパイルは眼中にない
  • これから新たに作っていくライブラリ開発に参加したい方へ
    • そういう声をすでにもらってる
    • コントリビュートしたいという情熱が素晴らしいアウトプットを生む
      • 空回りなく、これが確実に起こるようにしておきたい
      • そのために、一貫性のある開発プロセスをまず自分が作る
      • それまで待っててほしい
    • 次期リリースのために現時点でできるコントリビュート
      • slackに参加して、elmコミュニティの動向を知ること
        • 何かコントリビュートするときは常に事前にやるべきことだが

thanks you

  • @JustusAdam
    • elm-reactorのnavigation画面の作り直し
    • 数年前に完了してた。ようやく公開できた
  • 0.17の設計に参加してくれた人たち
    • なんども繰り返して「これはあかんね」となったりもした
    • それでも付き合ってくれて、優れたアウトプットしてくれた
  • Elmコミュニティ