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 support for transforming iterables #2585

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open

Add support for transforming iterables #2585

wants to merge 6 commits into from

Conversation

wojpawlik
Copy link
Contributor

@wojpawlik wojpawlik commented Jul 11, 2018

A small addition to _dispatchable is all it takes to use transducers to support iterables.

Checklist
  1. Naming -- https://youtu.be/4KqUvG8HPYo?t=2437
  2. Tests
  3. Docs
  4. Don't accept / return iterators.
  5. Dispatch to transduce method of obj, if present.
Ideas out of scope of this PR
  • Consider special-casing chain for iterables to avoid temporary arrays.
  • Clean up _dispatchable.
  • Expose _educe as R.educe.
  • Consider returning lazy iterable from range, repeat, unfold.

Related: #2525, #2508, #695, possibly other, closed issues.

@buzzdecafe
Copy link
Member

this is pretty nice IMO, I'd love to get this in post 1.0 (if that ever happens 😛)

@CrossEye
Copy link
Member

This is fantastic. This is one of the things I've wanted to have Ramda do for a long time.

I tried once before and fell down on the job, but I think we need a dedicated effort to get 1.0 out the door. I would like to do much more like this post 1.0.

@wojpawlik wojpawlik changed the title WIP: Add support for iterables and Set WIP: Add support for iterables Jul 14, 2018
@wojpawlik
Copy link
Contributor Author

wojpawlik commented Jul 14, 2018

Glad to hear that you like it :)

I improved every aspect of the original code and finished writing tests.

I want to stop worrying about ES3 compatibility, and embrace ES6+. (#2337 (comment))

I'll ignore CI for versions of Node older than 6.x, which are all end-of-life, and use ES6 in this PR.

When you decide which versions of Node to support in 1.0 and update CI to match it, I'll rebase my work.
I'm almost done, and all the added tests pass on Node 10, so no need to rebase; all that's needed is to merge #2589 before this.

@trgwii
Copy link

trgwii commented Jul 15, 2018

Amazing work!

@wojpawlik wojpawlik changed the title WIP: Add support for iterables Add support for iterables Jul 16, 2018
@wojpawlik

This comment has been minimized.

@Bradcomp
Copy link
Member

I haven't done a deep dive into the code yet, but I reviewed the tests. I'd like to see some tests that verify that the functions don't mutate the input when passed an iterable.

For instance, with all:


const it = iter([2,4,6,8,9,10]);
eq(R.all(even, it), false);
eq(R.all(even, it), false);

@wojpawlik
Copy link
Contributor Author

@Bradcomp... why?

There are no such tests anywhere in Ramda, and for that reason, I consider them out of the scope of this PR.

Also, iter aka iterableOnly is impossible to mutate. Equivalent definition:
const iterableOnly = R.compose(Object.freeze, R.pickAll([Symbol.iterator]), bound).
It returns a frozen object which only exposes iterable protocol.

@Bradcomp
Copy link
Member

Bradcomp commented Jul 16, 2018

Here is a counterexample, please let me know if I am missing something: https://goo.gl/xSpHEk

Edit: I see that with iterableOnly it works. This says more about a limitation of the test than the guarantee of the function itself, as the counter example shows.

From the Ramda home page:

Ramda has a more focused goal. We wanted a library designed specifically for a functional programming style, one that makes it easy to create functional pipelines, one that never mutates user data.

If I pass in a generator, I would expect it to not be mutated. If we're working with all iterables, we need to make sure that happens. Being that generators are inherently stateful, it will take extra precautions to ensure that.

Ideally all the functions would be tested to ensure they fulfill that property, but this is a really good place to start.

@wojpawlik
Copy link
Contributor Author

Thanks for elaborating, I understand your concern now.

If I pass in a generator, I would expect it to not be mutated. If we're working with all iterables, we need to make sure that happens.

  1. It's impossible to read an iterator without mutating it.
  2. Unless stateful iterator is passed, Ramda will never produce and return a stateful iterator.

We could refuse to operate on stateful iterators. I like this idea, I'll code it in tomorrow.

And if we ever decide to support mutable iterators, it'd be a non-breaking change.

@CrossEye
Copy link
Member

Some day, I'll learn to study the code before responding. Thanks @Bradcomp for your due diligence!

@wojpawlik

This comment has been minimized.

@wojpawlik wojpawlik mentioned this pull request Aug 4, 2018
6 tasks
@semmel
Copy link
Contributor

semmel commented Aug 14, 2018

Since for ... of loops are not supported by IE11 does this mean Ramda will no longer work in IE11?

Our customers (large corporations, not consumers) still work with IE11 which is afaik still shipped with Windows and gets security updates.

@zmoshansky
Copy link

Can I offer any help to try and get this across the line or is it blocked pending some goal (1.0)?

(Regardless, much thanks to the authors of Ramda and this PR; I've been using Ramda for the last ~4 years very happily. Iterable or Map/Set [Mostly subsumed by iterable support in practice] support is one of the few areas it seems to struggle).

@CrossEye
Copy link
Member

CrossEye commented Nov 7, 2018

I'm slowly working my way backward through open issues. This one hasn't made its way to the top of my list yet, but in any case, yes, it will probably have to wait for 1.0, as it's implemented with for-of, which is not available in all the pre-1.0 target environments.

@wojpawlik

This comment has been minimized.

@trgwii
Copy link

trgwii commented Mar 22, 2019

Since for ... of loops are not supported by IE11 does this mean Ramda will no longer work in IE11?

Our customers (large corporations, not consumers) still work with IE11 which is afaik still shipped with Windows and gets security updates.

I believe it should be possible to keep supporting IE11 through transpilation, but this would need some further investigation... I don't see a reason why for..of couldn't be transpiled, so there is still hope for the foreseeable future!

EDIT: And any of these changes obviously only apply to >= v1.0 versions of Ramda, so existing versions will continue to function as they have always done as long as the language doesn't introduce a breaking change.

@semmel
Copy link
Contributor

semmel commented Apr 1, 2019

@trgwii

I believe it should be possible to keep supporting IE11 through transpilation, ...

Yes fair enough, I could ship a transpiled ramda.js to IE 11, no problem there.

I just want to note that while for .. of is not needed for iterating over iterables, however it's use is certainly left a will of the implementor. But in that case I cannot see why Ramda could not go all ES2019 with arrow (=>) functions and stuff. And thus would be a different library with many functions gone. I think that decision is better saved for a major version bump. Rather then quietly introducing changes in the runtime requirements.

... existing versions will continue to function as they have always done ...

Letting source code rot with an old library version just makes it harder to update one day then IE 11 is finally history. That's not an option.

Also you cannot maintain a zoo of library versions in a medium size code base: What about a shared component which depends on Ramda? Must I than implement, test and document two versions of it, one with Ramda pre 1.0 and one with post 1.0? That would kill productivity. So also not an option.

@trgwii
Copy link

trgwii commented Apr 8, 2019

I think that decision is better saved for a major version bump. Rather then quietly introducing changes in the runtime requirements.

@semmel Ramda is very careful about these things in my experience, just look at 0.26.1 release notes. I'm certain no changes to supported runtimes will happen until major bump.

@wojpawlik wojpawlik changed the title Add support for iterables Add support for transforming iterables Nov 23, 2019
This was referenced Nov 23, 2019
@wojpawlik
Copy link
Contributor Author

I can rebase this to make it mergable, but I'm wondering if implicitly educing iterables is a good idea in the first place. Perhaps exposing R.educe to be explicitly would be better?

@wojpawlik
Copy link
Contributor Author

Also, there's a possible optimization: _educe(g, _educe(f, in)) = _educe(o(f, g), in), should I add it?

@CrossEye
Copy link
Member

CrossEye commented Dec 9, 2019

@GingerPluPlus: I very much like the idea here. After the holidays, I'm going to try to get a discussion going between anyone intertested in how to get 1.0 out the door, and then I'd be very interested in including this.

Also, what is the implication of using the word "educe" here? I know the English definitions, but I'm not making the connection with this function.

@wojpawlik
Copy link
Contributor Author

Thanks, but reconsider -- this may hinder adding Map support. No rush.

At this point, I'll believe in 1.0 only after I see it done :P

"Educe" is the name picked by Rich Hickey, see https://youtu.be/4KqUvG8HPYo?t=2437

@CrossEye CrossEye added the Maturation Ideas to make Ramda a more mature library label Jan 22, 2022
@CrossEye
Copy link
Member

Closing until after v1.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
1.0 discussion enhancement Maturation Ideas to make Ramda a more mature library
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants