Argh, this is the second time this gets me. It was posted in 2014 and I clicked on it hoping for an explanation of ultrasonic component physics, which I'm mildly interested in. Instead, yet another programming pattern that has hijacked a common term. And now, being reposted, it gets me again.
Me six. Worked as an apprentice DG engineer, learned about transducers when being taught to calibrate the vacuum chambers on reel to reel tape drives. :)
Hey all you pro audio people: you gotta see what Clojure has to offer for your world. Having come up in CSound Clojure's Pink and other libraries are first class, and the language's semantics pair so well with the audio mindset. Rich Hickey wrote Clojure after dealing with broadcast systems for 20 years. I think of transducers like a side chain. Check out Rich's additive synthesis stuff and you'll see the ethic and thrust behind this language. When the word Composition is invoked it means applying aesthetic, thinking about time, and the rigor that comes along with audio production. If you're a hacker/musician at heart you'll find a home within the Clojure community right away on many levels.
An interesting take on transducers is that they're just functions that return lists
transducer : a -> List b
with one additional caveat: they can contain internal mutable state.
For example the map transducer just takes in a function and returns a modified form of that function that wraps the result in a single element list. The filter transducer takes in a predicate and returns a modified form of that predicate that returns an empty list or single element list of the argument when the predicate evaluates to false or true respectively.
The take transducer is what requires state (and indeed it is implemented with mutable state in Clojure in the form of an internal counter). That means no reusing stateful transduced reducers otherwise you'll find it's already "exhausted." In this case just do the same thing as the map transducer on the identity function until the internal counter hits the number of elements specified.
Composing the transducers becomes just flatmapping/mapcatting one over the result of the previous one (Kleisli composition for those familiar with Haskell).
Running the transducers on an actual structure requires an actual reducing function and consists of first passing an element to the transducer, then reducing over the generated list with the reducing function, and offering the reduced result as the beginning accumulator for the next element that gets passed into the transducer.
12 comments
[ 2.9 ms ] story [ 30.6 ms ] threadAmbiguous jargon is a real problem in the field. I guess it's because the field is relatively young and we haven't nailed things down yet.
For example the map transducer just takes in a function and returns a modified form of that function that wraps the result in a single element list. The filter transducer takes in a predicate and returns a modified form of that predicate that returns an empty list or single element list of the argument when the predicate evaluates to false or true respectively.
The take transducer is what requires state (and indeed it is implemented with mutable state in Clojure in the form of an internal counter). That means no reusing stateful transduced reducers otherwise you'll find it's already "exhausted." In this case just do the same thing as the map transducer on the identity function until the internal counter hits the number of elements specified.
Composing the transducers becomes just flatmapping/mapcatting one over the result of the previous one (Kleisli composition for those familiar with Haskell).
Running the transducers on an actual structure requires an actual reducing function and consists of first passing an element to the transducer, then reducing over the generated list with the reducing function, and offering the reduced result as the beginning accumulator for the next element that gets passed into the transducer.
See https://stackoverflow.com/questions/26653829/how-is-a-transd... for where I first learned about the fundamentals behind this.