複雑になってきましたがもう少し辛抱してください。先頭のconsを展開すると以下のようになります。...)b1はincの引数nの最下位ビットで、0なら`ki、1ならkです。...)となり、これがincの結果になります。b24]になったので、元の数より1大きい数になっていることがわかります。次にb1がkの場合を考えます。incRec)となり、これは最下位ビットが`kiつまり0で、2番目以降のビット列をintRecで1加算したもの、つまり繰り上がりの処理です。こちらも元の数に1を足した結果になることがわかります。これで大体うまくいきそうですが、再帰の終了条件らしきものがありません。nのすべてのビットが1だった場合何が起こるのでしょうか?リストの終端はvを使って表すのでした。incRec)はvですからそれ以上の再帰は起こらず、結果として24個の要素すべてが`kiのリスト、つまり数値0が返ります。このように、ちょっとトリッキーでしたがちゃんと24ビット整数に1を加える処理になっていることがわかります。メモリELVMは24ビットアドレスのメモリ空間を持ち、各アドレスには24ビットの数値を格納できます。メモリもペアを使って表現しますが、今度はリストではなく2分木を使います。メモリ全体は高さ24の完全2分木になります。メモリを参照するときはアドレスを1ビットずつ見ていき、0なら左の子、1なら右の子を辿っていきます。メモリに値を格納するときは、根から対象アドレスの経路にあるノードのみが書き換えられ、他のノードは再利用されるのでそれほど効率は悪くありません。関数型データ構造というやつですね。ちなみに初期化時のメモリは左の子と右の子が同じノードを指すDAGになっていて、値が書き込まれた部分だけが本当の2分木になります。多くのプログラムはメモリを目一杯使わないので、これでUnlambdaインタプリタの消費メモリ量を節約できます。Unlambdaバックエンド実装の下準備として、様々なデータ構造を関数のみを使って実現する方法を解説しました。inc関数の処理を詳しく見ることで、すべてが関数であるUnlambdaでプログラミングするときの雰囲気を感じていただけたと思います。明日の後編ではいよいよUnlambdaバックエンドの実装を見ていきます。