Fork me on GitHub

Is it documented somewhere that the channel returned from a go block is closed after a take, or should this be obvious for a reason I'm missing?

(let [x (go 123)]
    (println "X" (<! x)) ;;123
    (println "X2" (<! x)) ;;nil


the alternative would be a pending take that parks forever and can never be satisfied?


what about a channel you can put something else on later? (I realize this would only be usable if you keep a reference to the result of the go block which isn't how it's meant to be used)


but go is not one of those channels?


you want to reuse the channel returned from a go block as a general purpose channel and put other things on it?


exactly yeah this is what I tried doing


I have some api functions that look like this

(defn get-file [this path]
  (go (->entry (<p! (.getFile gentry path gdir/Behavior.CREATE)))))
At first I took a final chan argument to put the result on but then I figured I could get away with just returning the go block


then later when just messing with the repl I figured I might be able to re-use that chan instead of having to create one, to put subsequent results on


Really a go block doesn't return a channel, it returns a readport (a channel is a full duplex combination of a read and write port). A channel just happens to be the most convenient impl of a readport


Like basically this is what I was trying

(let [fch (get-file filesystem path)]
  (go-loop []
    (do-stuff-with-file (<! fch))
using the internal go block to represent the initial value but then reuse it to subsequently "Set" files


gotcha thanks, just trying to make sure I understand fully


where is the channel returned from the go macro hobbled? it seems that it literally returns (chan 1)


In the grand tradition of clojure it isn't hobbled


sorry. i meant where it loses the write port part 🙂


core.async has the notion of read and write ports, but always just returns channels


You just have to imagine that using the writeport part of a channel returned by a go block is undefined behavior


Similarly for timeouts


One of the nice things about a concurrent ml style API (over the more traditional csp/go API core.async has) is read/write events are first class things, you can very naturally return a read event even if internally there is a full channel


Is it a bad practice to return a go block as sort of an analog to a js/promise, is it better to always explicitly take a channel arg to put the result on?