前記事では、
3.add(2).add(10)
という式を解析し、式をオブジェクトで表現する「構文解析」について見てきました。
ところで、いまさらですが、普通「式」といったら、
3+2+10
と書くのが一般的なのに、なんで一般的でない書き方をしているのか、というと、
- 作るのが(&解説するのが)面倒
- この式の解析の仕方は他の方も解説されている
という身も蓋もない理由です。
一般的な「式」の解析方法については、上の検索欄で「構文解析」あるいは「構文解析 JavaScript」などで検索していただくとひっかかると思います。
本連載では、式の解析の仕組みはなるべく単純化して、その先のトピック、具体的に言うと型のチェックや、関数型言語ならではの機能を詳しく見てみたいと考えています。
3.add(2)はどう動くのか?
そもそも、3.add(2)
という式はJavaScriptでは動作しません。これを動かすには何らかの変換が必要になります。今回はまず、この変換を支援する「ランタイムライブラリ」について見ていきます。まず、lang/runtime.ts
を開いてみましょう。
interface INum {
value:number,
add:(b:INum)=>INum,
};
export const Num=(value:number):INum=>({
value,
add(b:INum):INum {
return Num(value+b.value);
},
});
これを使ってちょっと遊んでみます。
TypeScript playgroundを開いてみましょう。このリンクから開くと、すでにプログラムが書かれていると思います。
Runを押して実行してみると
LOG: {
"value": 5
}
という結果が出力されます。1
最後に書いてある式Num(3).add(Num(2))
で、計算を行っています。
-
INum
型のオブジェクトは,次のメンバをもちます-
value
(JavaScriptの数値) -
add
(他のINum型のオブジェクトをもらって,足し算した結果をINumオブジェクトで返す関数)
-
- 関数
Num
は,JavaScriptの数値n
からINum型のオブジェクトを生成します2.
つまり,今連載で扱う言語……言語になんか名前あったほうがいいですよね.リポジトリ名からとって「tinyfunc」とでもしましょうか.
tinyfuncで3.add(2)
と書かれたプログラムがあったら,Num(3).add(Num(2))
というJavaScript3を生成してあげればいい,ということになります.
というわけで,次回はそのJavaScriptコードを頑張って生成してみます.
理解度チェック
-
INum
オブジェクトに,引き算をするsub
,掛け算をするmul
,割り算をするdiv
を追加してみて,次の計算をINum
オブジェクトを使って行ってみましょう.- 20+30-5
- 50-10-20
- 50-(10-20)
- 204+302
- 20*(4+30)*2
- 100/10/2
- 100/(10/2)
-
本当は[LOG]って出てますがなぜか消えてしまったので[]は取っています ↩
-
class
使った方がシンプルなのになんで使わないの? と思った方へ.この後の実装の都合で,こちらのほうがやりやすいからです.詳しくは今後お話しますが,JSに詳しい方向けに先回りしておくと「object.f(a)
と(object.f)(a)
が同じ挙動になるようにしたいから」です. ↩ -
Num(3).add(Num(2))
はTypeScript上で書いたものであって,JavaScriptで動くのか? と思った方は,PlayGround上の右側で「JS」タブを選んで,JavaScriptに変換されたコードを確認してみましょう.同じコードが出力されていると思います. ↩