Chaining
andywer opened this issue · comments
Hi there and thanks for sharing your work!
You wrote that you want to keep the code base as lean as possible, but maybe this is at least interesting for another package on top of iterall.
Right now there is only forEach
available to work with iterators. But filter
, map
& friends are a must-have for many people, too. And I would definitely like to daisy-chain them.
Do you know of an implementation or do you plan one? :)
Cheers,
Andy
You're correct that this library isn't the right home for these additional functions. But I agree that more of the higher order functions for collections are super useful to have.
I've started some work on that here https://github.com/leebyron/ecmascript-iterator-hof but it's not in a consumable form yet, unfortunately.
I while back I wrote a slightly experimental version of what you're asking for https://github.com/leebyron/loda-js/ check that out to see if it's relevant.
Hmm, loda might be quite what I had in mind, but there is no documentation to back that up... 😅
But maybe loda is already a little too much. My first idea was something simple and straight forward like
import collection from '<name>'
// ...
collection(iterator)
.map((item) => item.value)
.filter((value) => value > 0)
.forEach((value) => { console.log(value) })
A bit like iterator-hof
, but without new language features.
BTW why forEach
and not reduce
?
@chicoxyzzy Don't care too much about the code's details. .reduce()
should also be available, of course, but this is just some simple sample code to get the idea.
Anyway I'd prefer reduce
because all other methods could be made using it. Consider transducers
I considered naming that function forOf
instead of forEach
and maybe I should have to clarify its purpose, however the behavior is to fit the existing forEach
semantics, which are actually a little bit different from forOf
(array holes, ugh). You can think of it as version of for ... of
that works in all versions of javascript.
This library is designed to provide the minimal set of tools to use Iterators, but not to provide a plethora of iterator higher-order functions nor press an opinion on how to iterate.
Also note that you can very easily build reduce
with for ... of
and forEach
:
in ES6:
function reduce (collection, reducer, initial) {
var reduced = initial
for (let item of collection) {
reduced = reducer(reduced, item)
}
return reduced
}
anywhere with iterall:
function reduce (collection, reducer, initial) {
var reduced = initial
forEach(collection, function (item) {
reduced = reducer(reduced, item)
})
return reduced
}
@chicoxyzzy also - if you're into transducers, the popular transducer library transducers-js
already supports Iterables! It does so using the same fallback mechanics that iterall
advocates for so that it works in all versions of JavaScript and not just ES2015. A+
https://github.com/cognitect-labs/transducers-js/blob/master/src/com/cognitect/transducers.js#L44
@andywer I’ve been thinking along these lines as well. Take a look at Iterable. It provides a wrapper class for iterables and then attaches methods like map
, reduce
, and slice
to those. Where possible, it delegates to the underlying concrete class, especially to maintain lazy loading, for example using generators.
My initial experiment is targeted to MarkLogic’s in-database JavaScript implementation, which provides a lazy Sequence
class for database access. However, the concepts are the same for any iterable.
@jmakeig Thanks! I will have a closer look on it later, but it looks pretty much like what I had in mind. Btw: I found a minor typo in the README: require('/iterable')
(leading slash) ;)
require('/iterable')
(leading slash)
Confusing, but not a type-o. MarkLogic has different rules for resolving imports than Node. I’ve got a task to publish to npm that will fix/clarify this and will allow use in Node and the browser. And now we’re officially off-topic for this thread…