Hacker News new | ask | show | jobs
by gue5t 3840 days ago
Defining a transducer involves returing a closure wrapping some logic around calling a function of type (result, element) → result to get a function of type (result', element) → result'. All the while you're composing, I assume you don't know what this element type is?

Defining an iterator adaptor involves defining the state itself (generally you have a field for the state of the iterator you wrap, and some fields for the state of your transformation itself) and its .next() method for the Iterator impl. The .next() method has type (state, input) → (state, optional output), except that in Rust reality it mutates the state rather than returning a new one.

The difference seems to be that in Rust the output is separate from the state. You could convert an iterator adaptor into a transducer by making the optional output a field in the state.

Also, in Clojure it looks like the usage is that you compose the transducers separately from applying to an input, whereas in Rust you generally compose adaptors on top of the input iterator. I assume this is what you mean with "not referring to the collection at all". In Rust, defining the adaptor chain ahead of applying it would look like:

    let transducer = |x: Iterator| {x.map(xfrm).filter(pred).whatever()};
Which is fine, but not particularly idiomatic, and might require some work annotating types.