Is there a reason why pipe doesn't have an xform argument? I often find myself wanting to translate from one channel to another, but pipeline feels a little too heavy - I don't need to perform my computation on a separate (or multiple) threads.
I've had this conversation before (can't remember the context exactly) and I think there may be a gap here, but it needs some careful unpacking.
you can put the xform directly on a channel of course, and then combine with pipe - why does that not suffice?
(I'm asking this socratically, not trying to challenge you)
Embarrassingly I had actually forgotten I could do that.
I think one answer would be that you already have the channels in hand (so too late to do that)
another problem that I know I've seen is that it can be important to AVOID ever having the producer run the xform, because the producer is a hot path and your intent is to decouple the "work" from the "putter". because xforms on a channel may run in either the producer thread or some other thread, you don't (usually) have this guarantee
so something of the shape of "pipe with xform" that has the property would perhaps be useful
In my case I don't think there's much "work" - hence my reluctance to use pipeline. I tend to be reticent about parallelism if the workload is small, as past benchmarks tend to show functions like pmap are slower for small workloads. However, I think in my case I can use the channel xforms. I essentially have two channel pairs - a-in/a-out and b-in/b-out. I'm connecting a-in to b-out and b-in to a-out, with a translation between the two ends. I'm creating the B channels but not the A channels. However, if I put the translations on the B channels it should work, unless I have my logic all twisted.
If I'm putting data into b-in, then the xform will transform it before sending it to a-out. Likewise if a-in receives data and places it into b-out, then the xform on b-out should transform it.
Thanks for reminding me about channel xforms!
Is there a way to wait on a channel to close without consuming from it? I'm asking because if I set up a pipe between two channels, and then want to do something after the pipe is closed, I'm unsure how to do that without writing my own custom pipe function (which may be the solution!)
this is consuming (so definitely violates your ask), but take will deliver nil when closed
(nil is not allowed as a channel value, so it always represents close)
I guess a side-effectful reducer on the channel could do it... though that seems like bad practice?
(defn side-effect-on-reduced [side-effect]
(fn [rf]
(fn ([] (rf))
([result] (side-effect) (rf result))
([result x] (rf result x)))))
I'm not sure the completing arity ever get called in channel transducers
I just tested it and it actually does, though whether that's a guarantee in future I don't know.
Would it be useful to have a function in core.async that waits for a channel to be closed? It could operate the same was as timeout, in that it returns a channel that closes when its argument channel is closed.
(<! (a/wait-until-closed ch))
This seems analogous to the Thread.join method.