Groovyラムダ化計画の挫折
おとうさん、ぼくにもYコンビネータがわかりましたよ!を読んで試しているうちに、なぜか意識が明後日へと飛んでしまいました。…なんかこれ、プロパティーチェーンに見えない?
プロパティの連鎖ならgroovyが理解出来ます。理解出来れば実行もできるやん!てことで、
def parrot = λx.x assert parrot(1) == 1 assert parrot(2) == 2
とかGroovyConsoleに打ち込んで、実行出来そうな気がして来たんです。
もちろん「λx」もそのプロパティ「x」も未定義ですが、そこはそれ、propertyMissingメソッドがあります。で、やってみました。
import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; class Lambda { private static ENGINE = new ScriptEngineManager().getEngineByName("groovy"); def arg def propertyMissing(String name) { if (name.startsWith('λ')) { return new Lambda(arg:"$arg, ${name.substring(1)}") } else { ENGINE.eval("{$arg->$name}") } } } def propertyMissing(String name) { if (name.startsWith('λ')) { return new Lambda(arg:name.substring(1)) } else { throw new MissingPropertyException(name, getClass()) } } def parrot = λx.x println (parrot(1))
これで、なんと!ちゃんと1て出力されます。もちろん
println (parrot(2))
なら2て出力されます!
とまぁ、出来たのはここまで。「(λx.λy.x)(0)(1)」なんかは出来なくて、
def TRUE = λx.λy.x def FALSE = λx.λy.y println (TRUE(0,1)) println (FALSE(0,1))
と2引数のクロージャになってしまったり、
λx.x+1
や
λx.λy.x+y
など演算子が入る場合は、無理やりプロパティにするために
println ((λx.'x+1')(1)) println ((λx.λy.'x+y')(1,2))
と文字列で書いてやらないといけません。
うーん、おしい!…けど、まぁクロージャで代用出来るのでいいか、と途中で飽きてしまったのでした。