Hat Clojure Fortsetzungen / Koroutinen / etc?

20

Ich fing an, mit Python zu programmieren, und war wirklich verwirrt von Konzepten wie Coroutinen und Closures.

Jetzt denke ich, dass ich sie auf einer oberflächlichen Ebene kenne, aber ich habe diesen Moment der "Erleuchtung" nie gespürt, deshalb entscheide ich mich, Clojure zu lernen. Ich habe das Buch von Stuart Halloway gekauft und es ist gut, aber als ich mir den Index ansah, gab es keine Wörter wie Coroutine oder Fortsetzung. Ich habe sie gegoogelt, aber da ist auch nichts.

Meine Frage lautet also:

Verfügt Clojure über Fortsetzungen oder Coroutinen, um Aufgaben wie Ping-Ponging ohne Stapelüberlauf auszuführen?

Python-Beispiel (obwohl Standard-Python keine Vollversion dieser symmetrischen Coroutine unterstützt):

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

def pong():
  while 1:
   function to switching to ping
   print "pong"
Anfänger
quelle

Antworten:

20

Clojure hat kein call / cc, aber Sie wollen sowieso keine unbegrenzten Fortsetzungen .

Wir sprechen uns dagegen aus, call/ccals Kern-Sprachmerkmal die aufstrebende Steuerungsoperation zu implementieren, um alle anderen nativ in Bibliotheken zu relegieren. Das Primitiv call/ccist eine schlechte Abstraktion - in verschiedenen Bedeutungen von "schlecht", wie unten gezeigt - und seine Erfassung der Fortsetzung des gesamten Programms ist praktisch nicht nützlich. Die einzige Belohnung für die harte Arbeit, um die gesamte Fortsetzung effizient zu erfassen, ist mehr harte Arbeit, um die Erfassung der gesamten Fortsetzung zu umgehen. Sowohl den Benutzern als auch den Implementierern wird eine Reihe gut ausgewählter Steuerelemente mit unterschiedlichem Generalitätsgrad und durchdachten Interaktionen besser gedient ...

... Das Anbieten call/ccals zentrales Steuerungsmerkmal, in Bezug auf das alle anderen Steuerungsfunktionen implementiert werden sollen, ist eine schlechte Idee. Performance-, Speicher- und Ressourcenlecks, einfache Implementierung, einfache Verwendung und einfache Argumentation sprechen dagegen call/cc. Wenn es wirklich ein einzigartiges Steuerungsmerkmal gibt, das als Grundelement implementiert werden kann, während andere in Bibliotheken verbannt werden, ist dies nicht der Fall call/cc.

David Nolen hat eine begrenzte Fortsetzungsbibliothek für Clojure geschrieben. Versuch es!

delimc

Eine abgegrenzte Fortsetzungsbibliothek für Clojure 1.4.0 (und 1.3.0). Teile basierend auf cl-cont von Slava Akhmechet ( http://defmacro.org ) ...

Frank Shearar
quelle
2

Obwohl in Clojure keine erstklassigen Fortsetzungen oder Coroutinen als Kernfunktion integriert sind, ist es möglich, eigene zu implementieren.

Zum Beispiel core.async ist eine Clojure Bibliothek , dass Geräte die CSP (Concurrent Sequential Processes) Modell. Es verwendet ein goMakro, um den Code in eine Zustandsmaschine umzuwandeln. Es ist zwar an sich keine exakte Koroutine, kann jedoch verwendet werden, um dieselben Muster zu implementieren.

Es gibt auch pulley.cps , einen von mir erstellten Makrocompiler , der (via cps/ cps-fnmacros) Clojure-Code, der direkt geschrieben wurde, in einen Stil umwandelt, der die Fortsetzung übergibt. Nach meinem besten Wissen handelt es sich um das umfassendste Clojure-Programm zum Thema Fortsetzung. Es unterstützt dynamische Bindungen, Ausnahmen und das Hin- und Herwechseln zwischen nativem und transformiertem Code (obwohl die Fortsetzung nicht kontextübergreifend beibehalten wird). Momentan werden nur abortive (dh traditionelle call-cc) Fortsetzungen unterstützt, aber ich habe vor, in Zukunft begrenzte Fortsetzungen zu implementieren.

Während pulley.cps an sich keine Coroutinen direkt bereitstellt, call-ccist es relativ einfach, Ihre eigenen zu implementieren. In der Tat ist eines der Beispiele eine einfache Implementierung von kooperativem Multitasking . Darauf baut das CSP- Beispiel weiter auf. Es gibt auch ein Ping-Pong- Beispiel, aber es ist eher ein Beispiel für die Tail-Call-Optimierung als für Coroutinen.

Natürlich sind diese Arten von Transformationen am effektivsten, wenn sie auf das gesamte Programm angewendet werden. Leider ist dies nicht nur mit lokalisierten Makros möglich. Dennoch können auch lokalisierte Transformationen sehr effektiv sein.

Nathan Davis
quelle
1

Verfügt Clojure über Fortsetzungen oder Coroutinen, um Aufgaben wie Ping-Ponging ohne Stapelüberlauf auszuführen?

Alte Frage, daher bin ich mir nicht mal sicher, ob diese Funktion zu der Zeit verfügbar war, aber für alle, die irgendeine Art von "Ping-Pong" -Funktionalität implementieren möchten, sollten Sie das Trampolin ausprobieren !

Ich habe es gerade als Antwort auf meine Frage zu einem effizienten Continuation-Passing-Stil in Clojure entdeckt: /programming/50952443/continuation-passing-style-does-not-seem-to-make-a -difference-in-clojure / 50955276 # 50955276 und ich denke, es ist nur der Job. Ich hatte vor einiger Zeit davon gehört, es aber nie vollständig untersucht. Mehr täuschen mich. Im Gegensatz zu vielen anderen vorgeschlagenen Lösungen funktioniert es einfach .

====== PS. Viele Tutorial-Informationen online,] hier sind ein paar, die ich als nützlich empfunden habe

alex gian
quelle
1
Vielleicht Trampolin verlinken , um auf die Dokumentation zu verweisen?
Esoterik