Drkcore

06 03 2011 javascript Tweet

Javascriptで末尾最適化関数

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

ってエラーが出るのだが理由がよくわからん。

k_ define error


静岡ではJava Script The Good Patsの読書会をしています。興味があれば気軽に参加を。

ProductName JavaScript: The Good Parts ―「良いパーツ」によるベストプラクティス
Douglas Crockford
オライリージャパン / 1890円 ( 2008-12-22 )


About

  • もう5年目(wishlistありマス♡)
  • 最近はPythonとDeepLearning
  • 日本酒自粛中
  • ドラムンベースからミニマルまで
  • ポケモンGOゆるめ

Tag

Python Deep Learning javascript chemoinformatics Emacs sake and more...

Ad

© kzfm 2003-2021