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

Use Cases #1

Open
pemrouz opened this issue Jul 24, 2019 · 8 comments
Open

Use Cases #1

pemrouz opened this issue Jul 24, 2019 · 8 comments

Comments

@pemrouz
Copy link

pemrouz commented Jul 24, 2019

As @aklein mentioned, there doesn't seem to be much sense in reversing a Set.

For the other suggested use case, as an iterator prototype method, how would it be possible to have a general .reverse()? (i.e. you can't buffer all the values since if may be infinite).

@ljharb
Copy link
Member

ljharb commented Jul 24, 2019

Iterators are not generically reversible, so this proposal does not seek to add anything to Iterator.prototype.

@hax
Copy link
Member

hax commented Feb 3, 2020

This repo seems still empty?

@ljharb
Copy link
Member

ljharb commented Feb 4, 2020

indeed; we haven't updated it yet.

@dead-claudia
Copy link

Got some more concrete use cases for reversible iterators: https://es.discourse.group/t/bidirectional-iterators/339

My proposal there is different from this, but anything functionally equivalent to that (like adding a reverse method) is fine by me.

@hax
Copy link
Member

hax commented May 28, 2020

@isiahmeadows There are some differences in different languages, especially "next_back" (Rust) vs "previous" (Java, Kotlin) vs separate reverse iterator (Clojure and the current state of this proposal ), for example, r = range(1, 5):

previous() (step back)

r.next() // {value:1}
r.next() // {value:2}
r.previous() // {value:1}
r.previous() // {done: true}
r.next() // {value:1}
r.next() // {value:2}
r.next() // {value:3}
r.next() // {value:4}
r.next() // {done:true}
r.next() // {done:true}
r.previous() // {value:4}

next_back() (shorten range of values from the other end)

r.next() // {value:1}
r.next() // {value:2}
r.next_back() // {value:4}
r.next() // {value:3}
r.next_back() // {done:true}

Your proposal mix the semantics of previous and next_back, which seems problematical.


Another important question is how generators could support either of those?

Separate reverse iterator is simple, u just write another generator.

If previous() or next_back(), we need a way to retrieve the direction in the generators. A possible way is using the return value of yield, but we need function.sent to get the first invoking. An alternative may be introducing a separate function.dir meta property. Note it is also discussed in Rust, which propose a optional syntax for generators, but I think meta property is the better solution.

Actually, I wrote an idea about that, it use next_back semantic (though I didn't know Rust DoubleEndedIterator when I wrote it 😅 ).

@dead-claudia
Copy link

@hax It doesn't truncate - it just starts in a different spot. It's otherwise functionally identical to Java's.

Do want to reiterate I'm not beholden to this idea, and I'm still open to alternatives.

@conartist6
Copy link

I'm interested in joining this conversation. I would like for iter-tools to support reverse iteration. The simplest use case I can think of is making it possible to write an O(1) last(iterable) method. If anyone is interested there is some prior art in the space, specifically Lee Byron's proposal which is based on the implementation found in Immutable.js.

@conartist6
Copy link

conartist6 commented Nov 22, 2020

My personal thought is that the best implementation would be one which does not define any new kind of iterator at all. Not Lee's Symbol.reverseIterator (or [Symbol.iterator]().reverse()), nor the more fine-grained iterable[Symbol.iterator]().prev(). I think the best choice would be to simply create a convention for methods which return normal forward iterables over their contents in the backwards direction. This would be similar to how Map and Set offer methods that return iterators, e.g. entries(). The obvious choice would be to call such a method reverse(), but of course this is a non-starter since array already has a method with that name. I therefore suggest reversed(). reversed describes a way of considering an ordered collection of values (or entries). It feels appropriate to a method which does not have any effect. reverse() suggests action or change, and indeed this is what the user should expect on calling a reverse() method.

In such a scenario the only changes to the spec would be adding Array.prototype.reversed, Map.prototype.reversed, Set.prototype.reversed, and perhaps some others that I'm not thinking of.

EDIT: moving this train of thought back the the discussion board as it no longer matches the issue.

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

5 participants