leebyron / iterall

🌻 Minimal zero-dependency utilities for using Iterables in all JavaScript environments.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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…