Re: "Reader" as alternative to Iterator
| From: | Niklas Keller | Date: | Mon, 03 Jul 2017 07:09:44 +0000 |
| Subject: | Re: "Reader" as alternative to Iterator | ||
| References: | 1 2 3 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-99699@lists.php.net to get a copy of this message | ||
2017-07-03 4:49 GMT+02:00 Andreas Hennings <andreas@dqxtech.net>:
> Well, on a current project I made an attempt to write different
> adapters in userland.
> I finally decided that the clutter is not worth.
> So for this project I wrote everything as "readers", and not as iterators.
>
> With a native solution, one could do this:
>
> function generate() {
> yield 'a';
> yield 'b';
> yield 'c';
> }
>
> $it = generate();
>
> while (FALSE !== $v = $it->read()) {
> print $v . "\n";
> }
>
> With a userland adapter, the code would read like this:
>
> function generate() {
> yield 'a';
> yield 'b';
> yield 'c';
> }
>
> $it = generate();
>
> // This is the added line.
> $reader = new IteratorReaderAdapter($it);
>
> while (FALSE !== $v = $reader->read()) {
> print $v . "\n";
> }
>
>
> This does add clutter and performance overhead.
> In this example I'd say this is acceptable / survivable.
>
> In the project I was working on, I have multiple layers of "readers":
> - One layer to read raw data from a CSV file.
> - One layer to re-key the rows by column labels.
> - One layer to turn each row into an object, with structured
> properties instead of just string cells.
>
> With the "reader" approach, for each layer I would have one "reader
> provider" class and one "reader" class per layer.
> (In fact I have much more, but let's keep it simple)
> Generator syntax would allow to have only one class per layer.
> But with the additional adapter, we again increase the number of classes.
> (I wanted dedicated reader classes for different return types, e.g.
> one "RowReader", one "AssocReader", one "ObjectReader". So here I
> would need one adapter class per type. But let's focus on the simple
> case, where you can use the same reader class.)
>
> In addition to more classes and more function calls (performance), the
> adapters also make stack traces heavier to look at.
>
> Overall, for this project, I decided that it was not worth it.
>
> The main purpose of the generator syntax is to simplify the code. The
> need for userland adapters defeated this purpose.
> Native readers would have made generators worthwhile for my use case.
>
> The idea of "dedicated reader types" e.g. Reader<MyClass> could be
> added to "Open questions"..
Hey Andreas,
what you're trying to do here seems to be premature optimization. While you
save a bunch of method calls, your I/O will be the actual bottleneck there.
It's entirely fine to implement such logic in userland.
Amp has a similar interface for its streams, but those have only
string|null as types. If you want to allow all values, you either need a
second method or need to wrap all values in an object.
http://amphp.org/byte-stream/#inputstream +
http://amphp.org/amp/iterators/#iterator-consumption
Regards, Niklas