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 go
macro 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-fn
macros) 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-cc
se 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-cc
es 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.