¿Clojure tiene continuaciones / corutinas / etc?

20

Comencé a programar con Python, y estaba realmente confundido por conceptos como las rutinas y los cierres.

Ahora creo que los conozco en un nivel superficial, pero nunca he sentido ese momento de "iluminación", así que elijo aprender Clojure. Compré el libro de Stuart Halloway y está bueno, pero cuando miré el índice no había palabras como rutina o continuación. Los busqué en Google, pero tampoco hay nada allí.

Entonces, mi pregunta es:

¿Clojure tiene continuaciones o rutinas para realizar tareas como ping-pong sin desbordamiento de pila?

Ejemplo de Python (aunque Python estándar no admite una versión con todas las funciones de esta rutina simétrica):

def ping():
  while 1:
   print "ping"
   function to switching to pong

def pong():
  while 1:
   function to switching to ping
   print "pong"
Principiante
fuente

Respuestas:

20

Clojure no tiene llamada / cc, pero de todos modos no desea continuar sin delimitar .

Argumentamos en contra call/cccomo una característica central del lenguaje, como la operación de control distinguida para implementar nativamente relegando a todos los demás a las bibliotecas. Lo primitivo call/cces una mala abstracción , en varios significados de 'malo' que se muestra a continuación, y su captura de la continuación de todo el programa no es prácticamente útil. La única recompensa por el arduo trabajo para capturar toda la continuación de manera eficiente es el trabajo más duro para evitar la captura de toda la continuación. Tanto los usuarios como los implementadores están mejor atendidos con un conjunto de primitivas de control bien elegidas de varios grados de generalidad con interacciones bien pensadas ...

... Ofrecer call/cccomo una función de control central en términos de los cuales se deben implementar todas las demás instalaciones de control resulta una mala idea. Rendimiento, pérdidas de memoria y recursos, facilidad de implementación, facilidad de uso, facilidad de razonamiento, todos argumentan en contra call/cc. Si realmente hay una característica de control distinguida para implementar como primitiva, con otras relegadas a bibliotecas, no es así call/cc.

David Nolen escribió una biblioteca de continuaciones delimitadas para Clojure. ¡Pruébalo!

delimc

Una biblioteca de continuaciones delimitadas para Clojure 1.4.0 (y 1.3.0). Porciones basadas en cl-cont de Slava Akhmechet ( http://defmacro.org ) ...

Frank Shearar
fuente
2

Si bien Clojure no tiene continuas o corutinas de primera clase integradas como característica principal, es posible implementar las suyas propias.

Por ejemplo, core.async es una biblioteca Clojure que implementa el modelo CSP (Procesos secuenciales concurrentes). Utiliza una gomacro para transformar el código dentro de una máquina de estados. Si bien no son exactamente corutinas per se, se pueden usar para implementar los mismos patrones.

También hay pulley.cps , un compilador de macros que he creado que transforma el código Clojure (a través de cps/ cps-fnmacros) escrito en estilo directo en estilo de paso continuo. Que yo sepa, es el programa Clojure con el tema de continuación más completo. Admite enlaces dinámicos, excepciones, llamadas de ida y vuelta entre código nativo y transformado (aunque la continuación no se mantiene en todos los contextos). Por el momento, solo call-ccse admiten continuaciones abortivas (es decir, tradicionales ), pero tengo planes para implementar continuaciones delimitadas en el futuro.

Si bien pulley.cps no proporciona directamente corutinas per se, call-cces relativamente sencillo implementar las suyas propias. De hecho, uno de los ejemplos es una implementación simple de la multitarea cooperativa . Esto se basa en el ejemplo de CSP . También hay un ejemplo de Ping-Pong , pero es más un ejemplo de optimización de cola que las rutinas.

Por supuesto, este tipo de transformaciones son más efectivas cuando se aplican a todo el programa. Desafortunadamente, esto no es posible solo con macros, que están localizadas. Aún así, incluso las transformaciones localizadas pueden ser muy efectivas.

Nathan Davis
fuente
1

¿Clojure tiene continuaciones o rutinas para realizar tareas como ping-pong sin desbordamiento de pila?

Antigua pregunta, así que ni siquiera estoy seguro de si esta función estaba disponible en ese momento, pero para cualquiera que quiera implementar algún tipo de funcionalidad de "ping-pong", ¡revise el trampolín !

Lo acabo de descubrir como respuesta a mi pregunta sobre el estilo eficiente de paso de continuación en Clojure, aquí: /programming/50952443/continuation-passing-style-does-not-seem-to-make-a -difference-in-clojure / 50955276 # 50955276 y creo que es solo el trabajo. Lo había escuchado hace un tiempo, pero nunca investigé completamente. Más me engañan. A diferencia de muchas de las otras soluciones propuestas, simplemente funciona .

====== PS. Un montón de información tutorial en línea,] aquí hay algunos que encontré útiles

alex gian
fuente
1
¿Quizás vincular el trampolín para señalar la documentación?
esoterik