Clojure ha continuazioni / coroutine / ecc?


20

Ho iniziato a programmare con Python, ed ero davvero confuso da concetti come coroutine e chiusure.

Ora penso di conoscerli a un livello superficiale, ma non ho mai sentito quel momento di "illuminamento", quindi ho scelto di imparare Clojure. Ho comprato il libro di Stuart Halloway ed è buono, ma quando ho guardato l'indice non c'erano parole come coroutine o continuazione. Li ho cercati su Google, ma non c'è neanche niente.

Quindi, la mia domanda è:

Clojure ha continuazioni o coroutine per svolgere attività come il ping-pong senza un overflow dello stack?

Esempio di Python (sebbene Python standard non supporti una versione completa di questo coroutine simmetrico):

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

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

Risposte:


20

Clojure non ha call / cc, ma non vuoi comunque continuazioni non delimitate .

Litighiamo contro call/cccome caratteristica del linguaggio centrale, come l'operazione di controllo distinta per implementare relegando nativamente tutti gli altri nelle biblioteche. La primitiva call/ccè una cattiva astrazione - in vari significati di "cattivo" mostrata di seguito, - e la sua cattura della continuazione dell'intero programma non è praticamente utile. L'unica ricompensa per il duro lavoro per catturare l'intera continuazione in modo efficiente è il duro lavoro per aggirare la cattura dell'intera continuazione. Sia gli utenti che gli implementatori sono meglio serviti con una serie di primitive di controllo ben scelte di vari gradi di generalità con interazioni ben ponderate ...

... Offrire call/cccome funzionalità di controllo principale in termini di implementazione di tutte le altre strutture di controllo risulta una cattiva idea. Prestazioni, perdite di memoria e risorse, facilità di implementazione, facilità d'uso, facilità di ragionamento sono tutte controindicate call/cc. Se esiste davvero una caratteristica di controllo distinta da implementare come primitiva, con altre relegate in librerie, non lo è call/cc.

David Nolen ha scritto una biblioteca di continuazioni delimitate per Clojure. Provalo!

delimc

Una libreria di continuazioni delimitate per Clojure 1.4.0 (e 1.3.0). Porzioni basate su cl-cont di Slava Akhmechet ( http://defmacro.org ) ...


2

Mentre Clojure non ha continuazioni di prima classe o coroutine integrate come funzionalità di base, è possibile implementare le tue.

Ad esempio, core.async è una libreria Clojure che implementa il modello CSP (Concurrent Sequential Processes). Usa una gomacro per trasformare il codice in una macchina a stati. Sebbene non sia esattamente coroutine di per sé, può essere utilizzato per implementare gli stessi schemi.

C'è anche pulley.cps , un compilatore di macro che ho creato che trasforma (tramite cps/ cps-fnmacro) il codice Clojure scritto in stile diretto in stile di passaggio di continuazione. Per quanto ne so, è il programma Clojure a tema di continuazione più completo. Supporta il binding dinamico, le eccezioni, il richiamo avanti e indietro tra codice nativo e trasformato (sebbene la continuazione non sia mantenuta in tutti i contesti). Al momento, call-ccsono supportate solo le continuazioni abortive (ovvero, tradizionali ), ma ho in programma di implementare le continuazioni delimitate in futuro.

Mentre pulley.cps non fornisce direttamente coroutine di per sé, call-ccè relativamente semplice da implementare. In effetti, uno degli esempi è una semplice implementazione del multitasking cooperativo . Questo è ulteriormente sviluppato nell'esempio CSP . C'è anche un esempio di ping-pong , ma è più un esempio di ottimizzazione della coda che di coroutine.

Naturalmente, questo tipo di trasformazioni sono più efficaci se applicate all'intero programma. Sfortunatamente, questo non è possibile solo con le macro, che sono localizzate. Tuttavia, anche le trasformazioni localizzate possono essere molto efficaci.


1

Clojure ha continuazioni o coroutine per svolgere attività come il ping-pong senza un overflow dello stack?

Vecchia domanda, quindi non sono nemmeno sicuro che questa funzione fosse disponibile al momento, ma per chiunque desideri implementare qualsiasi tipo di funzionalità "ping-pong", dai un'occhiata al trampolino !

L'ho appena scoperto come risposta alla mia domanda sull'efficace continuation-passing style di Clojure, qui: /programming/50952443/continuation-passing-style-does-not-seem-to-make-a -difference-in-clojure / 50955276 # 50955276 e penso che sia solo il lavoro. Ne avevo sentito parlare qualche tempo fa, ma non avevo mai indagato a fondo. Più mi prendi in giro. A differenza di molte delle altre soluzioni proposte, semplicemente funziona .

====== PS. Un sacco di informazioni tutorial online,] qui sono alcune che ho trovato utili


1
forse collegare il trampolino per indicare la documentazione?
esoterik,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.