|
|
|
|
|
by llasram
3838 days ago
|
|
I could have been clearer. By the scare-quoted "collection" I meant a value which implements the relevant collection-like interface. In Clojure this is any object `reduce` works on, in Rust is any struct implementing the `Iterator` trait etc. In all the examples discussed these transformations are lazy, only execution the composition of any number of transforms when values are requested. Clojure transducers are different because a transducer is a function which accepts a reducing function and returns a new reducing function, adding behavior by how the input function is composed into the result function. Because the domain and range of transducers are both reducing functions, they can be chained through function composition. A chain is actually applied by transforming a reducing function then using that function to `reduce` (Rust `fold`) a collection. The cool part is that the transformations don't refer to collections at all, not even through some highly abstract collection-like interface. This makes them applicable to other domains, like the previously-mentioned channels. |
|
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:
Which is fine, but not particularly idiomatic, and might require some work annotating types.