Closed conartist6 closed 2 years ago
@conartist6
First it's not clear what you really proposed, do you propose Array.prototype.reversed()
returns a reversed Array ? If that, Array.prototype.toReversed()
has already been included in the official proposal: https://github.com/tc39/proposal-change-array-by-copy .
But there is no Set/Map.prototype.toReversed()
and I feel it will never be, because it seems no use cases to just reverse the order of Map/Set. An iterator give reverse iteration order might enough.
Or, you may propose it returns an iterator? or iterable? If that, it seems have no much difference with reverse iterator proposal.
reverseIterate(slice([1, 2, 3], 0, 2))
slice(reverseIterate(array), 0, 2)
Order of coz matters. Pipeline or method chaining could make it much clear:
// OOP style
Sequence.of(1, 2, 3).slice(0, 2).toReversed().toArray() // expect [2, 1]
Sequence.of(1, 2, 3).toReversed().slice(0, 2).toArray() // expect [3, 2]
// FP style with F# style pipeline
seqOf(1, 2, 3) |> slice(0, 2) |> reversed |> Array.from // expect [2, 1]
seqOf(1, 2, 3) |> reversed |> slice(0, 2) |> Array.from // expect [3, 2]
Or, maybe you want reversed
always means reverse the upstream source, so both return [3, 2]
? It's possible, but I never know and use libraries design like that, and it bring the other issues like whether call reversed
two times means double the effect so cancel the reversed, or it's idempotent so still reversed.
If you first slice then reverse, the only way to reverse is by doing
[...sliced].reverse()
.
I guess you mean slice(0, 2)
(assume it give u a iterable, not array) already have the direction?
slice(0, 2)
could be simplified as take(n)
, and actually it means take the first n elements, so it already one-direction and no way to reverse.
If that's what you mean, yes, some iterator helpers already limit the reversibility.
Or in double-ended proposal, iterators always reversible (means u could always call reverse
it), because it just change the end which could be iterated.
There are three type of iterables as double-ended iteration:
take(n)
and takeLast(n)
take(n)
, reverse it will transform it to back-onlytakeLast(n)
, reverse it will transform it to front-onlyHere are the simple result table for common iterators (note, most aggregator methods like toArray
, every
, etc. are direction-neutral so not listed here) :
EDITED: I moved the table to here: https://github.com/tc39/proposal-deiter/issues/1#issuecomment-1019488928
I think that just makes a bigger mess.
Is it a bigger mess? Maybe, but I think it's the nature of reversing iteration, and it's easy to see the pattern in the table.
First it's not clear what you really proposed, do you propose Array.prototype.reversed() returns a reversed Array ?
No, just an generator over the arrays values in reverse order.
But there is no Set/Map.prototype.toReversed() and I feel it will never be, because it seems no use cases to just reverse the order of Map/Set.
Using your own examples anyone who wants to run takeLast
or reduceRight
on data stored in a Map or Set has a use case. I see no reason this usage should be particularly unlikely.
The bulk of my criticism is that the design simply offers nothing of value. If I have to write a completely separate generator implementation based on whether the parameter is provided or not, why should I not just have two completely separate generators?
Why would it be important that I be able to write iter.slice().reverse()
when I could just write iter.reverse().slice()
?
I see no reason this usage should be particularly unlikely.
@conartist6 I mean if Map.p.reverse
returns a new Map. Not mean iterator.
The bulk of my criticism is that the design simply offers nothing of value. If I have to write a completely separate generator implementation based on whether the parameter is provided or not, why should I not just have two completely separate generators?
Because you don't need to write and maintain two generators if the abstraction have the nature of double-ended. You just need write and maintain one.
And, the motivation of deiter is make [first, ..., last] = seq
work, not only for built-ins but also for all userland iterables if they have the nature of double-ended.
Why would it be important that I be able to write iter.slice().reverse() when I could just write iter.reverse().slice()?
Not sure what u mean... I think my previous comment already discuss the importance of the operation order.
I've seen several versions of this proposal and I've already written my own, which you can find here.
I want to bring up my concerns again here, which come from my perspective maintaining iter-tools.
My biggest concern is that you cannot reverse an arbitrary iterable performantly. This is because if you write
reverseIterate(slice([1, 2, 3], 0, 2))
, you've created a problem: the order of operations matters. If you first slice then reverse, the only way to reverse is by doing[...sliced].reverse()
. What most people would expect is actually essentiallyslice(reverseIterate(array), 0, 2)
. Now you could try to invert the order of operations on the fly, but I think that just makes a bigger mess.