🚀 Transducers with nanoutils 0.1.1

Alexey Berezin
3 min readFeb 3, 2019

What’s a transducer?

Transducer is a function which changes behaviour of a reducer without knowing the structure and without creating intermediate structures

Transformation process using transducers. Mentioned in Understanding Transducers in JavaScript.

Examples

Task. Find sum of all ages which will be even next year
Means. You can do it at least three different ways

Imperative style

Declarative way with Array.prototype methods

I know here you can only use reduce but it becomes imperative and loses effect of Divide and Conquer. Here it means all steps are separated from each other and easily readable

Declarative way with transducers

Here we use nanoutils@0.1.1

Here I intentionally didn’t write it in a single line as it doesn’t improve performance and makes it clear

Performance 🐌 … 🚀

Performance test was implemented with perf_hooks

Given 3 ways mentioned above for array of sizes 10K, 100K and 1M the statistics look like this

You can check performance on CodeSandbox

Yet another one example

Task. Having posts on the page return first page (to make example even more simple) which is filtered by a specified author and date
Input. All data was generated with Fake. Example is available in CodeSandbox

Imperative style

The code itself can be optimised. However, every step is described in details. The bad part here is that we need to provide next filter with one more function which is bad for scalability

Declarative way with Array.prototype methods

Here we optimise filters with Object and Array.prototype.every which looks much better. Array.prototype.slice is applicable to get the first filtered value as Array (in case we need 5 or 10 first filtered values)

Declarative way with transducers

Here we can see several changes

  1. filterPredicatesObject which has same structure as post inside posts
  2. where is used to validate post with specified filterPredicates
  3. takeT is used to take first post (if we wanted to take last posts, we would replace transduce => transduceRight and takeT => takeLastT)
  4. pushReducer replaces flip(append) as it creates less Arrays to get the result (To prove it, you can save [] to the variable and mutate it afterwards, you will see that result of transduce is also mutated)

Easy to debug

If you have troubles you can easily find the way with consoleT or can debug the application easily as nanoutils doesn’t mutate anything

consoleT helper
debugT helper

Links

  1. Nanoutils 0.1.0: Release
  2. Transducer API in details: Issue on GitHub
  3. Roman Liutikov: Understanding transducers in Javascript
  4. CodeSandbox: Documentation
  5. Node.js 11.9: Performance Timing API

Thank you!

Alexey Berezin,
Front-end Developer from Yandex

--

--