Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add collect method #5

Closed
edevine opened this issue Jan 6, 2017 · 9 comments
Closed

Add collect method #5

edevine opened this issue Jan 6, 2017 · 9 comments

Comments

@edevine
Copy link

edevine commented Jan 6, 2017

Consider this snippet in the readme which incorrectly suggests the return value of flatten is an array.

var deepValues = [ [ 'A' ], [[ 'B' ]], 'C' ]
var flat = deepValues.values().flatten() // [ 'A', ['B'], 'C' ]

Adding the method collect:

class Iterator<T> {
    collect<R>(fn: (iterator: Iterator<T>) => R): R;
}

Would allow:

var deepValues = [ [ 'A' ], [[ 'B' ]], 'C' ]
var flat = deepValues.values().flatten().collect(Array.from) // [ 'A', ['B'], 'C' ]
@leebyron
Copy link
Owner

leebyron commented Jan 6, 2017

I can update the Readme to make it more clear that the return values are Iterators.

I'm not sure I see the value of collect() isn't iter.collect(fn) equivalent to fn(iter)?

@edevine
Copy link
Author

edevine commented Jan 6, 2017

It is, but if we're dealing with several chained methods with line breaks, collect would make the code much more readable.

deepValues.values()
  .filter(value => value.isValid)
  .map(value => value.children)
  .flatten()
  .collect(Array.from);

vs

Array.from(
  deepValues.values()
    .filter(value => value.isValid)
    .map(value => value.children)
    .flatten()
);

@edevine
Copy link
Author

edevine commented Jan 6, 2017

The method could also attempt to construct the callback to be used with Map and Set:

Iterator.prototype.collect = function (collect) {
  return Symbol.species in collect ? new collect[Symbol.species](this) : collect(this);
}

@leebyron
Copy link
Owner

leebyron commented Jan 6, 2017

I don't think all current and future uses of Species will accept that call signature

@RangerMauve
Copy link

Are there any examples in the wild that use a similarly named method?

@edevine
Copy link
Author

edevine commented Jan 6, 2017

@leebyron No they won't. Neither will all functions accept the call signature either. It's up to the developer/ static type checker to know when to use them.

@edevine
Copy link
Author

edevine commented Jan 6, 2017

@RangerMauve I came across the name in these meeting notes: https://github.com/rwaldron/tc39-notes/blob/master/es6/2014-11/nov-19.md#58-mapprototypemap-and-mapprototypefilter-spec--set

My suggested implementation is different, but the essence is the same: a convenient API to put iterator results back into a collection after they have been transformed.

@leebyron
Copy link
Owner

leebyron commented Jan 6, 2017

I'd like to keep this proposal limited to just those higher-order operations on Iterators themselves to keep a well defined scope for an eventual proposal.

I was present for that particular conversation and remember the controversy around a collect method and introducing a collection prototype. The consensus there was to start with an Iterator prototype proposal, which inspired work on this.

If work begins on some kind of shared collection prototype, then perhaps that would be the right opportunity to define a protocol for creating collections from Iterators. Right now Symbol.species might not be the complete solution.

@leebyron leebyron closed this as completed Jan 6, 2017
@edevine
Copy link
Author

edevine commented Jan 13, 2017

@leebyron How about a more general purpose infix method such as D3's selection.call() for chaining arbitrary functions.

class Iterator {
  call(callback, ...args) {
    return callback(this, ...args);
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants