HaxeFoundation / haxe-evolution

Repository for maintaining proposal for changes to the Haxe programming language
111 stars 58 forks source link

[PROPOSAL] Iterator Improvements (Step, Reverse, Float) #104

Open EliteMasterEric opened 1 year ago

EliteMasterEric commented 1 year ago

I'd like to see more functionality for iterators, inspired by Ruby.

// Standard IntIterator
for (i in (0...10))
  trace(i); // 1, 2, 3, 4, 5...

// PROPOSALS

// Reverse Iterator
for (i in (10...0))
  trace(i); // 10, 9, 8, 7, 6

// Step Iterator
for (i in (0...10).step(2))
  trace(i); // 0, 2, 4, 6, 8

// FloatIterator with Step
// Compiler type-checks min and max to determine if it is an Int or a Float before choosing an iterator.
for (i in (5.0...7.5).step(0.1))
  trace(i); // 5.0, 5.1, 5.2, 5.3, 5.4, ...

I was actually able to implement step(value:Int):IntIterator locally without modifying compilation, but reverse and FloatIterator would require compiler changes (I got a "Cannot iterate backwards" error)

This is pre-draft, but if nobody has any obvious problems with it I will write up a more formal proposal

kLabz commented 1 year ago

This can "easily" be implemented on user side, like it was done there: https://github.com/RealyUniqueName/Iterators

Jarrio commented 1 year ago

To continue the conversation from the issue, sure it "can" be implemented by the user. But something like a simple reverse iterator seems like an unnecessary thing to "require" a custom library for. Where the lacking of one suggests a user do array.reverse() before looping which is just an unnecessary step to begin with when all targets support reverse iteration

Simn commented 1 year ago

There's a long-standing tradition that whenever reverse iteration comes up, someone points out the --> operator:

function main() {
    var i = 10;
    while (i --> 0) {
        trace(i);
    }
}
tobil4sk commented 1 year ago

I suppose an issue with the reverse iterator is that it could be used with values that are unknown at compile time, e.g.

final x = getSomeInt();
// Forward or Reverse Iterator ?
for (i in (10...x))
  trace(i); // 10, ??, ??, ...

In this case, the code would have to decide at runtime which direction the iterator has to go in. This would make compile time optimisation much more complicated (i.e. inlined iterators, loop unrolling, etc.). It might result in having to generate 2 code paths for each for loop, one for the forward case and one for the backward case, which is obviously not ideal. This makes repurposing the existing x...y syntax for reverse iterators quite hard to justify.

nanjizal commented 1 year ago

my iteration lib may also be useful for some, thinking of putting on haxelib soon so improvements welcome, especially from Rudy I have not looked into his lib yet, but I am sure it will be good. ( the last part of my readme is offtopic just experimental and I may move to a branch ).

https://github.com/nanjizal/iterMagic