haslett icon indicating copy to clipboard operation
haslett copied to clipboard

Can we reduce/transduce or no?

Open alza-bitz opened this issue 11 months ago • 2 comments

Hey there, many thanks for this lib!

I have a question about reduce/transduce on the output channel. The core.async docs imply the channel has to close before the result is available, but the channel here is backed by a websocket of course and I want that to stay open.. As such, I am guessing reduce/transduce won't work in this case?

Currently I'm using loop/recur inside a go block and that seems to work ok, but I was just curious about other options to avoid looping if possible.

Thanks 🙏

alza-bitz avatar Mar 10 '25 21:03 alza-bitz

If you're using clojure.core.async/transduce, then yes, the channel needs to close. Depending on the reduction (as reductions can return early), it may require all input to create an output. For example, the sum of all values put on the channel could not be worked out until the channel was closed, because until the channel is closed, more values can always be added to it.

(def total-value
  (a/transduce identity + 0 numbers-ch)))

However, you can add a transducer to a channel that can perform transformation as the channel receives data. For example, you could have a transducer that finds the absolute value of each value put onto the channel.

(def absolute-ch
  (a/chan 10 (map abs)))

Transducers have control over when they output, so a transducer can also delay output. For example, you might have a transducer to computer a running average over a 10 value window, in which case, the transducer might wait until its received the first 10 numbers before outputting the average.

weavejester avatar Mar 10 '25 23:03 weavejester

Ah ok, got it. Thanks! The transducer in my case would be using a state-based condition with respect to earlier messages to decide termination, but that's the same in principle to a windowed message count I suppose. I will look into it, seems these docs are the place to start: https://clojure.org/reference/transducers#_early_termination https://clojure.org/reference/transducers#_creating_transducible_processes

alza-bitz avatar Mar 24 '25 12:03 alza-bitz