Hacker News new | ask | show | jobs
by spion 4013 days ago
Transducers create functions that are meant to be passed to reduce (i.e. take accumulator and element and return a new accumulator).

Its possible to implement most other functions (map, filter, take etc.) using reduce. Transducers take advantage of that.

Unfortunately, if you try to do that, you'll notice that the implementation is sometimes tied with the way you build the entity: e.g. for vectors, map implemented in terms of reduce would start with an empty vector then append to it.

That sucks. We want operation chains that are independent of the data structure they operate on. We want them to work on vectors, lists, channels, whatever - anything that can have a reduce-like operation (anything reducible)

However, it turns out you don't necessarily have to recreate the entity (e.g. list) when chaining. All you need to know how to do is invoke the next operation in the chain, i.e. the next reduction function. For example:

* map can apply the function on the element to get a new result, then call the next reduction function with the accumulator and that new result.

* filter can check the element and either return the old accumulator or apply the next reduction function with the element, etc.

Therefore, transducers simply take an additional argument: the next reduction function that should be applied. This lets you build up a chain of operations (e.g. map filter etc) that doesn't care about the kind of entity they're operating on. Only the last "step" must be a reduction function that needs to know how to build the result.