06 03 2011 javascript Tweet
Javascript The Good Partsの4章の最後にメモ化関数があるので、末尾最適化関数を書かねばならんだろうと。
Function.prototype.tail = function () {return [this, arguments];}; Function.prototype.call_with_tco = function () { var c = [this, arguments]; var escape = arguments[arguments.length-1]; while(c[0] !== escape) c = c[0].apply(this, c[1]); return escape.apply(this,c[1]); }; var tcoptimizer = function (f) { var s = f.toString(); var t = s.match(/function\s+\((.+?)\)\s+{\s+(.+)\?\s+(.+?)\((.+?)\)\s+:\s+([a-zA-Z_]+)/); var f_str = "var func_ = function (" + t[1] + ", k_) { " + t[2] + " ? func_.tail(" + t[4] + ", k_) : k_.tail(" + t[5] +");};"; eval (f_str); return func_; }; var id = function (x) {return x;}; var sum = function (n,acc) { return n > 0 ? sum(n-1,acc+n) : acc;}; //console.log(sum(10000,0)); console.log(tcoptimizer(sum).call_with_tco(10000,0,id));
firebugでfunctionで始まる文字列をevalしたらSyntaxエラーになったのでvarからevalしてある。これは謎だがとりあえず動くようになった。しかしid関数とcall_with_tcoメソッドがちょっとよろしくないのでラップしてみる。
var tcopt = function (f) { var id = function (x) {return x;}; var func_ = tcoptimizer(f); return function() { var slice = Array.prototype.slice; var args = slice.apply(arguments); args.push(id); return func_.call_with_tco(args); }; }; var sum = function (n,acc) { return n > 0 ? sum(n-1,acc+n) : acc;}; //console.log(sum(10000,0)); var tco_sum = tcopt(sum); console.log(tco_sum(100,0));
すると
TypeError: k_ is undefined
ってエラーが出るのだが理由がよくわからん。
静岡ではJava Script The Good Patsの読書会をしています。興味があれば気軽に参加を。