¿Qué es un ejemplo de una continuación no implementada como un procedimiento?

15

Un interesante acerca de la distinción entre devoluciones de llamada y continuations sobre SO ha hecho esta pregunta. Por definición, una continuación es una representación abstracta de la lógica necesaria para completar un cálculo. En la mayoría de los idiomas, esto se manifiesta como un procedimiento de un solo argumento al que le pasa cualquier valor que necesite un procesamiento continuo.

En un lenguaje puramente funcional (donde todas las funciones son ciudadanos puros y de primera clase), creo que una continuación podría modelarse completamente como una función. Esto es, después de todo, cómo he entendido previamente las continuaciones hasta este punto. Sin embargo, el mundo está lleno de estado (suspiro ...) y, por lo tanto, la definición general no requiere que el programa de captura de continuación esté, solo necesita abarcar la intención.

Para ayudarme a comprender, ¿se puede proporcionar un ejemplo en un lenguaje funcional donde la continuación se exprese de una manera más abstracta que una función? Sé que Scheme le permite capturar la continuación actual de una manera de primera clase (call / cc), pero aun así, parece que el procedimiento de un argumento pasado a call / cc simplemente recibe la continuación actual en la forma de otro procedimiento de argumento al que la función call / cc'd puede aplicar su resultado.

    
pregunta David Cowden 20.09.2013 - 10:29
fuente

2 respuestas

11

tl; dr; El tipo es la abstracción general sobre una continuación

Una continuación es el tipo de sus entradas y salidas

Lo más cercano que encontrará a una continuación no basada en procedimientos es probablemente la mónada de continuación en Haskell como se expresa como un tipo, para el cual se pueden usar muchas funciones para interactuar con el tipo para interrumpir, reanudar, retroceder, etc.

Puedes encapsular ese cierre en un tipo como el tipo Cont en Haskell, donde obtienes la abstracción de mónada como una "abstracción de nivel superior", y hay otras formas de abstracción sobre las continuaciones que obtienes cuando miras el continuación como tipo en lugar de simplemente procedimiento , por ejemplo

  • Puede tomar dos continuaciones y hacer una alternativa entre ellas si el tipo sigue las leyes para ser un monoide
  • Puede abstraerse sobre el tipo para cambiar los tipos de entrada o salida de la continuación si encapsula el cierre en un tipo que respeta las leyes de a functor
  • Puede aplicar o decorar de manera arbitraria y parcial su continuación con funcionalidades como la validación de entrada o la conversión de entrada si encapsula el cierre en un tipo que sigue las leyes de funtor aplicativo

Cierre vs. Procedimiento

Al final del día básicamente tienes razón; una continuación es un "procedimiento", aunque prefiero referirme a él como un cierre. A menudo, las continuaciones se expresan mejor como cierres de primera clase que han encerrado un entorno vinculado. En un lenguaje funcional puro, podría decir que esto no es particularmente razonable porque carece de referencias; esto es cierto, pero puede incluir valores y la asignación simple hace que la inclusión del valor y la referencia sea exactamente lo mismo. Esto da lugar a en Haskell:

(\x -> \y -> insideYIcanAccess x (and y))

Un lenguaje que carece de la capacidad de encerrar un entorno vinculante puede carecer técnicamente de cierres de primera clase, pero incluso entonces hay un entorno en algunos (generalmente el global) que está disponible para el cierre.

Por lo tanto, diría que es más preciso describir una continuación como: Un cierre que se usa de una manera particular.

Conclusión

A la pregunta de "¿Se puede implementar una continuación de otra manera que no sea un procedimiento?" No. Si no tiene funciones de primera clase realmente no puede tener continuaciones como tales (los punteros de función sí cuentan como funciones de primera clase, por lo que, como alternativa, el acceso de memoria arbitrario puede ser suficiente).

Ahora, con la pregunta de "¿Hay alguna manera de expresar una continuación de una manera más abstracta que un procedimiento?" Expresarlo como un tipo le da una abstracción mucho mayor, permitiéndole tratar la continuación de formas muy generales, de modo que puede interactuar con la continuación de muchas más formas que solo ejecutándola.

    
respondido por el Jimmy Hoffa 20.09.2013 - 17:20
fuente
2

Un ejemplo que podría gustarte son las coroutinas. Por ejemplo, los Coroutines de Lua o los iteradores / generadores de Python o C # son similares en potencia a las continuaciones de un disparo (continuaciones a las que solo puedes llamar una vez), pero la continuación no se convierte explícitamente en una función. En su lugar, tiene formas de hacer avanzar la rutina hasta la próxima declaración de "rendimiento".

Por ejemplo, considera el siguiente programa de Python:

def my_iterator():
   yield 1
   yield 2
   yield 3

def main():
   it = my_iterator()
   x = it.next()
   y = it.next()
   z = it.next()
   print x + y + z

Es similar al siguiente programa de Javascript con devoluciones de llamada explícitas:

function my_iterator()
  return function(cb1){
    cb1(1, function(cb2){
      cb2(2, function(cb3){
        cb3(3, function(cb4){
          throw "stop iteration";
        });
      });
    });
  });
}

function main(){
   var getNext1 = my_iterator();
   getNext1(function(x, getNext2){
      getNext2(function(y, getNext3){
         getNext3(function(z, getNext4){
            console.log(x + y + z);
         });
      });
   });
}

El ejemplo de Javascript es un poco ruidoso porque cada paso debe devolver la siguiente continuación además de devolver el valor generado (en Python realiza un seguimiento de la continuación dentro del ite

    
respondido por el hugomg 21.09.2013 - 02:58
fuente