Actually one of the things I found during my work on transducers is that actually they seem to me more implementable in C++ than in Haskell. For example, you can implement state-less transducers with almost zero overhead, something that in Clojure is definitely not true (so the standard transducers do hide state inside the closure of the reducing functions). It is also easier to do n-ary transducers for zipping and unzipping and everything, as you intuit, is type checked.
Still, I agree that transducers are most useful when you have libraries that make sense of them. For example, you could implement a lot of "Rx" using transducers. Ideally I see a user never writing a transducer, and occasionally passing one to some library that provides "higher order" reactive collections (channels, observables, etc.) that can be transformed with transducers. For example, my motivation to implement them in C++ was to build "observable/reactive lenses" (something like "cursors" in Om) [1] where you could use transducers to specify how you "zoom" into the virtual sequence of state values...
Anyways, they are an interesting coding tool, but they don't really influence the architecture of the application.
> they seem to me more implementable in C++ than in Haskell
If you don't mind the overhead, it's ContT wrapping some base monad. Or you could make it integral. That is more specific than transducers, I grant. But there's not much they can do that ContT over like Array does not.
I think it's too bad they were invented in Clojure, because they're brutally hard to use right and write in clojure.
I have some interesting work I could share in private on using them to provide stream fusion properties to pipelines of channels. Hit me up on keybase if you'd like to see. I don't want to open source it because then people will expect me to explain them and maintain them and I don't feel like it :)
Sorry, I actually meant "than in Clojure". You are right about the ContT. I'm actually curious about your transducer based stream fusion stuff... I'll hit you up later about it :-)
Actually one of the things I found during my work on transducers is that actually they seem to me more implementable in C++ than in Haskell. For example, you can implement state-less transducers with almost zero overhead, something that in Clojure is definitely not true (so the standard transducers do hide state inside the closure of the reducing functions). It is also easier to do n-ary transducers for zipping and unzipping and everything, as you intuit, is type checked.
Still, I agree that transducers are most useful when you have libraries that make sense of them. For example, you could implement a lot of "Rx" using transducers. Ideally I see a user never writing a transducer, and occasionally passing one to some library that provides "higher order" reactive collections (channels, observables, etc.) that can be transformed with transducers. For example, my motivation to implement them in C++ was to build "observable/reactive lenses" (something like "cursors" in Om) [1] where you could use transducers to specify how you "zoom" into the virtual sequence of state values...
Anyways, they are an interesting coding tool, but they don't really influence the architecture of the application.
[1] atria::funken https://github.com/Ableton/atria