On Wed, Jun 6, 2012 at 10:55 AM, Gustavo Lopes <glo...@nebm.ist.utl.pt> wrote: > On Tue, 5 Jun 2012 19:35:14 +0200, Nikita Popov wrote: >> >> >> Before going any further I'd like to get some comments about what you >> think of adding generator support to PHP. >> > > I approve. > > A few comments on the current RFC: > > * The RFC is too vague. Yup, it's not yet complete.
> current() and key() should return false when !valid() Are you sure about that? The Iterator::current() docs don't specify anything, but the Iterator::key() docs say that it should return NULL on failure. Checking on the first spl class that came to my mind SplFixedArray also returns NULL when it is out of elements. My personal preference would be to throw exceptions if those two methods are called after the generator was closed (as calling them is clearly an error, isn't it?), but I see that this would be inconsistent with the usual iterator behavior. > next() is underspecified. Not sure what exactly you mean. next() really doesn't do much more than resuming the generator. What should I add additionally about it? > valid() refers to a section that doesn't exist. Yes, sorry, I hadn't yet written it. I now added it at https://wiki.php.net/rfc/generators#closing_a_generator. > And if you cannot implement rewind(), doing nothing is not an option. I was thinking of the Generator as a NoRewindIterator, which also simply does nothing when rewind() is called on it. This allows you to start traversing the iterator in one loop and continue traversing it in another loop: function *allNaturalNumbers() { for ($i = 0; ; ++$i) { yield $n; } } $numbers = allNaturalNumbers(); echo 'First loop:', "\n"; foreach ($numbers as $n) { echo $n, "\n"; if ($n == 3) break; } echo 'Second loop:', "\n"; foreach ($numbers as $n) { echo $n, "\n"; if ($n == 6) break; } This would output: First loop: 1 2 3 Second loop: 4 5 6 Generators in Python behave the same way. (To be fair though Python generally has no notion of rewinding an iterator, so all iterators in Python act like that.) I don't know whether that behavior is of any use, so I'll gladly change the behavior to throwing an exception if that's more desirable. > In fact, if you can't implement Iterator in full, you should implement > Traversable instead. Not sure whether the lack of rewinding behavior really disqualifies it to use the Iterator interface. I think having the internal iteration methods exposed is quite handy, especially if you consider their use as coroutines, where you often want to call the iteration interface manually and not using a foreach loop. > RewindableGenerator could perhaps implement Iterator though -- but I find > the nature of RewindableGenerator very strange. Whether an iterator is > rewindable or not seems to be related to the nature of the generator (e.g., > is it reading packets from the network). It's not something you can wrap a > non-rewindable generator and expect it to work. So it's a sort of unsafe > operation, like a cast in C. Yes, agree with that. > * Overall, the RFC is very underspecified. We never have a formal > description of what a generator is and exact semantics of it. There is no > reference to exceptions. What to do if the generator returns function. If > the generator can be a function method. Yes, the RFC is only a stub, it's not complete yet. But to answer your questions: * Exceptions can be thrown from generators as always. * Not sure what you mean by "generator returns function". What would be that problem with that? * Generators can be methods, as shown in the example in the Introduction section. Closures can also be generators. > I suppose this is a work in progress and that you just want to gauge the > general interest, and I hope you take these considerations into account. Yup, thanks for your comments! Nikita -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php