2021年2月20日土曜日

ElmにおけるMVCと入出力インタフェース

The Elm Architectureというものを教えてもらった.Webアプリのフロントエンド開発でよく利用されているReduxやVuexというライブラリに影響を与えたものだそうで,ふむふむ,なかなかよくできている.

Model-View-Update

まずは簡単なプログラミングの例を見てほしい.適当な文を入力してもらい,処理を実施するとその文を反転したものを出力するというシンプルなものだ.

The Elm Architectureは,モデル(Model)とビュー(View)を定義して,ビューから発するメッセージに応じてモデルを更新するというイベント・ドリブンなプログラミングモデルである.イベントに相当するものをメッセージと呼び,更新する処理をアップデート(Update)として定義する.

MVCモデルを理解している人は,このアーキテクチャもMVCモデルに非常に似ているということに気付くだろう.Controllerの代わりにUpdateと表現されているにすぎない.ほとんど同じような立て付けである.

モデルが変更されると自動でビューも更新されるので,DOMを操作してアップデートしてというような低レベルな処理をプログラマが意識する必要のない点もありがたい.このあたりの抽象化が上手に実装されている点は,イマ風のアーキテクチャだなと感心する.

具体例

この例では,Modelとして{ input : String, output : String }を与えている.2つの文字列型変数inputoutputを持つ.前者は入力された文字列,後者は処理後の結果として出力されるべき文字列である.

Viewも関数で定義されるのは面白い.中身がそれぞれHTMLのタグと対応しているので,HTMLをきちんと理解しているプログラマであれば読みこなすことは容易であろう.しかもDOMの知識を持っていなくても理解できそうだという点も興味深い.

onInputonClickというキーワードがユーザ操作とメッセージ発生を結びつけているものである.前者は文字が入力/削除される毎に発生し,その都度,モデルのinputが書き換えられているが,今回の例ではそれを意識する必要はない.メッセージが発生するとUpdate関数がそれを受け取り,受け取ったメッセージに応じた処理(case文で分岐している)を行う.メッセージがChange(テキストエリアの編集で,都度,発生する)だったらinputの書き換えを,メッセージがReverse(「reverse」ボタンのクリックで発生する)だったら文字列の反転処理を行いoutputに格納する,という処理が定義されている.

入出力インタフェースの抽象化問題

このプログラム,実質的な処理に相当する部分は「String.reverse model.input」という部分だけである.その意味では,この程度のプログラムであれば実行するために準備しなければならない部分のオーバヘッドが大きすぎるといえなくもない.

ElmはいわゆるAltJS,すなわち,JavaScriptにコンパイルされて実施される処理系である.一方,今回のような小さなプログラムならば,JavaScriptをコマンドラインで実行するjscという処理系を使えば,次のような極めてシンプルなプログラムで表現できる.

#!/System/Library/Frameworks/JavaScriptCore.framework/Versions/A/Helpers/jsc

let input, output;

input = this.readline();

output = input.split("").reverse().join("");

print(output);

このファイルをreverse.jsという名前で保存し,実行属性を付けて実際に動作させてみた例が次の例である(なお,入力するデータは日本語文字列だと文字化けしてしまうため,英文データとした).

echoコマンドを用いてパイプで流し込んだ文字列が,適切に反転されて出力されていることを確認されたい.

しかし,これをきちんと理解するためには,標準入出力の概念を理解しなければならない. readline()とprint()がプログラム側からのインタフェースになっていることの学習も必要だ.一度,理解してしまえばシンプルで分かりやすいものだが,抽象度が高いため初学者には若干難しいという問題もある.

Elmにおける実装

対してElmの場合は次のようなものとなる(余分な記述は排除した).

textarea [ value model.input, onInput Change ] []

textarea [ value model.output ] []

その実装はGUI部品として目に見えるため,ある程度は抽象化されているとはいえ具体的に理解しやすいのではなかろうか.

Webブラウザで動作させる素のJavaScript実装においてもTextArea等を用いた入出力の実装を具体的に理解することができるが,具体的すぎてDOMの理解が必要という課題が生じる.Elmが提供するインタフェースは,抽象度と具体化の度合いがちょうどよいのではないか,初学者にもすんなりと受け入れられるのではないかと考える次第である.


0 件のコメント:

コメントを投稿