# [VOTE] Generators

- Thread: https://externals.io/message/62486
- Original archive: https://news-web.php.net/php.internals/62486
- Started by Nikita Popov on 2012-08-25T16:10:52+00:00
- Messages: 26
- Page 1 of 2: messages 1 to 25 (25 per page, add `?page=N` to the URL)
- Next page: https://externals.io/message/62486.md?page=2
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #62486 — Nikita Popov — 2012-08-25T16:10:52+00:00

URL: https://externals.io/message/62486#62486

Hi internals!

I think the generators RFC has been discussed thoroughly enough by
now, so I opened the vote:

    https://wiki.php.net/rfc/generators#vote

Thanks,
Nikita

---

## #62531 — Stas Malyshev — 2012-08-26T20:25:41+00:00

URL: https://externals.io/message/62486#62531 · In reply to: #62486

Hi!

> I think the generators RFC has been discussed thoroughly enough by
> now, so I opened the vote:
> 
>     https://wiki.php.net/rfc/generators#vote

I think it's fine but I'd still like to put forward a proposal to
reconsider the requirement for parentheses in syntax like this:

$data = (yield $value);

I don't see how it's particularly useful in this case, or in any case
except for the array(), in which case one would want to always use
parens to make the code clear, but I don't think we need to make it
mandated everywhere just to cover this one (and pretty rare) case. Is
there a technical reason to do that?
-- 
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

---

## #62568 — Nikita Popov — 2012-08-27T17:59:47+00:00

URL: https://externals.io/message/62486#62568 · In reply to: #62531

> Hi!
>
> > […]
>
> I think it's fine but I'd still like to put forward a proposal to
> reconsider the requirement for parentheses in syntax like this:
>
> $data = (yield $value);
>
> I don't see how it's particularly useful in this case, or in any case
> except for the array(), in which case one would want to always use
> parens to make the code clear, but I don't think we need to make it
> mandated everywhere just to cover this one (and pretty rare) case. Is
> there a technical reason to do that?

Yes, the parens are required for technical reasons. For yield-by-ref I
have to distinguish expr_without_variable and variable, which seems to
break the precedence handling. So I end up with lots of s/r conflicts.
I don't know, maybe I just don't the right trick, but I see no way to
support it without parens until we have an AST based parser. If anyone
has a solution to this, I would have no problem dropping the
requirement.

Nikita

PS: And yes, we really need an AST based parser :P

---

## #62581 — Jared Williams — 2012-08-29T16:21:50+00:00

URL: https://externals.io/message/62486#62581 · In reply to: #62486

> -----Original Message-----
> From: Nikita Popov [mailto:nikita.ppv@gmail.com] 
> Sent: 25 August 2012 17:11
> To: PHP internals
> Subject: [PHP-DEV] [VOTE] Generators
> 
> Hi internals!
> 
> I think the generators RFC has been discussed thoroughly 
> enough by now, so I opened the vote:
> 
>     https://wiki.php.net/rfc/generators#vote
> 
> Thanks,
> Nikita
> 

Hi,
	Just discovered another seg fault. 
When iterating over a generator that returns references twice it
causes a seg fault.

function &bind(array $keys, array &$row)
{
	foreach($keys as $key)
		yield $key => $row[$key];
}

$row = [];
$it = bind(['a', 'b'], $row);

foreach($it as $key => &$ref)
	echo $key;
echo "\n";
foreach($it as $key => &$ref)
	echo $key;



Jared

---

## #62582 — Nikita Popov — 2012-08-29T18:52:57+00:00

URL: https://externals.io/message/62486#62582 · In reply to: #62581

On Wed, Aug 29, 2012 at 6:21 PM, Jared Williams
<jared.williams1@ntlworld.com> wrote:
>
>
> > […]
>
> Hi,
>         Just discovered another seg fault.
> When iterating over a generator that returns references twice it
> causes a seg fault.
>
> function &bind(array $keys, array &$row)
> {
>         foreach($keys as $key)
>                 yield $key => $row[$key];
> }
>
> $row = [];
> $it = bind(['a', 'b'], $row);
>
> foreach($it as $key => &$ref)
>         echo $key;
> echo "\n";
> foreach($it as $key => &$ref)
>         echo $key;

Thanks, this is now fixed. It'll throw an exception now, saying that
you can't traverse an already closed generator.

Nikita

---

## #62583 — Derick Rethans — 2012-08-29T20:10:52+00:00

URL: https://externals.io/message/62486#62583 · In reply to: #62582

> > […]
> 
> Thanks, this is now fixed. It'll throw an exception now, saying that
> you can't traverse an already closed generator.

Nothing in the core throws an exception, why would this?!

cheers,
Derick

-- 
http://derickrethans.nl | http://xdebug.org
Like Xdebug? Consider a donation: http://xdebug.org/donate.php
twitter: @derickr and @xdebug
Posted with an email client that doesn't mangle email: alpine

---

## #62584 — Stas Malyshev — 2012-08-29T20:47:45+00:00

URL: https://externals.io/message/62486#62584 · In reply to: #62583

Hi!

> > […]
> 
> Nothing in the core throws an exception, why would this?!

I'd rather have it skip foreach, maybe producing a warning/notice. It'd
otherwise also be only place generators throw exceptions, which is a bit
unexpected.
-- 
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

---

## #62585 — Nikita Popov — 2012-08-29T20:48:12+00:00

URL: https://externals.io/message/62486#62585 · In reply to: #62583

> 
>
> > […]
>
> Nothing in the core throws an exception, why would this?!

To my knowledge all iterator-related functionality is supposed to
throw exceptions (as it is a feature related to the object oriented
part of PHP). At leas this is what a quick search of the code base
gave me. (See http://lxr.php.net/xref/PHP_TRUNK/ext/spl/spl_dllist.c#1248
for example).

Nikita

---

## #62586 — Gustavo Lopes — 2012-08-29T20:49:57+00:00

URL: https://externals.io/message/62486#62586 · In reply to: #62583

> 
>
> > […]
>
> Nothing in the core throws an exception, why would this?!
>

This is not accurate. All the iterators throw exceptions on similar  
situations. Generators are iterators, so I see no deviation from the norm  
here.

-- 
Gustavo Lopes

---

## #62587 — Derick Rethans — 2012-08-29T21:19:44+00:00

URL: https://externals.io/message/62486#62587 · In reply to: #62585

> 
> > […]
> 
> To my knowledge all iterator-related functionality is supposed to
> throw exceptions (as it is a feature related to the object oriented
> part of PHP). At leas this is what a quick search of the code base
> gave me. (See http://lxr.php.net/xref/PHP_TRUNK/ext/spl/spl_dllist.c#1248
> for example).

"ext/spl" - SPL is not *core* language. The generators are. Don't throw 
exceptions from core features!

Derick

---

## #62588 — Hannes Magnusson — 2012-08-29T21:50:12+00:00

URL: https://externals.io/message/62486#62588 · In reply to: #62587

> 
>
> > […]
>
> "ext/spl" - SPL is not *core* language. The generators are. Don't throw
> exceptions from core features!

In general I agree with core language features shouldn't be throwing
exceptions...
But SPL definitely should never have been its own extension and most
of it should have been core language features - and throwing
exceptions in many of those cases makes perfect sense.

We also have the case of IteratorAggregate throwing exception (which
is a *core* language feature, not defined in ext/spl):

$ ./sapi/cli/php -r 'class foo implements IteratorAggregate { function
getIterator() { return new stdclass; } } foreach(new foo as $bar) {}'

Fatal error: Uncaught exception 'Exception' with message 'Objects
returned by foo::getIterator() must be traversable or implement
interface Iterator' in Command line code:1
Stack trace:
#0 Command line code(1): unknown()
#1 {main}
  thrown in Command line code on line 1

-Hannes

---

## #62589 — Pierre Joye — 2012-08-29T21:52:48+00:00

URL: https://externals.io/message/62486#62589 · In reply to: #62587

hi!



> "ext/spl" - SPL is not *core* language. The generators are. Don't throw
> exceptions from core features!

I would not have a problem with exceptions here. It is much cleaner
than yet another warning.

Cheers,
-- 
Pierre

@pierrejoye | http://blog.thepimp.net | http://www.libgd.org

---

## #62591 — Yasuo Ohgaki — 2012-08-29T23:07:50+00:00

URL: https://externals.io/message/62486#62591 · In reply to: #62589

Hi,

2012/8/30 Pierre Joye <pierre.php@gmail.com>:
> hi!
>
> 
>
> > […]
>
> I would not have a problem with exceptions here. It is much cleaner
> than yet another warning.

But we have errorException for errors since PHP 5.1.
http://jp.php.net/errorException

Are there any technical reasons not to have exception?
If there are, we should use error. If not, more arguments.

BTW, I would like to change errorException behavior.
It removes output buffer and make it less useful for error
handling. I'll post new thread for it when I have time.

Regards,

--
Yasuo Ohgaki
yohgaki@ohgaki.net

---

## #62593 — Derick Rethans — 2012-08-30T08:27:50+00:00

URL: https://externals.io/message/62486#62593 · In reply to: #62584

> > […]
> 
> I'd rather have it skip foreach, maybe producing a warning/notice. 
> It'd otherwise also be only place generators throw exceptions, which 
> is a bit unexpected.

Indeed. Even though yield/generator is an iterator *internally*, 
nothing on the language syntax side hints at that. Nothing even 
indicates you're using "OO" there.

This is unlike the SplIterators where are you are clearly constructing 
fancy objects.

cheers,
Derick

-- 
http://derickrethans.nl | http://xdebug.org
Like Xdebug? Consider a donation: http://xdebug.org/donate.php
twitter: @derickr and @xdebug
Posted with an email client that doesn't mangle email: alpine

---

## #62595 — Derick Rethans — 2012-08-30T08:37:45+00:00

URL: https://externals.io/message/62486#62595 · In reply to: #62591

> 2012/8/30 Pierre Joye <pierre.php@gmail.com>:
> > […]
> 
> But we have errorException for errors since PHP 5.1.
> http://jp.php.net/errorException
> 
> Are there any technical reasons not to have exception?

That is a different discussion: 
http://thread.gmane.org/gmane.comp.php.devel/74941

Right now, language syntax does not throw exceptions, so until we have 
*consensus* on error handling/reporting/exceptions, the new yield 
keyword with generators should *not* throw exceptions either!

cheers,
Derick

-- 
http://derickrethans.nl | http://xdebug.org
Like Xdebug? Consider a donation: http://xdebug.org/donate.php
twitter: @derickr and @xdebug
Posted with an email client that doesn't mangle email: alpine

---

## #62596 — Derick Rethans — 2012-08-30T08:39:14+00:00

URL: https://externals.io/message/62486#62596 · In reply to: #62586

> 
> 
> > […]
> 
> This is not accurate. All the iterators throw exceptions on similar 
> situations. Generators are iterators, so I see no deviation from the 
> norm here.

Nothing shows that they are. In any example I saw, I don't even see any 
OO syntax/functionality. For me, "yield" is a core syntax *keyword*, and 
hence: no exceptions.

cheers,
Derick

-- 
http://derickrethans.nl | http://xdebug.org
Like Xdebug? Consider a donation: http://xdebug.org/donate.php
twitter: @derickr and @xdebug
Posted with an email client that doesn't mangle email: alpine

---

## #62597 — Andrew Faulds — 2012-08-30T09:35:55+00:00

URL: https://externals.io/message/62486#62597 · In reply to: #62596

Derick Rethans <derick@php.net> wrote:
>Nothing shows that they are. In any example I saw, I don't even see any
>
>OO syntax/functionality. For me, "yield" is a core syntax *keyword*,
>and 
>hence: no exceptions.
>

I was unware PHP was a purist, non-OOP language. What is "OO syntax" anyway? Why can the core not use high-level language constructs too?

Yield is core syntax, but it produces a function returning a generator, which is an object, and since Iterators use Exceptions, it would be stupid for Generators, which *are* a class of Iterator, not to. 
-- 
Sent from my Android phone with K-9 Mail.
Andrew Faulds
http://ajf.me/

---

## #62598 — Lester Caine — 2012-08-30T11:16:25+00:00

URL: https://externals.io/message/62486#62598 · In reply to: #62597

Andrew Faulds wrote:
>
> Derick Rethans<derick@php.net>  wrote:
> > […]
> I was unware PHP was a purist, non-OOP language. What is "OO syntax" anyway? Why can the core not use high-level language constructs too?
>
> Yield is core syntax, but it produces a function returning a generator, which is an object, and since Iterators use Exceptions, it would be stupid for Generators, which*are*  a class of Iterator, not to.

Actually - shouldn't the discussion on use of Exceptions be sorted out prior to 
adding them piecemeal into new functions. If I had a vote I'd certainly ask that 
any implementation of generators respected the 'core' code practices. Iterators 
are simply an add-on in my design manual and can be avoided - as can yield - but 
yield is being brought in at a level where it is more invasive?

Error handling is another growing minefield and needs to be tidied up before 
this sort of creep makes it impossible to remove if that is the preferred 
option? There needs to be a formal agreement on Exceptions before they are 
pushed out further.

-- 
Lester Caine - G8HFL
-----------------------------
Contact - http://lsces.co.uk/wiki/?page=contact
L.S.Caine Electronic Services - http://lsces.co.uk
EnquirySolve - http://enquirysolve.com/
Model Engineers Digital Workshop - http://medw.co.uk
Rainbow Digital Media - http://rainbowdigitalmedia.co.uk

---

## #62599 — Nikita Popov — 2012-08-30T14:04:28+00:00

URL: https://externals.io/message/62486#62599 · In reply to: #62593

> 
>
> > […]
>
> Indeed. Even though yield/generator is an iterator *internally*,
> nothing on the language syntax side hints at that. Nothing even
> indicates you're using "OO" there.
>
> This is unlike the SplIterators where are you are clearly constructing
> fancy objects.

In their most trivial use (i.e. just sticking them into foreach) you
won't notice that generator objects are actually, well, objects. But
still you can work with them as objects and they also expose the
Iterator API. E.g. you can call $gen->rewind() and this will throw an
Exception (if it isn't rewindable at the moment). Do you disagree that
this should throw an exception? Should it throw an error instead? If
not, then why would the same `rewind()` call done internally in foreach
not also throw an Exception? Why would that throw an error instead?
It's two times the same thing, just invoked slightly different.

Nikita

---

## #62633 — Nikita Popov — 2012-09-01T16:02:40+00:00

URL: https://externals.io/message/62486#62633 · In reply to: #62486

> Hi internals!
>
> I think the generators RFC has been discussed thoroughly enough by
> now, so I opened the vote:
>
>     https://wiki.php.net/rfc/generators#vote
>
> Thanks,
> Nikita

The vote ended with 24 in favor and one against. As such the RFC is accepted.

If somebody could give me Zend karma I can merge the branch :)

Nikita

---

## #62634 — Lester Caine — 2012-09-01T17:09:21+00:00

URL: https://externals.io/message/62486#62634 · In reply to: #62633

----- Original message -----
> On Sat, Aug 25, 2012 at 6:10 PM, Nikita Popov <nikita.ppv@gmail.com>
> wrote:
> > […]
> 
> The vote ended with 24 in favor and one against. As such the RFC is
> accepted.
> 
> If somebody could give me Zend karma I can merge the branch :)

Now are you just going to blast everything in are take note of the objections to exceptions? 
I still think this needs the documentation completely reworked without the incorrect examples as to why it was supposedly needed!

---

## #62635 — Gustavo Lopes — 2012-09-01T18:14:17+00:00

URL: https://externals.io/message/62486#62635 · In reply to: #62633

On Sat, 01 Sep 2012 18:02:40 +0200, Nikita Popov <nikita.ppv@gmail.com>  
wrote:

> The vote ended with 24 in favor and one against. As such the RFC is  
> accepted.
>

I've merged Nikita's branch in 53351d0.

As to the "exception objection": the behavior of throwing exceptions on  
illegal state was written on the RFC when voting opened, and the RFC was  
accepted almost unanimously. As the proposal was accepted as such, I saw  
no valid reason not to merge. In fact, changing the proposal after it was  
voted on would be much more objectionable.

Derick argues this is some sort of tacit change of the design rules of the  
language, with the objection against exception throwing relying also on  
the user's ignorance that generators return a Generator object (though he  
also chose not to vote against the proposal). I don't find his arguments  
persuasive, but, in any case, the issue can be adjudicated by the  
community through an RFC that establishes either a clear general policy  
for exception throwing or handles just this particular case.

-- 
Gustavo Lopes

---

## #62651 — Stas Malyshev — 2012-09-02T01:46:30+00:00

URL: https://externals.io/message/62486#62651 · In reply to: #62635

Hi!

> illegal state was written on the RFC when voting opened, and the RFC was  
> accepted almost unanimously. As the proposal was accepted as such, I saw  
> no valid reason not to merge. In fact, changing the proposal after it was  
> voted on would be much more objectionable.

I definitely did not agree to using exceptions, though I support the
rest of it. I'm completely fine with merging it but just for the record
I'd like to note that accepting it doesn't mean we will not tweak it or
change some fine details of it - like how we handle some error situations.
-- 
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

---

## #62674 — Derick Rethans — 2012-09-02T17:10:40+00:00

URL: https://externals.io/message/62486#62674 · In reply to: #62651

> > […]
> 
> I definitely did not agree to using exceptions, though I support the
> rest of it.

Same here.

> I'm completely fine with merging it but just for the record I'd like 
> to note that accepting it doesn't mean we will not tweak it or change 
> some fine details of it - like how we handle some error situations.

Right, so lets remove that exception throwing!

cheers,
Derick

---

## #62707 — Pierre Joye — 2012-09-03T07:52:10+00:00

URL: https://externals.io/message/62486#62707 · In reply to: #62674

hi Derick,


> 
>
> > […]
>
> Same here.
>
> > […]
>
> Right, so lets remove that exception throwing!

Let clear that topic once and for all (almost) instead.

I think some guidance to help to chose on a case by base whether
exceptions should be used or not. Let discussion that in the other
thread.

Cheers,
-- 
Pierre

@pierrejoye | http://blog.thepimp.net | http://www.libgd.org

---

Next page: https://externals.io/message/62486.md?page=2
