JVMで高階関数

SchemeJVMコンパイルする話。

高階関数を実現するには、どうすれば良いのか考えた。

まず、通常のメソッド呼び出しを考えると、JVMアセンブラJasminのドキュメントによれば

invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V

とかやるらしい。これでは、呼ぶメソッドを事前に決めておかなくてはいけないので、話にならない。ドキュメントを見ていくと

goto 12

とかいう命令があるので、これを使えないかと思ったが、これもやっぱり引数をコンパイル時に決定しなくてはいけないので使えない。

まいった…と思って、思いついたのがF#。.NetCLRとJVMなら似たようなもんだろ。.NetのディスアセンブラReflectorを使って、F#のプログラムを見てみると、関数は関数を表現するクラスにコンパイルされている。*1なるほど、これは春くらいに見た覚えがあるぞ。というか、これを覚えてて「高階関数くらい実装しなよ」と学生さんに言ったときに、「関数をクラスにするんだよ」とかわかったようなわからないようなコメントをしたんだな、きっと…

クロージャ変換は並みの苦労じゃあできない」とは言うものの、ACのみなさんなら易々とこなしてくれるはず。がんばってもらおう。

*1:ちなみにただ呼び出すだけの関数はクラスのメソッドコンパイルされる