Bien que Clojure n'ait pas de continuations ou de coroutines de première classe intégrées en tant que fonctionnalité de base, il est possible d'implémenter les vôtres.
Par exemple, core.async est une bibliothèque Clojure qui implémente le modèle CSP (Concurrent Sequential Processes). Il utilise une go
macro pour transformer le code qu'il contient en une machine à états. Bien qu'il ne s'agisse pas exactement de coroutines en soi, il peut être utilisé pour implémenter les mêmes modèles.
Il y a aussi pulley.cps , un compilateur de macros que j'ai créé qui transforme (via cps
/ cps-fn
macros) le code Clojure écrit en style direct en style passant par la continuation. À ma connaissance, il s'agit du programme Clojure sur le thème de la continuation le plus complet. Il prend en charge la liaison dynamique, les exceptions, les appels entre le code natif et le code transformé (bien que la continuation ne soit pas maintenue dans tous les contextes). Pour le moment, seules les suites abortives (c'est-à-dire traditionnelles call-cc
) sont prises en charge, mais j'ai des plans pour mettre en œuvre des suites délimitées à l'avenir.
Bien que pulley.cps ne fournisse pas directement de coroutines en soi, call-cc
il est relativement simple de mettre en œuvre la vôtre. En fait, l'un des exemples est une simple mise en œuvre du multitâche coopératif . Ceci est développé dans l' exemple CSP . Il y a aussi un exemple Ping-Pong , mais c'est plus un exemple d'optimisation des appels de queue que des coroutines.
Bien entendu, ces types de transformations sont plus efficaces lorsqu'elles sont appliquées à l'ensemble du programme. Malheureusement, cela n'est pas possible avec les macros seules, qui sont localisées. Pourtant, même des transformations localisées peuvent être très efficaces.