2012-04-05 15 views
5

Ich frage mich, ob es eine Möglichkeit gibt, ein generisches "Memoize" -Funktional (wie in einer Funktion mit einer Funktion als Eingabe und eine Funktion als Ausgabe, als Python-Dekoratoren) in der Lage, auch cps zu verarbeiten -Stil-Funktionen.Memoize Fortsetzung Stilfunktion übergeben

für eine normale Funktion (wie in „der Ergebniswert durch die Rückkehr zurückkommt, sind die Parameter nur für die Eingabe!“) Eine memoize Funktion als (in JavaScript) kann so einfach sein

function memoize(fun) { 
    var cache = {}; 
    return function() { 
     var args = Array.prototype.slice.call(arguments); 
     if (args in cache) 
      return cache[args]; 
     var ret = fun.apply(this, arguments); 
     cache[args] = ret; 
     return ret; 
    }; 
} 

aber Eine cps-style-Funktion kann nicht durch meine einfache memoize-Funktion gespeichert werden, weil ich "wieder" die Argumente des Typs function auswerten muss, wobei ich auch die Parameter kenne, die an sie übergeben werden sollen.

Zum Beispiel angesichts der Funktion

function cps(param, next) { 
    var ret = param + 1; 

    // setTimeout for simulate async behaviour 
    setTimeout(function() { 
      next(ret); 
    }, 0); 
} 

vielleicht kann ich die next finde, ist eine Funktion, aber seine Unterschrift (gut ... vielleicht, aber es ist schwierig), und auf jeden Fall nicht die in dem verwendeten Parameter Funktion!

Kann mir jemand sagen, dass ich falsch liege? : D

Ich bin daran interessiert, in der Lage zu sein, ein halbes Dutzend von cps-style-Funktionen zu merken, und ich möchte nicht mit der Logik durcheinander bringen einen "Cache" in jedem von ihnen einfügen.

+0

Wenn Sie eine Hashtabelle als Argument Ihrer Funktion übergeben (Definieren von n-Schlüsselpaaren: Werten), würde dies die Logik für Ihren Zweck vereinfachen? – fcalderan

+0

es ist nicht so einfach: Ich benutze cps-style-Funktionen, weil ich mit Ajax-Aufruf beschäftigen: die continueIfTrue/continueIfFalse werden nicht direkt von meinen Funktionen aufgerufen, als Callbacks registriert und vom Browser aufgerufen, wenn die Antwort zurückkam. .. Ich kann nicht sehen, wie die Verwendung einer Hashtabelle mir helfen kann (vielleicht bin ich nur blind: D mich erleuchten!). –

Antwort

2

Ich bin neu bei CPS, aber ich denke, dass Sie Ihre Funktionen in einer bestimmten Weise konstruieren müssen.

Ihre CPS-Funktionen haben die folgende Struktur (aus Ihrem Beispiel zu verallgemeinern):

function cps(param, next) { 
    var ret = someFunctionOfParam(param); 

    // setTimeout for simulate async behaviour 
    setTimeout(function() { 
     next(ret); 
    }, 0); 
} 

Also, Sie könnten Ihren Standard memoizer, verwenden und die CPS-Funktion als auch konstruieren. Halten Sie diese getrennt im Interesse der es zunächst die CPS-Hersteller (einnimmt das letzte Argument für die Funktionen ist immer die Funktion zu übergeben):

function cpsMaker(transformFunc) { 
    return function() { 
       var args = Array.prototype.slice.call(arguments); 
       var next = args.pop(); // assume final arg is function to call 
       var ret = transformFunc.apply(this,args); 
       // setTimeout for simulate async behaviour 
       setTimeout(function() { 
        next(ret); 
       }, 0); 
      } 
} 

Und dann kann die memoizer in Verbindung mit diesem verwendet werden:

function plusOne(val) { 
    return val+1; 
} 

var memoPlusOne = memoize(plusOne); 
var cpsMemPlusOne = cpsMaker(memoPlusOne); 

cpsMemPlusOne(3,function(n){console.log(n)}); 

der Punkt ist, die memoization der Transformation von der CPS Konstruktion zu trennen.

Vielen Dank für die Einführung der Idee von Memoized CPS; Auch wenn diese Antwort Unsinn ist, war es für mich eine Augenöffner!

0

Es gibt so eine generische Möglichkeit, dies zu tun, die in F # here präsentiert wird.