Erlangでたらい回し 遅延評価版

closure を使えば遅延評価できるとな。

λ萌え - たらいを後回し
実は、closureをサポートしている言語であれば、遅延評価は可能だったりする。明示的にやらなければならないものの、それを明示するのは実に簡単だ。
まず、遅延評価したい値は、ただclosureでくるめばいい。

http://blog.livedoor.jp/dankogai/archives/50829735.html

てことでやってみた。

ltak(X, Y, Z) ->
    XX = X(),
    YY = Y(),
    if XX =< YY -> YY;
       true     ->
            ltak( fun() -> ltak( fun() -> X()-1 end, Y, Z ) end,
                  fun() -> ltak( fun() -> Y()-1 end, Z, X ) end,
                  fun() -> ltak( fun() -> Z()-1 end, X, Y ) end )
    end.

fun() -> xxx end が重なると、読みやすくはないな。
X(), Y() を代入(束縛) しているのは、if の条件式部分で X(), Y() を呼ぶと "illegal guard expression" というエラーになるので。

ベンチマーク結果。memoize 版より速い!

ltak(100, 50, 0) = 100 : time 9.64400 msec
tak_memoize(100, 50, 0) = 100 : time 75.8870 msec

# memoize版の作りが悪くて遅いのかもしれんが