core-async

2020-05-25T17:25:14.300300Z

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)]
  (go
    (println "X" (<! x)) ;;123
    (println "X2" (<! x)) ;;nil
    ))

dpsutton 2020-05-25T17:29:57.300800Z

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

2020-05-25T17:33:48.302800Z

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)

dpsutton 2020-05-25T17:34:10.303100Z

but go is not one of those channels?

dpsutton 2020-05-25T17:34:50.303600Z

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

2020-05-25T17:35:19.304200Z

exactly yeah this is what I tried doing

2020-05-25T17:36:39.305100Z

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

2020-05-25T17:38:06.306500Z

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

2020-05-25T17:42:02.309800Z

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

2020-05-25T17:42:16.310200Z

Like basically this is what I was trying

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

2020-05-25T17:42:41.310500Z

gotcha thanks, just trying to make sure I understand fully

dpsutton 2020-05-25T17:43:12.311Z

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

2020-05-25T17:43:46.311900Z

In the grand tradition of clojure it isn't hobbled

dpsutton 2020-05-25T17:44:43.313600Z

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

2020-05-25T17:45:12.314200Z

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

2020-05-25T17:46:35.315900Z

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

2020-05-25T17:46:51.316300Z

Similarly for timeouts

2020-05-25T17:50:43.320600Z

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

2020-05-25T17:51:38.321200Z

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?