I think the difficulty here is that Chord has a bidirectional channel, where putting and taking operate on different "streams" inside the channel. (Internally, Chord is actually using a different channel for reads and writes. It constructs the "joined" channel using chord.channels/bidi-ch)
I don't think this was envisioned as a proper way to use channels. I think they were envisioned as a queue, and queues hold values, not communication streams. When you put onto a channel, it contains what you put until you take it off. (Note that channels with attached transducers must be buffered because it needs a place to hold the result of the reduction step.) A Chord channel isn't like this: when you put on it, the value is gone, and different values from some other place appear when you take from it. The more usual solution is to use a pair of channels. map<, map>, etc happened to work because they always put/take a value unchanged in the opposite direction onto the transformed channel. I suspect the core developers were only using map>, map< et al in pipelines (where transducers are fine) and not realizing people were using them in a way that relied on the other direction being pass-through. You will always need either a pair of channels to undo the unification done by Chord, or you will need to implement a channel (using reify and the WritePort and ReadPort protocols) where take and put mean different things and you can attach a transducer independently to each. Something like that would probably not make it in to core because it encourages the use of Chord-style "multistream" channels. You could try something like this: (defn eduction> [xform ch] (let [in-stream (chan 1 xform) out-stream (chan)] (pipe in-stream ch) (pipe ch out-stream) (chord.channels/bidi-ch in-stream out-stream))) Of course it would be more efficient to use reify and implement the channel interfaces directly, like map> does, but with transducer semantics for f (including the finalize arity and when the f is called). On Friday, February 12, 2016 at 1:41:20 PM UTC-6, James Reeves wrote: > > I currently have some core.async code that looks like: > > (map< :foo ch) > > However, map< and map> are now deprecated, with the suggestion to use > transducers instead. Unfortunately it's not obvious how to go about that. > > At first I thought that I could use a pipe and a new channel: > > (pipe ch (chan 1 (map :foo))) > > But there's no distinction between channel input and output here. This > matters because I'm using a bidirectional channel from Chord > <https://github.com/jarohen/chord>. > > I'm thinking that it would be nice to have some functions like: > > (eduction< ch xform) > (eduction> ch xform) > (eduction ch xform) > > So I could write something like: > > (eduction< ch (map :foo)) > > Have I missed anything? Is there some equivalent to this functionality > already in core.async that I haven't noticed? > > - James > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.