2016-07-30 36 views
1

Als Hobby-Projekt arbeite ich an einem alternate futures and promises implementation basierend auf "From Events to Futures and Promises and back". Der ursprüngliche Autor verwendet Kanäle/Ereignisse unter der Haube, weshalb ich core.async verwende. Eine Zukunft, in Pseudo Go Syntax ausgedrückt, sieht wie folgt aus:Wie man unendlich go-loops behandelt

func future(func f() (T, bool)) Future <T> { 
    ch = newChannel() 
    spawn(func() { 
     x := f() 
     for { syncEvt(sndEvt(ch, x)) } 
    }) 
    return rcvEvt(ch) 
} 

gültig Go-Syntax, Typdefinitionen und eine get Funktion:

type Comp struct { 
    value interface{} 
    ok bool 
} 

type Future chan Comp 

func future(f func() (interface{}, bool)) Future { 
    future := make(chan Comp) 

    go func() { 
     v, o := f() 
     c := Comp{v, o} 
     for { 
      future <- c 
     } 
    }() 

    return future 
} 

func (ft Future) get() (interface{}, bool) { 
    c := <-ft 
    return c.value, c.ok 
} 

Nun, wenn ich diesen Port zu Clojure, war ich dachte, es zu implementieren, wie folgt:

(defrecord Comp [value ok]) 

(defn future [f] 
    (let [future (chan)] 
    (go-loop [comp (f)] 
     (>! future comp) 
     (recur comp)) 
    future)) 

(defn get [future] 
    (<!! future)) 

da ich Clojure ziemlich neu bin (und core.async), bin ich sehr besorgt über die unendliche go-loop. Wird der IOC-Thread jemals veröffentlicht? Sollte ich eine Art Giftpille zur Verfügung stellen, um den Kreislauf zu stoppen (obwohl ich denke, dass dies ziemlich fehleranfällig wäre)? Irgendwelche Vorschläge?

+0

Ja, in der Regel die 'recur' abhängig gemacht wird mit [' if'] (https://clojuredocs.org/clojure.core/if) oder eine seiner Varianten. –

+0

Ich weiß, aber die Implementierung aus dem Papier verwendet die Endlosschleife, um sicherzustellen, dass die Zukunft (die ein Kanal ist) immer verfügbar ist, sobald "comp" verfügbar wird. Daher würde ich gerne wissen, wie man damit in Clojure umgeht. – beatngu13

Antwort

4

Go Blöcke in Clojure sind nicht wie sie in Go sind. In core.async go existieren Blöcke als Callbacks, die an Kanäle angehängt sind und als solche leben sie so lange wie der Kanal selbst lebt. Denken Sie also an go Blöcke als syntaktischer Zucker über Rückrufe und es wird allen Sinn ergeben.

Dieses Video-Tutorial geht in etwas mehr Detail: https://www.youtube.com/watch?v=VrwVc-saWLw