Elmガイドの歩き方
現時点で日本語訳なドキュメントが見当たらないので、公式を気合いで読む。 このメモは各章の要点だけ適当にメモったもの。
ElmはJavaScriptにコンパイルされる関数型言語。 WebサイトやWebアプリケーションを作るためのツール(Reactみたいな感じ)。 シンプルさ、使いやすさ、品質の高さを重視している。
ガイドの目的
- Elmプログラミングの基礎を知る。
- インタラクティブなアプリケーションをElmアーキテクチャで作る方法を知る。
- 他の言語にも通じる原則とかパターンを知る。
カウンターのサンプルアプリケーションでElmの雰囲気を見る。
update
とview
が完全に切り離されていて、HTMLを宣言的に記述できていることに注目。
「なぜ関数型言語なのか?」という見出しの割には、関数型関係なくね?みたいな話。 Elmの特徴について書いてあると思って読めばよいかと。
- ランタイムエラーが発生しない。関数が
null
やundefined
にならない。 - 機能追加を助ける便利なエラーメッセージがある。
- アプリケーションが成長してもうまく設計されたコードであり続ける。
- すべてのElmパッケージのセマンティックバージョン管理を自動的に強制する。
インストールの仕方。
- MacとWindowsはインストーラから
- npmでのインストールも可能
- githubのソースから
インストールしたらelm
コマンドが使えるようになる。
とりあえずnpmで入れとけばよいかと。
エディタ用のプラグイン色んなの出てる。
- Atom
- Brackets
- Emacs
- IntelliJ
- Light Table
- Sublime Text
- Vim
- VS Code
コードフォーマッターとしてelm-formatがあって、vimだとそれ使ってフォーマットしてくれる。
elm-formatはnpm install elm-format
で入れて使う。
elm
コマンドでできること。
Elm用のREPL。 コードをJavaScriptに変換して実行しているので、Node.jsがインストールされている必要がある。 バックスラッシュを使って複数行記述とかできる。
Elmプロジェクトの構築と実行(動作確認)に使う。
プロジェクトルートでコマンドを実行すると、http://localhost:8000
でサーバが起動し、
選択したElmファイルの動きを確認できる。
Elmプロジェクトをビルドする。 ElmコードをHTMLやJavaScriptに変換する。
Elmパッケージのインストールに使う。
パッケージはpackage.elm-lang.org
で公開されている。
elm.json
ファイルに依存関係が追加される。
REPLで体験するElmのコア言語の話。
実際はREPLはすべての結果の型を出力するが、ドキュメント上は省略されている。
値
, 関数
, リスト
, タプル
, レコード
について見ていく。
- 文字列
"
で囲んで宣言、++
で結合。
- 数値
- JavaScriptとは異なり、整数と浮動小数*点数を区別する。
- Python3と同様に浮動小数点の除算
/
と整数の除算//
がある。
数値が0よりも小さいかを判定するisNegative
関数を書いてみる。
- 引数を括弧で囲んでコンマで区切る代わりにスペースを使用して関数に適用する。
- 慣れるとクリーンに見える。らしい。
- 無名関数
- 引数をバックスラッシュつけてアロー(
->
)使って定義する。 - 即時実行する場合は括弧で囲んで後ろに引数を渡す。
- 引数をバックスラッシュつけてアロー(
条件付きの振る舞いをするときはIf式。
if
,then
,else
キーワードを使い、括弧や中括弧は使わない。- ブール値のみ使える。数値や文字列やリストはブール値代わりに使えない。
数値が9000を超えているかを示す関数を書いてみる。 関数の2行目の前にスペースを追加することに注意(構文的に重要なスペースがある)。
リスト。よくある感じ。
- 扱う値はすべて同じ型である必要がある。
- Listのapiに渡して色々できる。
タプル。よくある感じ。
- 固定数の値を保持、各値が任意の型を持てる。
- 関数から多値を返す時などに利用する。
- 扱う値が複雑になってきたらレコード使った方が良い。
JavaScriptのオブジェクトみたいなキーと値の組み合わせ。
- 中括弧で囲んでレコードを作成。
- フィールドへのアクセス
- ドットを利用してアクセスする。
- フィールド名を先に書いて関数のようにアクセスさせる仕方もある(
.name bill
みたいなやつ)。
- レコードを引数にとる関数はパターンマッチを使ってシンプルにできる。
- { age }の例、ageフィールドのあるレコードなら何でも渡せる。
- レコードの更新
- レコードの値の更新には
|
を使う。 - レコードの更新は破壊的な更新にならない。
- 既存のレコードを上書きするのではなく、新しいレコードを作成する。
- 可能な限り多くのコンテンツを共有することでこれを効率的にしている。
- たとえば10個のフィールドの1つを変更すると残りの9個は変更されていない値を共有して新しいレコードを作成する。
- レコードの値の更新には
レコードとJavaScriptでいうオブジェクトの違い。
- 存在しないフィールドにアクセスできない。
- フィールドは未定義またはnullにならない。
- 再帰的なレコードは作れない(this使ってどうのみたいな)。
Elmでアプリケーションを作る時に使うアーキテクチャパターン。 言語自体でこれをサポートしているので、何かしらのフレームワーク持ってきて使うとかしない。
- Webアプリケーションを設計するためのシンプルなパターン。
- モジュール性、コードの再利用、およびテストに最適。
- リファクタリングや機能追加の際にコードを健康な状態に保つ。
- ElmアーキテクチャはElm以外でも有用。
- ReduxはElmアーキテクチャに触発されている。
すべてのElmプログラムのロジックは、3つの部分に分割される。
- Model: アプリケーションの状態。
- Update: 状態を更新する。
- View: 状態をHTMLとして表示する。
Elmアーキテクチャでユーザ入力を処理する方法をサンプルで学んでいく。
- Buttons
- Text Fields
- Check Boxes
- Radio Buttons
- etc.
当たり前のように型を使うサンプルになっているので、このまま進まずにTypes
の章を先に読んだほうが良い。というわけで、スキップしてTypes
に行く。