Elmは、JavaScriptにコンパイルできる言語、いわゆるaltJSです。
変数宣言(のようなもの)
JavaScriptの場合
const a = 1;
let b = 1;
var c = 1;
ワイ「const
は定数いうて再代入できひんやつやな」
Elmの場合
a = 1
ワイ「const
もlet
もvar
も無いねんな」
ハスケル子「はい」
ハスケル子「デフォルトで再代入不可です」
ハスケル子「つまり不変なので、変数ですらなくて」
ハスケル子「ただ値に命名している、値を定義しているって感じですね」
ハスケル子「あとセミコロンも要りません」
ワイ「再代入はできなくても、JSのconstみたいに」
ワイ「オブジェクトのプロパティを一部変更することはできんねやろ?」
ハスケル子「いえ、オブジェクトのプロパティ・・・」
ハスケル子「というかElmではレコードのフィールドですね」
ハスケル子「フィールドも上書きできません1」
ハスケル子「全ての値が不変です」
ワイ「へぇぇ・・・」
関数の定義
JavaScriptの場合
function add (a, b) {
return a + b;
}
または
const add = function (a, b) {
return a + b;
}
アロー関数式で書くと↓
const add = (a, b) => a + b;
Elmの場合
add a b =
a + b
ワイ「Elmではカッコもカンマも無いんやな」
ワイ「さらにreturnも書かへんねやな」
ハスケル子「はい」
ハスケル子「関数の最後に評価された値が自動的に戻り値になります」
ワイ「そもそもfunction
とかいうのも無いんやな」
ワイ「変数とほぼおんなじやん」
ハスケル子「そうですね」
ハスケル子「引数があれば関数って感じです」
関数の実行(適用)
JavaScriptの場合
const result = add(3, 5);
Elmの場合
result = add 3 5
ワイ「関数を適用するにもカッコもカンマも無しなんや」
ハスケル子「はい」
ハスケル子「ただ、add
関数の結果を更に別の関数に渡したいときなんかは───」
result = anotherFunc add 3 5
ハスケル子「───と書くと」
ハスケル子「anotherFunc
関数に対して、add
と3
と5
という」
ハスケル子「3つの引数を渡してる感じになっちゃうので」
result = anotherFunc (add 3 5)
ハスケル子「↑こうすると、カッコで囲まれた部分が先に実行されます」
ワイ「なるほどな」
ワイ「add 3 5
の計算結果、つまり8
が」
ワイ「anotherFunc
関数の引数として渡される感じか」
ハスケル子「はい」
ハスケル子「または───」
result = anotherFunc <| add 3 5
ハスケル子「───こう書いても同じです」
ワイ「あー、パイプラインいうやつやね」
ワイ「これ読みやすくて好きやわ」
書く順序による影響
JavaScriptの場合
const a = 3;
const b = 5;
const c = a + b;
ワイ「基本、上から順に実行って感じよな」
ハスケル子「はい」
ハスケル子「なので例えば───」
const c = a + b;
const a = 3;
const b = 5;
ハスケル子「───こんな感じで」
ハスケル子「a
やb
に値を代入するより上の行で」
ハスケル子「a
やb
を使った計算などをしようとすると」
ハスケル子「エラーになっちゃいますよね」
ワイ「なるほどな」
ワイ「でもまあ、それは普通そうやろ」
ハスケル子「それがElmの場合は違うんですよ」
Elmの場合
c = a + b
a = 3
b = 5
ハスケル子「↑これも普通にOKです」
ワイ「ええ・・・」
ワイ「a
やb
を定義するより上の行で」
ワイ「a
やb
を計算に使ってるやん・・・」
ハスケル子「はい」
ハスケル子「関数と同じ感じなんですよ」
ワイ「ああ・・・」
ワイ「JSでも関数はそうやもんな」
ワイ「下の方で宣言した関数、上の方で使えるもんな」
ハスケル子「はい」
ハスケル子「Elmでは全ての値が不変なので、それが可能なんです」
ワイ「全ての値が不変・・・つまり再代入という概念が存在しないということやろ?」
ワイ「それやと順番が関係なくなるの?」
ワイ「なんで・・・?」
ハスケル子「JSの場合は───」
let a = 3;
console.log(a);
// 3 と表示。
a = 5;
console.log(a);
// 5 と表示。
ハスケル子「let a = 3;
って書いて」
ハスケル子「そのすぐ下の行でa
を呼び出したら、a
の値は3
だけど」
ハスケル子「その後、a = 5;
って再代入して」
ハスケル子「その下の行でa
を呼び出したら、a
の値は5
」
ワイ「それは分かるわ」
ワイ「当然の時間の流れや」
ハスケル子「でも再代入という概念がないとしたらどうですか?」
ワイ「ああ・・・」
ワイ「再代入できひんなら、a
はいつでも3
や」
ワイ「a
の状態が変わることが無いから」
ワイ「a
を5
に変えた後に呼び出したらどうこう・・・」
ワイ「みたいな話がそもそもあり得へんわけやな」
ハスケル子「そうです」
ハスケル子「全ての値が不変で」
ハスケル子「時間が止まってるようなものなので」
ハスケル子「コードの中に前とか後とか無いイメージです」
ワイ「なるほどなー」
ワイ「時が止まってるような」
ワイ「1フレームの中で全てが実行されているような」
ワイ「不思議な感じやな」
ワイ「スタープラチナ・ザ・ワールドみたいやな」
ハスケル子「オラオラオラオラ!って感じです」
ワイ「痛い!痛い!」
ワイ「やめてぇや」
ワイ「ええと、つまり」
ワイ「時間が止まっとるようなもんやから」
ワイ「値の定義より上の行で、その値を使っても」
ワイ「問題ないんやな」
ハスケル子「そんな感じです」
ワイ「でも、なんの値も変えられなくて」
ワイ「この言語、何ができるの・・・?」
ハスケル子「普通にシングルページアプリケーションとか」
ハスケル子「動きのあるゲームだって作れますよ」
ワイ「えぇ・・・!?」
ワイ「全て不変のはずやのにボール動いてますやん・・・!」
ワイ「言うてることちゃいますやん・・・!」
ハスケル子「気になるならElm Guide読んでみてください」
ハスケル子「じゃあ」
ハスケル子「次はオブジェクトとかイベントハンドラについて比べてみましょう」
〜後編に続く〜
後編も書いたで!
→ JavaScriptとElmを比べてみた〜後編・Vue.jsとも比べてみた〜
-
詳しくは後編にて。 ↩