Perlで継続
30分プログラム、その49。404 Blog Not Found:perl - to goto or not to goto, that's the continuationによるとPerlでも"本当の継続"が使えるらしいので、試してみる。
この記事は、
という意味らしい。決して、call/ccが書ける、という意味ではない。
use strict; use warnings; sub ident{ @_; } sub length_cps(&@){ my ($k,$x,@xs) = @_; unless($x){ $k->(0); }else{ @_ = (sub{$k->(1+shift)},@xs); goto &length_cps; # &length_cps(sub{ $k->(1+shift) },@xs); } } sub fact_cps(&$){ my ($k,$n) = @_; if($n == 0){ $k->(1) }else{ @_ = (sub{ $k->($n*shift)},$n-1); goto &fact_cps; # &fact_cps(sub{ $k->($n*shift) },$n-1); } } sub reverse_cps(&@){ my ($k,$x,@xs) = @_; unless($x){ $k->(()); }else{ @_ = (sub{ $k->(@_,$x)},@xs); goto &reverse_cps; # &reverse_cps(sub { $k->(@_,$x) } , @xs); } } print length_cps(\&ident,(1,2,3,4)),"\n"; print fact_cps(\&ident,5),"\n"; print reverse_cps(\&ident,(1,2,3,4)),"\n";
- scalar(@_)でlengthは書けるよ、というツッコミは禁止
- ベンチマークしないとよさがわからないね
- $kをレキシカル変数にしなくて、はまった。ちゃんとuse strictはつけましょう