Czy Clojure ma kontynuacje / coroutines / etc?

20

Zacząłem programować w Pythonie i byłem bardzo zdezorientowany takimi pojęciami, jak coroutines i closures.

Teraz myślę, że znam ich na jakimś powierzchownym poziomie, ale nigdy nie czułem tego momentu „oświecenia”, więc wybrałem naukę Clojure. Kupiłem książkę Stuarta Hallowaya i jest dobra, ale kiedy spojrzałam na indeks, nie było słów takich jak „coroutine” czy „kontynuacja”. Przeszukałem ich, ale tam też nic nie ma.

Moje pytanie brzmi:

Czy Clojure ma kontynuacje lub coroutines do wykonywania zadań takich jak ping-pong bez przepełnienia stosu?

Przykład Python (chociaż standardowy Python nie obsługuje w pełni funkcjonalnej wersji tej symetrycznej coroutine):

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

def pong():
  while 1:
   function to switching to ping
   print "pong"
Nowicjusz
źródło

Odpowiedzi:

20

Clojure nie ma call / cc, ale i tak nie chcesz nieokreślonych kontynuacji .

Argumentujemy przeciwko call/ccjako podstawowej funkcji języka, jako wyróżniającej się operacji kontrolnej mającej na celu implementację natywnego przeniesienia wszystkich innych bibliotek do bibliotek. Prymityw call/ccto zła abstrakcja - w różnych znaczeniach „zła” pokazana poniżej - a uchwycenie kontynuacji całego programu nie jest praktycznie przydatne. Jedyną nagrodą za ciężką pracę, aby skutecznie uchwycić całą kontynuację, jest cięższa praca, aby obejść przechwycenie całej kontynuacji. Zarówno użytkownikom, jak i implementatorom lepiej służy zestaw dobrze dobranych prymitywów kontrolnych o różnym stopniu ogólności z przemyślanymi interakcjami ...

... Oferowanie call/ccjako podstawowej funkcji kontroli, w ramach której wszystkie inne funkcje kontroli powinny być wdrażane, okazuje się złym pomysłem. Argumenty przemawiają za wydajnością, wyciekiem pamięci i zasobów, łatwością implementacji, łatwością użycia, łatwością rozumowania call/cc. Jeśli naprawdę istnieje jedna wyróżniająca się funkcja kontroli, którą można zaimplementować jako prymityw, a inne są umieszczane w bibliotekach, tak nie jest call/cc.

David Nolen napisał bibliotekę kontynuacji dla Clojure. Wypróbuj to!

delimc

Ograniczona biblioteka kontynuacji dla Clojure 1.4.0 (i 1.3.0). Fragmenty oparte na cl-cont Slava Akhmechet ( http://defmacro.org ) ...

Frank Shearar
źródło
2

Chociaż Clojure nie ma wbudowanych pierwszorzędnych kontynuacji ani coroutines jako podstawowej funkcji, możliwe jest wdrożenie własnej.

Na przykład core.async to biblioteka Clojure, która implementuje model CSP (Concurrent Sequential Processes). Używa gomakra do przekształcenia kodu w maszynę stanu. Chociaż nie jest to właściwie coroutines per se, można go zastosować do wdrożenia tych samych wzorców.

Istnieje także pulley.cps , kompilator makr, który napisałem, który przekształca (przez cps/ cps-fnmakra) kod Clojure napisany w stylu bezpośrednim w styl kontynuacji. Według mojej najlepszej wiedzy jest to najbardziej kompletny program Clojure o kontynuacji. Obsługuje dynamiczne wiązanie, wyjątki, wywoływanie tam i z powrotem między kodem macierzystym a transformowanym (chociaż kontynuacja nie jest zachowywana w różnych kontekstach). W tej chwili call-ccobsługiwane są tylko nieudane kontynuacje (tj. Tradycyjne ), ale mam plany, aby wdrożyć wyznaczone kontynuacje w przyszłości.

Podczas gdy pulley.cps nie zapewnia bezpośrednio samych coroutines, z call-cctym że wdrożenie własnego jest stosunkowo proste. W rzeczywistości jednym z przykładów jest prosta implementacja wielozadaniowości kooperacyjnej . Jest to dalej oparte na przykładzie CSP . Jest też przykład Ping-Ponga , ale jest to bardziej przykład optymalizacji ogonów niż coroutines.

Oczywiście tego rodzaju transformacje są najskuteczniejsze w przypadku zastosowania do całego programu. Niestety nie jest to możliwe w przypadku samych makr, które są zlokalizowane. Mimo to nawet zlokalizowane transformacje mogą być bardzo skuteczne.

Nathan Davis
źródło
1

Czy Clojure ma kontynuacje lub coroutines do wykonywania zadań takich jak ping-pong bez przepełnienia stosu?

Stare pytanie, więc nie jestem nawet pewien, czy ta funkcja była w tym czasie dostępna, ale dla każdego, kto chce wdrożyć jakąkolwiek funkcję „ping-ponga”, sprawdź trampolinę !

Właśnie to odkryłem jako odpowiedź na moje pytanie dotyczące efektywnego stylu kontynuacji przekazywania w Clojure, tutaj: /programming/50952443/continuation-passing-style-does-not-seem-to-make-a -difference-in-clojure / 50955276 # 50955276 i myślę, że to tylko praca. Słyszałem o tym jakiś czas temu, ale nigdy nie przeprowadziłem pełnego dochodzenia. Więcej mnie oszuka. W przeciwieństwie do wielu innych proponowanych rozwiązań, po prostu działa .

====== PS. Mnóstwo informacji o samouczkach online,] oto kilka, które uznałem za przydatne

alex gian
źródło
1
może linkify trampolina, aby wskazać dokumentację?
esoterik