Actually "transducer" can be done with straight function composition. It would work in any language supporting high order function, a fancy way of saying passing function around as argument or return value.
e.g. in Javascript (I'll be overly verbose for illustration)
function mySumReducer(sum, value1) {
return sum + value1;
}
function myTimesReducer(product, value1) {
return product * value1;
}
[1, 2, 3, 4].reduce(mySumReducer, 0) gives 10
[1, 2, 3, 4].reduce(myTimesReducer, 1) gives 24
function myDoubler(x) {
return x * 2;
}
function valueTransducer(originalReducer, valueEnhancer) {
var newReducer = function(memo, value) {
var newMemo = originalReducer(memo, valueEnhancer(value));
return newMemo;
}
return newReducer;
}
var myDoubleSumReducer = valueTransducer(mySumReducer, myDoubler);
var myDoubleTimesReducer = valueTransducer(myTimesReducer, myDoubler);
[1, 2, 3, 4].reduce(myDoubleSumReducer, 0) gives 19
[1, 2, 3, 4].reduce(myDoubleTimesReducer, 1) gives 192
valueTransducer is a generic transducer that can be used to apply an extra function to the value during the reduction process. Voila, you got a transducer in Javascript!
To make it more useful,
function fancyTransducer(originalReducer, valueEnhancer, memoEnhancer) {
return function(memo, value) {
return memoEnhancer(originalReducer(memo, valueEnhancer(value)));
}
}
This generic transducer can transform the value and memo of the original reducer. Also since the transducer returns another reducer, you can chain it up by calling transducer again with it using different enhancers. The wonder of functional composition.
It's nothing fancy once it's laid out. It's just a useful programming pattern.