http://www.kmonos.net/wlog/52.php#_0212050903
を見て、ぎゃふん! と思ってから寝た。
寝ている間に、いやあれは目指しているところが違うからいいんじゃないかと思えてきた。
とはいえ、やっぱりちょっとぎゃふんと思っている。
思っているだけではつまらないので、C 言語版を作ってみた。相変わらず、memo はなし。fix だけ。
#include <stdio.h> typedef int (*func_t)(int); int fib_maker( func_t f, int x ){ return x<=1 ? 1 : f(x-1)+f(x-2);} #define FIX( name, maker ) int name( int x ){ return maker( name, x ); } FIX( fib, fib_maker ) void test(){ int i; for( i=0 ; i<10 ; ++i ) printf( "%d ", fib(i) );}
プリプロセッサに頑張ってもらった。それもまた C 言語。
すごく久しぶりに C を書いたので、for( int i; i<10 ; ++i ) の何が悪いのか気づくのに5分ぐらいかかってしまった。愚かなり。
昨日一昨日と書いた C++ 版は動的(fix は実行時に関数を作る)だが、こちらはマクロであることからもわかるとおり、静的(FIX はコンパイル時に関数を作る)。
C++ も「やればできる子」だが、template がなければ大したことのない言語なので、動的に解決するなら昨日のやり方は悪くないんじゃないかと思っている。
それと。
http://www.kmonos.net/wlog/52.php#_0212050903 に ruby がない。
折角だから書いておこう。
fib_maker = lambda{ |f| lambda{ |x| x<=1 ? 1 : f.call(x-1) + f.call(x-2) } } fix = lambda{ |maker| f = lambda{ |x| f.call(x) } f = maker.call( f ); } fib = fix.call( fib_maker ); (0..10).each{ |i| p fib.call(i); }
いや、こんなに lambda ばかりにする必要はないわけだが。
こうしてみると、 call を書かねばならないのがちょっと鬱陶しい。
java だと C言語 以上に書きにくいと思うがどうだろう。
で。
都合四つぐらい書いたわけだが、やっぱり根本的な部分が今ひとつわかってない気がする。数学の素養が不足しているのか、関数型の世界になじめていないのか。