Pregunta

Esto está relacionado con ¿Cuál es llamada / cc? , pero yo no quería secuestrar a esta pregunta para mis propios fines, y algunos de sus argumentos como la analogía con setjmp / longjmp me evadir.

Creo que tengo una idea suficiente sobre lo que es una continuación, pienso en ella como una instantánea de la pila de llamadas actual. Yo no quiero entrar en la discusión por qué esto podría ser interesante o lo que puede hacer con continuaciones. Mi pregunta es, más concretamente, ¿por qué tengo que proporcionar un argumento de la función de llamar / cc? ¿Por qué no llama / cc acaba de regresar a la continuación actual, por lo que podía hacer lo que me plazca con ella (almacenarlo, lo llaman, lo que sea)? En un enlace desde esta otra pregunta ( http: // comunidad .schemewiki.org /? llamar-con-corriente de continuación para los programadores de C-), se habla de "Esencialmente es sólo una forma limpia para conseguir la continuación a usted y mantener fuera del camino de los saltos posteriores volver al punto de guardado. ", pero no lo estoy consiguiendo. Parece innecesariamente complicado.

¿Fue útil?

Solución 4

Contra común SO etiqueta de la red que estoy respondiendo a mi propia pregunta, sino más bien como el editor de que el proveedor de la respuesta.

Después de un tiempo empecé una pregunta similar sobre en LTU . Después de todo, estos son los chicos que ponderan el diseño de lenguajes durante todo el día, no son ellos, y uno de los respuestas finalmente patadas conmigo. Ahora las cosas mencionadas aquí, por ejemplo, por Eli o en la pregunta original, tiene mucho más sentido para mí. Es todo acerca de lo que se incluye en la continuación, y donde la continuidad aplicado establece en.

Una de las carteles en LTU escribieron:

  

"Se puede ver exactamente cómo llamar / cc le permite 'mantener fuera del camino.' Con ellos o conseguir / cc que tiene que hacer algún tipo de prueba para determinar si usted tiene una copia de salto o sólo la inicial llamar. Básicamente, llamada / cc mantiene el uso de la continuación de la continuación, mientras que con get / cc o em, la continuación contiene su uso y así (por lo general) es necesario agregar una prueba para el comienzo de la continuación (es decir, inmediatamente después de get / cc / em) para separar el "uso de las partes de continuación" del "resto de la continuación" partes ".

Esto condujo a casa para mí.

Gracias chicos de todos modos!

Otros consejos

Si utiliza una construcción como Jay muestra, a continuación, se puede agarrar la continuación, pero en cierto modo, el valor que se tomó ya está echado a perder porque ya continuación el interior que lo eres. Por el contrario, call/cc se puede utilizar para agarrar la continuación que es Todavía a la espera fuera de la expresión actual. Por ejemplo, uno de los usos más simples de continuaciones es implementar una especie de abort:

(call/cc (lambda (abort)
           (+ 1 2 (abort 9))))

No se puede hacer eso con la operación que usted describe. Si lo pruebas:

(define (get-cc) (call/cc values))
(let ([abort (get-cc)]) (+ 1 2 (abort 9)))

A continuación, se produce un error acerca de la aplicación 9 como un procedimiento. Esto sucede porque abort salta de nuevo a la let con el nuevo valor de 9 - lo que significa que usted ahora está haciendo una segunda ronda de la misma expresión Además, salvo que ahora está obligado a abort 9 ...

Dos notas relacionadas adicionales:

  1. Para una buena introducción práctica a continuaciones, ver PLAI .
  2. call/cc es un poco complejo en el que se necesita en una función - una construcción conceptualmente más fácil de usar es let/cc que se puede encontrar en algunas implementaciones como PLT Scheme. El ejemplo anterior se convierte en (let/cc abort (+ 1 2 (abort 9))).

Eso sería menos versátil. Si quieres que el comportamiento, sólo se puede hacer:

(call/cc (lambda (x) x))

Se puede echar un vistazo a los ejemplos de usos de las continuaciones de "Darrell Ferguson y Dwight Deugo. 'Llamada con Patrones de continuación a corto plazo'. 8ª Conferencia sobre Lenguajes de Patrones de Programas. De septiembre de 2001." ( http://library.readscheme.org/page6.html ) y tratar de volver a escribir utilizando una llamada / cc-retorno, que se define como anteriormente.

Sugiero comenzar por preguntarse: ¿qué significa ser una continuación de primera clase

?

La continuación de una expresión esencialmente consiste en dos piezas de datos: primera, el cierre (es decir, medio ambiente) de que la expresión; y en segundo lugar, una representación de lo que se debe hacer con el resultado de la expresión. Un lenguaje con continuaciones de primera clase, entonces, es uno que tiene estructuras de datos que encapsula estas partes, y que trata a estas estructuras de datos como lo haría con cualquier otro.

llamada / cc es una manera particularmente elegante para darse cuenta de esta idea: la continuación actual se empaqueta como un procedimiento que encapsula lo que-es-a-hacer--con-la-expresión como lo que el procedimiento no cuando se aplica a la expresion; para representar la continuación de esta manera simplemente significa que el cierre de este procedimiento contiene el medio ambiente en el lugar que fue invocada.

Se podría imaginar la realización de la idea de continuaciones de primera clase en otras formas. No se les llaman / cc, y es difícil para mí imaginar cómo una representación de este tipo podría ser más simple.

En una nota de despedida, considerar la aplicación de Let / cc que Eli se ha mencionado, que yo prefiero llamar a bind / cc:

(define-syntax bind/cc
    (syntax-rules ()
        ((bind/cc var . body)
             (call/cc (lambda (var) . body)))))

Y como un ejercicio, ¿cómo poner en práctica la llamada / cc basado en bind / cc?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top