2012-04-05 9 views
5

Me pregunto si hay una manera de implementar una funcionalidad genérica de "memoize" (como en una función con una función como entrada y una función como salida, como decoradores de python) capaz de manejar también cps funciones de estilomemoise continuation passing style function

para una función normal (como en "el valor del resultado regresa por el retorno, los parámetros son sólo para la entrada!") Una función memoize puede ser tan simple como (en javascript)

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; 
    }; 
} 

pero una función de estilo cps no puede ser memorizada por mi función simple memoize, porque necesito evaluar "nuevamente" los argumentos de la función de tipo, conociendo también el parámetro para pasarlos.

Por ejemplo, dada la función

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

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

tal vez pueda encontrar que next es una función, pero su firma (bueno ... tal vez, pero es complicado), y definitivamente no los parámetros utilizados en el ¡función!

¿Alguien me puede decir que estoy equivocado? : D

Me interesa poder memorizar media docena de funciones de estilo cps y no quiero meterme con la lógica insertando un "caché" en cada una de ellas.

+0

si pasa una tabla hash como argumento de su función (definiendo n-pares de clave: valores) simplemente haría la lógica para su propósito? – fcalderan

+0

no es tan simple: estoy usando funciones cps-style porque estoy tratando con una llamada ajax: el continueIfTrue/continueIfFalse no son llamadas directamente por mis funciones, son registradas como devoluciones de llamada y son llamadas por el navegador cuando la respuesta regresa. No puedo ver cómo el uso de una tabla hash puede ayudarme (tal vez estoy solo a ciegas: ¡D ilumínalo!). –

Respuesta

2

Soy nuevo en CPS, pero creo que tendrá que construir sus funciones de una manera particular.

Sus funciones de CPS tienen la siguiente estructura (generalizar a partir de su ejemplo):

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

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

lo tanto, usted podría utilizar su memoizer estándar, y la construcción de la función CPS también. Teniendo esto separada para el bien de ella, en primer lugar el CPS-fabricante (supone el último argumento a favor de las funciones es siempre la función para pasar a):

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); 
      } 
} 

Y entonces el memoizer se puede utilizar en conjunción con él:

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

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

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

El punto es separar la memorización de la transformación de la construcción de CPS.

Gracias por introducir la idea de CPS memorable; incluso si esta respuesta es basura, ¡me ha abierto los ojos!

0

Existe una manera tan genérica para hacerlo, que se presenta here en F #.

Cuestiones relacionadas