On Wed, Feb 3, 2021 at 4:38 PM Levi Morrison <le...@php.net> wrote:

> Hello, everyone!
>
> This proposal adds two new classes to the SPL:
>
>   - `Spl\ReverseArrayIterator`. It iterates over an array in reverse
> order. It does not duplicate the array.
>   - `Spl\ForwardArrayIterator`. It iterates over an array in forward
> (normal) order. It does not duplicate the array.
>
> They both implement Countable which returns the `count()` of the
> array. The [PR][1] has some examples and discusses why I am proposing
> `ForwardArrayIterator` when there is already `ArrayIterator`, the
> short of which is for performance. There are timing numbers in [one of
> the comments][2].
>
> When it comes time to vote I may merge this into another RFC with
> [`CachedIterable` by Tyson Andre][3], which I recommend readers also
> take a look at. Whether we team up for the RFC vote or not, I wanted
> to get this out there for discussion and review.
>
>   [1]: https://github.com/php/php-src/pull/6535
>   [2]: https://github.com/php/php-src/pull/6535#issuecomment-769179450
>   [3]: https://github.com/php/php-src/pull/6655
>

Hey Levi,

I like the general idea of having an "ArrayIterator but sane".

That said, I don't think that the ReverseArrayIterator +
ForwardArrayIterator pair of iterators approaches this problem correctly.
There are plenty of iterators that could be run in reverse, and I think it
would be silly to create two classes for each of them. E.g. if we introduce
an ObjectPropertyIterator, should there be both
ForwardObjectPropertyIterator and ReverseObjectPropertyIterator? I don't
think so.

I think the correct abstraction for bidirectional iterators is to introduce
an interface

// Or "ReversibleIterator"
interface BidrectionalIterator extends Iterator {
    public function prev(): void;
    public function end(): void;
}

and then a class along the lines of:

class ReverseIterator implements BidirectionalIterator {
    public function __construct(private BidirectionalIterator $iter) {}

    public function next() { $this->iter->prev(); }
    // etc.
}

This would replace "new ReverseArrayIterator($array)" with "new
ReverseIterator(new ArrayIterator($array))", but in a way that is general,
and composes.

Regards,
Nikita

Reply via email to