Imagine a conveyor on a car factory: a chain of operations from welding body parts and painting doors to gluing a logo and inflating wheels. Every operation is independent and is based only on a protocol: a car comes from this side and goes to that side after the operation is complete.
Of course, those operations have some input data: this car should have 17" wheels, that car should have 16" wheels. We can do this too:
Calling “skip(1)” creates a function (operation) that knows how to skip exactly 1 item (car).
Sometimes you need to make a new model with additional equipment package. It may be as simple as adding a couple of steps to the conveyor:
Or replacing some steps in existing:
Arrays give you this flexibility to concatenate, merge, copy, and modify existing pipelines.
To finish the conveyor there should be some mechanism like moving belt that will transport a car from one operation from another. This is where Undercut tries to help (not mentioning a pack of 40+ prebuilt common operations like filter/map/skip/etc).
Core pull functions allow you to quickly run a pipeline and acquire the result or combine it into something self-contained and reusable like an Iterable.
Having a list of numbers called “source”:
And a “pipeline” of operations:
We could `pull` items out of the `source` through the `pipeline` and get an array of result items:
In our case “result” will be:
All is done lazily, so “map” won’t run for the skipped item. There’re also “pullValue”, if your result is a single value (not a sequence). Or more generic “pull”, where you pass “target” function getting result items and converting it into whatever you want.
As “pull” is built around Iterables, and many native objects are Iterable out of the box (arrays, strings, maps, sets, etc), you can easily transform a Map of Usernames-by-Id into an Object of Ids-by-Username.
Moreover, you may create a reusable “view” of this data:
The “pullLine” function binds together a “pipeline” and a “source” into an Iterable. Every time you iterate over it, the pipeline will be executed again, giving you a fresh view on processed data.
Let’s build a “pow” operation:
Get an Iterable, go by its items, calculate new values, put them into another iterable with “yield”.
If you aren’t familiar with generators (functions marked with “*” asterisk). Basically, the return value of such function will be not what you return, but an implicit Iterable you can put items into with the “yield” keyword. Please read MDN for more detailed description. I also recommend reading an awesome book Exploring ES6 by Dr. Axel Rauschmayer.
Actually, one important aspect is missing. The “exponent” value isn’t defined and should be assigned in a pipeline like those 17" wheels. To fix this just add another function around:
And this “pow” we can actually use:
It was only a brief review of the Undercut, but should be enough for basic use cases. If you want to learn more, please with undercut.js.org for documentation and tutorials.