<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
    <channel>
        <title>[PHP-DEV] Generators in PHP</title>
        <description>Hi internals!

In the last few days I've created a proof of concept implementation
for generators in PHP. It's not yet complete, but the basic
functionality is there:
https://github.com/nikic/php-src/tree/addGeneratorsSupport

The implementation is outlined in the RFC-stub here:
https://wiki.php.net/rfc/generators

Before going any further I'd like to get some comments about what you
think of adding generator support to PHP.

If you don't know what generators are you should have a look at the
&quot;Introduction&quot; section in the above RFC or in the Python documentation
at http://wiki.python.org/moin/Generators.

Nikita

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php</description>
        <link>http://www.serverphorums.com/read.php?7,508120,508120#msg-508120</link>
        <lastBuildDate>Sat, 18 May 2013 19:36:19 +0200</lastBuildDate>
        <generator>Phorum 5.2.18</generator>
        <item>
            <guid>http://www.serverphorums.com/read.php?7,508120,549096#msg-549096</guid>
            <title>Re: [PHP-DEV] Re: Generators in PHP</title>
            <link>http://www.serverphorums.com/read.php?7,508120,549096#msg-549096</link>
            <description><![CDATA[ On Sun, Aug 19, 2012 at 6:03 PM, Derick Rethans &lt;derick@php.net&gt; wrote:<br />
&gt; On Sun, 19 Aug 2012, Nikita Popov wrote:<br />
&gt;<br />
&gt;&gt; On Sun, Aug 19, 2012 at 6:28 AM, Stas Malyshev &lt;smalyshev@sugarcrm.com&gt; wrote:<br />
&gt;&gt; &gt;<br />
&gt;&gt; &gt;&gt; For PHP we would need to have some similar behavior. PHP's current<br />
&gt;&gt; &gt;&gt; exception model is incompatible with GeneratorExitException<br />
&gt;&gt; &gt;&gt; (because PHP does not have BaseExceptions). So what I'd probably do<br />
&gt;&gt; &gt;&gt; instead is monkeypatch a ZEND_RETURN opcode at the current<br />
&gt;&gt; &gt;&gt; execution position and<br />
&gt;&gt; &gt;<br />
&gt;&gt; &gt; Patching opcodes is not a good idea, since opcodes could be cached,<br />
&gt;&gt; &gt; and the cache can be shared between different processes.<br />
&gt;&gt;<br />
&gt;&gt; Patching a single opcode should be okay, because it does not require<br />
&gt;&gt; modification of the op_array. Only execute_data-&gt;opline has to be<br />
&gt;&gt; changed (and the execute data is not shared). The exception handling<br />
&gt;&gt; mechanism currently uses the same technique. It patches an<br />
&gt;&gt; ZEND_HANDLE_EXCEPTION opcode into the current position.<br />
&gt;<br />
&gt; Please do not modify opcodes for running code. That is a ginormous hack<br />
&gt; and it *will* cause problems with some code.<br />
<br />
I don't see how it can cause problems (exception handling works after<br />
all), but I agree that it's better to avoid. Thinking about it again,<br />
there shouldn't be necessity for it. But right now I'm waiting for<br />
laruence to refactor the finally handling code. After that's done I'll<br />
see how to best implement it ;)<br />
<br />
Nikita<br />
<br />
-- <br />
PHP Internals - PHP Runtime Development Mailing List<br />
To unsubscribe, visit: <a href="http://www.php.net/unsub.php" target="_blank"  rel="nofollow">http://www.php.net/unsub.php</a>]]></description>
            <dc:creator>Nikita Popov</dc:creator>
            <category>php-internals</category>
            <pubDate>Sun, 19 Aug 2012 20:20:01 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?7,508120,549069#msg-549069</guid>
            <title>Re: [PHP-DEV] Re: Generators in PHP</title>
            <link>http://www.serverphorums.com/read.php?7,508120,549069#msg-549069</link>
            <description><![CDATA[ On 19/08/12 17:03, Derick Rethans wrote:<br />
&gt; On Sun, 19 Aug 2012, Nikita Popov wrote:<br />
&gt;<br />
&gt;&gt; On Sun, Aug 19, 2012 at 6:28 AM, Stas Malyshev &lt;smalyshev@sugarcrm.com&gt; wrote:<br />
&gt;&gt;&gt;&gt; For PHP we would need to have some similar behavior. PHP's current<br />
&gt;&gt;&gt;&gt; exception model is incompatible with GeneratorExitException<br />
&gt;&gt;&gt;&gt; (because PHP does not have BaseExceptions). So what I'd probably do<br />
&gt;&gt;&gt;&gt; instead is monkeypatch a ZEND_RETURN opcode at the current<br />
&gt;&gt;&gt;&gt; execution position and<br />
&gt;&gt;&gt; Patching opcodes is not a good idea, since opcodes could be cached,<br />
&gt;&gt;&gt; and the cache can be shared between different processes.<br />
&gt;&gt; Patching a single opcode should be okay, because it does not require<br />
&gt;&gt; modification of the op_array. Only execute_data-&gt;opline has to be<br />
&gt;&gt; changed (and the execute data is not shared). The exception handling<br />
&gt;&gt; mechanism currently uses the same technique. It patches an<br />
&gt;&gt; ZEND_HANDLE_EXCEPTION opcode into the current position.<br />
&gt; Please do not modify opcodes for running code. That is a ginormous hack<br />
&gt; and it *will* cause problems with some code.<br />
I can't say much about this in particular, but using hacks and kludges <br />
to implement language features is probably not the best of ideas.<br />
&gt; Derick<br />
&gt;<br />
<br />
<br />
-- <br />
Andrew Faulds<br />
<a href="http://ajf.me/" target="_blank"  rel="nofollow">http://ajf.me/</a><br />
<br />
<br />
-- <br />
PHP Internals - PHP Runtime Development Mailing List<br />
To unsubscribe, visit: <a href="http://www.php.net/unsub.php" target="_blank"  rel="nofollow">http://www.php.net/unsub.php</a>]]></description>
            <dc:creator>Andrew Faulds</dc:creator>
            <category>php-internals</category>
            <pubDate>Sun, 19 Aug 2012 18:10:02 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?7,508120,549068#msg-549068</guid>
            <title>Re: [PHP-DEV] Re: Generators in PHP</title>
            <link>http://www.serverphorums.com/read.php?7,508120,549068#msg-549068</link>
            <description><![CDATA[ On Sun, 19 Aug 2012, Nikita Popov wrote:<br />
<br />
&gt; On Sun, Aug 19, 2012 at 6:28 AM, Stas Malyshev &lt;smalyshev@sugarcrm.com&gt; wrote:<br />
&gt; &gt;<br />
&gt; &gt;&gt; For PHP we would need to have some similar behavior. PHP's current <br />
&gt; &gt;&gt; exception model is incompatible with GeneratorExitException <br />
&gt; &gt;&gt; (because PHP does not have BaseExceptions). So what I'd probably do <br />
&gt; &gt;&gt; instead is monkeypatch a ZEND_RETURN opcode at the current <br />
&gt; &gt;&gt; execution position and<br />
&gt; &gt;<br />
&gt; &gt; Patching opcodes is not a good idea, since opcodes could be cached, <br />
&gt; &gt; and the cache can be shared between different processes.<br />
&gt; <br />
&gt; Patching a single opcode should be okay, because it does not require<br />
&gt; modification of the op_array. Only execute_data-&gt;opline has to be<br />
&gt; changed (and the execute data is not shared). The exception handling<br />
&gt; mechanism currently uses the same technique. It patches an<br />
&gt; ZEND_HANDLE_EXCEPTION opcode into the current position.<br />
<br />
Please do not modify opcodes for running code. That is a ginormous hack <br />
and it *will* cause problems with some code.<br />
<br />
Derick<br />
<br />
-- <br />
<a href="http://derickrethans.nl" target="_blank"  rel="nofollow">http://derickrethans.nl</a> | <a href="http://xdebug.org" target="_blank"  rel="nofollow">http://xdebug.org</a><br />
Like Xdebug? Consider a donation: <a href="http://xdebug.org/donate.php" target="_blank"  rel="nofollow">http://xdebug.org/donate.php</a><br />
twitter: @derickr and @xdebug<br />
<br />
-- <br />
PHP Internals - PHP Runtime Development Mailing List<br />
To unsubscribe, visit: <a href="http://www.php.net/unsub.php" target="_blank"  rel="nofollow">http://www.php.net/unsub.php</a>]]></description>
            <dc:creator>Derick Rethans</dc:creator>
            <category>php-internals</category>
            <pubDate>Sun, 19 Aug 2012 18:10:01 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?7,508120,549001#msg-549001</guid>
            <title>Re: [PHP-DEV] Re: Generators in PHP</title>
            <link>http://www.serverphorums.com/read.php?7,508120,549001#msg-549001</link>
            <description><![CDATA[ On Sun, Aug 19, 2012 at 6:28 AM, Stas Malyshev &lt;smalyshev@sugarcrm.com&gt; wrote:<br />
&gt; Hi!<br />
&gt;<br />
&gt;&gt; For PHP we would need to have some similar behavior. PHP's current<br />
&gt;&gt; exception model is incompatible with GeneratorExitException (because<br />
&gt;&gt; PHP does not have BaseExceptions). So what I'd probably do instead is<br />
&gt;&gt; monkeypatch a ZEND_RETURN opcode at the current execution position and<br />
&gt;<br />
&gt; Patching opcodes is not a good idea, since opcodes could be cached, and<br />
&gt; the cache can be shared between different processes.<br />
<br />
Patching a single opcode should be okay, because it does not require<br />
modification of the op_array. Only execute_data-&gt;opline has to be<br />
changed (and the execute data is not shared). The exception handling<br />
mechanism currently uses the same technique. It patches an<br />
ZEND_HANDLE_EXCEPTION opcode into the current position.<br />
<br />
Nikita<br />
<br />
-- <br />
PHP Internals - PHP Runtime Development Mailing List<br />
To unsubscribe, visit: <a href="http://www.php.net/unsub.php" target="_blank"  rel="nofollow">http://www.php.net/unsub.php</a>]]></description>
            <dc:creator>Nikita Popov</dc:creator>
            <category>php-internals</category>
            <pubDate>Sun, 19 Aug 2012 11:00:02 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?7,508120,548932#msg-548932</guid>
            <title>Re: [PHP-DEV] Re: Generators in PHP</title>
            <link>http://www.serverphorums.com/read.php?7,508120,548932#msg-548932</link>
            <description><![CDATA[ Hi!<br />
<br />
&gt; For PHP we would need to have some similar behavior. PHP's current<br />
&gt; exception model is incompatible with GeneratorExitException (because<br />
&gt; PHP does not have BaseExceptions). So what I'd probably do instead is<br />
&gt; monkeypatch a ZEND_RETURN opcode at the current execution position and<br />
<br />
Patching opcodes is not a good idea, since opcodes could be cached, and<br />
the cache can be shared between different processes.<br />
-- <br />
Stanislav Malyshev, Software Architect<br />
SugarCRM: <a href="http://www.sugarcrm.com/" target="_blank"  rel="nofollow">http://www.sugarcrm.com/</a><br />
(408)454-6900 ext. 227<br />
<br />
-- <br />
PHP Internals - PHP Runtime Development Mailing List<br />
To unsubscribe, visit: <a href="http://www.php.net/unsub.php" target="_blank"  rel="nofollow">http://www.php.net/unsub.php</a>]]></description>
            <dc:creator>Stas Malyshev</dc:creator>
            <category>php-internals</category>
            <pubDate>Sun, 19 Aug 2012 06:30:02 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?7,508120,548693#msg-548693</guid>
            <title>Re: [PHP-DEV] Re: Generators in PHP</title>
            <link>http://www.serverphorums.com/read.php?7,508120,548693#msg-548693</link>
            <description><![CDATA[ On Thu, Aug 9, 2012 at 4:49 AM, Sherif Ramadan &lt;theanomaly.is@gmail.com&gt; wrote:<br />
&gt;&gt;<br />
&gt;&gt; One question, though: It looks based on the voting like finally {} blocks<br />
&gt;&gt; are going in.  So... what should happen in the following situation:<br />
&gt;&gt;<br />
&gt;&gt; function stuff() {<br />
&gt;&gt;   try {<br />
&gt;&gt;     foreach (range(1, 100) as $i) {<br />
&gt;&gt;       yield $i;<br />
&gt;&gt;     }<br />
&gt;&gt;   }<br />
&gt;&gt;   finally {<br />
&gt;&gt;     print &quot;All done&quot;;<br />
&gt;&gt;   }<br />
&gt;&gt; }<br />
&gt;&gt;<br />
&gt;&gt; Does &quot;All done&quot; get printed once, or 101 times?  Similarly:<br />
&gt;&gt;<br />
&gt;&gt; function things() {<br />
&gt;&gt;   $i = 1;<br />
&gt;&gt;   try {<br />
&gt;&gt;     while (true) {<br />
&gt;&gt;       yield $i++;<br />
&gt;&gt;     }<br />
&gt;&gt;   }<br />
&gt;&gt;   finally {<br />
&gt;&gt;     print &quot;All done&quot;;<br />
&gt;&gt;   }<br />
&gt;&gt; }<br />
&gt;&gt;<br />
&gt;&gt; That will run indefinitely.  So will &quot;All done&quot; ever print, or does that<br />
&gt;&gt; finally become unreachable?<br />
&gt;&gt;<br />
&gt;&gt; (I have no clue what the behavior &quot;should&quot; be in these cases, just that it<br />
&gt;&gt; should be sorted out sooner rather than later.)<br />
&gt;&gt;<br />
&gt;<br />
&gt;<br />
&gt; Based on my understanding of both RFCs, I don't see that this would be<br />
&gt; a conflict or lead to unexpected behavior. As stated by the generators<br />
&gt; RFC: &quot;When you first call the generator function ($lines =<br />
&gt; getLinesFromFile($fileName)) the passed argument is bound, but nothing<br />
&gt; of the code is actually executed. Instead the function directly<br />
&gt; returns a Generator object.&quot;.<br />
&gt;<br />
&gt; So in the event we are calling the function stuff(), nothing should<br />
&gt; actually be executed, and as we iterate over the traversable object<br />
&gt; the generator should be &quot;passing control back and forth between the<br />
&gt; generator and the calling code&quot;. This would be indicated by the<br />
&gt; &quot;yield&quot; keyword present in the function. Meaning you should see the<br />
&gt; expected result and finally should only ever be called once in your<br />
&gt; first example.<br />
&gt;<br />
&gt; As for you second example... Obviously if you've created an infinite<br />
&gt; loop you've made everything outside of the loop unreachable, whether<br />
&gt; you're using generators or not.<br />
&gt;<br />
&gt; However, I'll let the author of the RFC provide any clarification or<br />
&gt; corrections where I might be wrong.<br />
<br />
Ooops, accidentially hit &quot;Send&quot; too early. So again:<br />
<br />
Yes, that is basically right. The one interesting case that arises<br />
when using generators is what happens when you close a generator<br />
before it is finished. E.g. in the function mentioned above:<br />
<br />
function stuff() {<br />
    try {<br />
        foreach (range(1, 100) as $i) {<br />
            yield $i;<br />
        }<br />
    } finally {<br />
        print &quot;All done&quot;;<br />
    }<br />
}<br />
<br />
If you now create the generator, do 50 iterations and then close it:<br />
<br />
$gen = stuff();<br />
foreach (stuff() as $i) {<br />
    if ($i == 50) break;<br />
}<br />
unset($gen);<br />
<br />
In that case the code (normally) would never reach the &quot;finally&quot;<br />
clause, simply because it isn't resumed anymore.<br />
<br />
Python solved this problem by throwing a GeneratorExitException into<br />
the generator when it is closed. So when unset($gen) is called an<br />
exception is thrown at the yield-stackframe and the generator resumed.<br />
This then invokes usual exception bubbling and runs finally clauses.<br />
When the GeneratorExitException bubbles out of the generator function<br />
is implicitly caught and discarded.<br />
<br />
For PHP we would need to have some similar behavior. PHP's current<br />
exception model is incompatible with GeneratorExitException (because<br />
PHP does not have BaseExceptions). So what I'd probably do instead is<br />
monkeypatch a ZEND_RETURN opcode at the current execution position and<br />
resume the generator. This would then invoke any finally clauses<br />
through the usual processes. This should be a very transparent process<br />
that &quot;just works&quot; without the need for any strange exception hacks.<br />
<br />
Nikita<br />
<br />
-- <br />
PHP Internals - PHP Runtime Development Mailing List<br />
To unsubscribe, visit: <a href="http://www.php.net/unsub.php" target="_blank"  rel="nofollow">http://www.php.net/unsub.php</a>]]></description>
            <dc:creator>Nikita Popov</dc:creator>
            <category>php-internals</category>
            <pubDate>Sat, 18 Aug 2012 15:40:06 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?7,508120,548692#msg-548692</guid>
            <title>Re: [PHP-DEV] Re: Generators in PHP</title>
            <link>http://www.serverphorums.com/read.php?7,508120,548692#msg-548692</link>
            <description><![CDATA[ On Thu, Aug 9, 2012 at 4:49 AM, Sherif Ramadan &lt;theanomaly.is@gmail.com&gt; wrote:<br />
&gt;&gt;<br />
&gt;&gt; One question, though: It looks based on the voting like finally {} blocks<br />
&gt;&gt; are going in.  So... what should happen in the following situation:<br />
&gt;&gt;<br />
&gt;&gt; function stuff() {<br />
&gt;&gt;   try {<br />
&gt;&gt;     foreach (range(1, 100) as $i) {<br />
&gt;&gt;       yield $i;<br />
&gt;&gt;     }<br />
&gt;&gt;   }<br />
&gt;&gt;   finally {<br />
&gt;&gt;     print &quot;All done&quot;;<br />
&gt;&gt;   }<br />
&gt;&gt; }<br />
&gt;&gt;<br />
&gt;&gt; Does &quot;All done&quot; get printed once, or 101 times?  Similarly:<br />
&gt;&gt;<br />
&gt;&gt; function things() {<br />
&gt;&gt;   $i = 1;<br />
&gt;&gt;   try {<br />
&gt;&gt;     while (true) {<br />
&gt;&gt;       yield $i++;<br />
&gt;&gt;     }<br />
&gt;&gt;   }<br />
&gt;&gt;   finally {<br />
&gt;&gt;     print &quot;All done&quot;;<br />
&gt;&gt;   }<br />
&gt;&gt; }<br />
&gt;&gt;<br />
&gt;&gt; That will run indefinitely.  So will &quot;All done&quot; ever print, or does that<br />
&gt;&gt; finally become unreachable?<br />
&gt;&gt;<br />
&gt;&gt; (I have no clue what the behavior &quot;should&quot; be in these cases, just that it<br />
&gt;&gt; should be sorted out sooner rather than later.)<br />
&gt;&gt;<br />
&gt;<br />
&gt;<br />
&gt; Based on my understanding of both RFCs, I don't see that this would be<br />
&gt; a conflict or lead to unexpected behavior. As stated by the generators<br />
&gt; RFC: &quot;When you first call the generator function ($lines =<br />
&gt; getLinesFromFile($fileName)) the passed argument is bound, but nothing<br />
&gt; of the code is actually executed. Instead the function directly<br />
&gt; returns a Generator object.&quot;.<br />
&gt;<br />
&gt; So in the event we are calling the function stuff(), nothing should<br />
&gt; actually be executed, and as we iterate over the traversable object<br />
&gt; the generator should be &quot;passing control back and forth between the<br />
&gt; generator and the calling code&quot;. This would be indicated by the<br />
&gt; &quot;yield&quot; keyword present in the function. Meaning you should see the<br />
&gt; expected result and finally should only ever be called once in your<br />
&gt; first example.<br />
&gt;<br />
&gt; As for you second example... Obviously if you've created an infinite<br />
&gt; loop you've made everything outside of the loop unreachable, whether<br />
&gt; you're using generators or not.<br />
&gt;<br />
&gt; However, I'll let the author of the RFC provide any clarification or<br />
&gt; corrections where I might be wrong.<br />
<br />
Yes, that is basically right. The one interesting case that arises<br />
when using generators is what happens when you close a generator<br />
before it is finished. E.g. in the function mentioned above:<br />
<br />
function stuff() {<br />
    try {<br />
        foreach (range(1, 100) as $i) {<br />
            yield $i;<br />
        }<br />
    } finally {<br />
        print &quot;All done&quot;;<br />
    }<br />
}<br />
<br />
-- <br />
PHP Internals - PHP Runtime Development Mailing List<br />
To unsubscribe, visit: <a href="http://www.php.net/unsub.php" target="_blank"  rel="nofollow">http://www.php.net/unsub.php</a>]]></description>
            <dc:creator>Nikita Popov</dc:creator>
            <category>php-internals</category>
            <pubDate>Sat, 18 Aug 2012 15:40:06 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?7,508120,543923#msg-543923</guid>
            <title>Re: [PHP-DEV] Generators in PHP</title>
            <link>http://www.serverphorums.com/read.php?7,508120,543923#msg-543923</link>
            <description><![CDATA[ hakre wrote:<br />
<br />
 &gt;&gt; Also, currently yield looks very similar to return and I think this<br />
 &gt;&gt; is a nice thing as it is similar semantically. yield($foo) would<br />
 &gt;&gt; give it different semantics, imho.<br />
 &gt;<br />
 &gt; I love this point a lot. Return is very common and yield is some<br />
 &gt; kind of return.<br />
 &gt;<br />
I agree also: yield behaves far more like a return statement than a <br />
function call. (In a sense, a yield is a return that doesn't discard the <br />
current function's execution state.)<br />
<br />
Which (as it happens) reminds me of the difference between<br />
return $foo;<br />
and<br />
return ($foo);<br />
<br />
-- <br />
PHP Internals - PHP Runtime Development Mailing List<br />
To unsubscribe, visit: <a href="http://www.php.net/unsub.php" target="_blank"  rel="nofollow">http://www.php.net/unsub.php</a>]]></description>
            <dc:creator>Morgan L. Owens</dc:creator>
            <category>php-internals</category>
            <pubDate>Fri, 10 Aug 2012 03:10:12 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?7,508120,543919#msg-543919</guid>
            <title>Re: [PHP-DEV] Generators in PHP</title>
            <link>http://www.serverphorums.com/read.php?7,508120,543919#msg-543919</link>
            <description><![CDATA[ Mike Ford wrote:<br />
 &gt;<br />
 &gt; The signposting needn't even be as in-your-face as a generator<br />
 &gt; keyword (either instead of or in addition to function): I could get<br />
 &gt; behind a variation such as:<br />
 &gt;<br />
 &gt; function f($x, $y) yields { ... yield $z; ... }<br />
 &gt;<br />
 &gt; Or even (stretching a bit to re-use an existing keyword!):<br />
 &gt;<br />
 &gt; function f($x, $y) return { ... yield $z; ... }<br />
 &gt;<br />
 &gt; Although I like the concept of generators, I would be -1 for any<br />
 &gt; implementation that doesn't differentiate them in some way from<br />
 &gt; regular functions.<br />
 &gt;<br />
In other words you want to have return-value type-hinting _in one <br />
specific instance_: when calling f() returns a Generator object.<br />
<br />
<br />
<br />
-- <br />
PHP Internals - PHP Runtime Development Mailing List<br />
To unsubscribe, visit: <a href="http://www.php.net/unsub.php" target="_blank"  rel="nofollow">http://www.php.net/unsub.php</a>]]></description>
            <dc:creator>Morgan L. Owens</dc:creator>
            <category>php-internals</category>
            <pubDate>Fri, 10 Aug 2012 03:00:02 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?7,508120,543843#msg-543843</guid>
            <title>Re: [PHP-DEV] Generators in PHP</title>
            <link>http://www.serverphorums.com/read.php?7,508120,543843#msg-543843</link>
            <description><![CDATA[ &gt; Also, currently yield looks very similar to return and I think this is<br />
&gt; a nice thing as it is similar semantically. yield($foo) would give it<br />
&gt; different semantics, imho.<br />
<br />
I love this point a lot. Return is very common and yield is some kind of return.<br />
<br />
<br />
-- <br />
PHP Internals - PHP Runtime Development Mailing List<br />
To unsubscribe, visit: <a href="http://www.php.net/unsub.php" target="_blank"  rel="nofollow">http://www.php.net/unsub.php</a>]]></description>
            <dc:creator>hakre</dc:creator>
            <category>php-internals</category>
            <pubDate>Thu, 09 Aug 2012 23:30:04 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?7,508120,543727#msg-543727</guid>
            <title>Re: [PHP-DEV] Generators in PHP</title>
            <link>http://www.serverphorums.com/read.php?7,508120,543727#msg-543727</link>
            <description><![CDATA[ On Thu, Aug 9, 2012 at 5:59 PM, Andrew Faulds &lt;ajf@ajf.me&gt; wrote:<br />
&gt; yield(), so far as the programmer is concerned, might as well be a function.<br />
&gt; It isn't, strictly speaking, but like other function calls, it suspends<br />
&gt; execution of the function until the called function completes.<br />
&gt;<br />
&gt; So I don't think this is a problem.<br />
<br />
I definitely can see that yield() is a plausible syntax, but I still<br />
think that the normal yield notation is better suited. Another reason<br />
is the following:<br />
<br />
PHP has several constructs with a yield-like syntax. Examples are<br />
&quot;include $file&quot; (and require etc) and &quot;print $string&quot;. Both are<br />
keyword expressions, so they are rather similar to yield.<br />
<br />
On the other hand there are also other constructs which use the<br />
function notation. Like isset(), empty(), etc.<br />
<br />
The main distinction between them is their primary use: Both include<br />
and print are usually used as statements, not as expressions. Writing<br />
$foo = include &quot;bar&quot;; is something you rarely do. So here the<br />
friendlier keyword notation is chosen. isset() and empty() on the<br />
other hand are pretty much always used as expressions (they really<br />
don't make sense as statements). So the function-like syntax is chosen<br />
here, because it causes less ambiguities.<br />
<br />
For yield the same applies. Yield will be primarily used as a<br />
statement. The vast majority of cases will just be<br />
<br />
    yield $someValue;<br />
<br />
The expression use is just secondary here. And even there the<br />
value-less yield (the one that does not need parens) is the most<br />
common case:<br />
<br />
    $data = yield;<br />
<br />
The case where you want to both receive and send at the same time is<br />
rather rare (mostly for trampoline patterns or task scheduling).<br />
<br />
So I think we should not sacrifice the most common cases for slightly<br />
better syntax in the rare cases.<br />
<br />
Also, currently yield looks very similar to return and I think this is<br />
a nice thing as it is similar semantically. yield($foo) would give it<br />
different semantics, imho.<br />
<br />
Nikita<br />
<br />
-- <br />
PHP Internals - PHP Runtime Development Mailing List<br />
To unsubscribe, visit: <a href="http://www.php.net/unsub.php" target="_blank"  rel="nofollow">http://www.php.net/unsub.php</a>]]></description>
            <dc:creator>Nikita Popov</dc:creator>
            <category>php-internals</category>
            <pubDate>Thu, 09 Aug 2012 19:50:02 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?7,508120,543676#msg-543676</guid>
            <title>Re: [PHP-DEV] Generators in PHP</title>
            <link>http://www.serverphorums.com/read.php?7,508120,543676#msg-543676</link>
            <description><![CDATA[ On 09/08/12 16:58, Nikita Popov wrote:<br />
&gt; On Wed, Aug 8, 2012 at 10:55 PM, Andrew Faulds &lt;ajf@ajf.me&gt; wrote:<br />
&gt;&gt; Hmm. This is just a quick thought:<br />
&gt;&gt;<br />
&gt;&gt; Considering the yield syntax will vary about needing () round it, why not<br />
&gt;&gt; make it a &quot;fake&quot; function (language construct).<br />
&gt;&gt;<br />
&gt;&gt; This way it's consistent: yield(), yield($v), yield($k =&gt; $v), $a = yield(),<br />
&gt;&gt; etc.<br />
&gt;&gt;<br />
&gt;&gt; (yield $x) is just messy as an expression. We don't have (isset $x), we have<br />
&gt;&gt; isset($x).<br />
&gt; There are two reasons why I would not choose that syntax:<br />
&gt;<br />
&gt; 1. This would make &quot;yield&quot; look like a functions, without actually<br />
&gt; being a function. PHP has done this in the past quite often and I<br />
&gt; think it was a mistake. It is the reason why people try to write<br />
&gt; empty(someCall()). It looks like a function, so they expect it to<br />
&gt; behave like one. Similarly you also can't do $f = 'empty'; $f($foo),<br />
&gt; which again is confusing to people new to the language.<br />
yield(), so far as the programmer is concerned, might as well be a <br />
function. It isn't, strictly speaking, but like other function calls, it <br />
suspends execution of the function until the called function completes.<br />
<br />
So I don't think this is a problem.<br />
&gt; 2. Other languages that implement generators also use the &quot;yield $foo&quot;<br />
&gt; syntax (and also have the same parentheses requirements). So this<br />
&gt; makes PHP consistent with them.<br />
Doesn't mean we can't lead the way and have a nicer syntax :)<br />
&gt; Nikita<br />
<br />
<br />
-- <br />
Andrew Faulds<br />
<a href="http://ajf.me/" target="_blank"  rel="nofollow">http://ajf.me/</a><br />
<br />
<br />
-- <br />
PHP Internals - PHP Runtime Development Mailing List<br />
To unsubscribe, visit: <a href="http://www.php.net/unsub.php" target="_blank"  rel="nofollow">http://www.php.net/unsub.php</a>]]></description>
            <dc:creator>Andrew Faulds</dc:creator>
            <category>php-internals</category>
            <pubDate>Thu, 09 Aug 2012 18:10:09 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?7,508120,543663#msg-543663</guid>
            <title>Re: [PHP-DEV] Generators in PHP</title>
            <link>http://www.serverphorums.com/read.php?7,508120,543663#msg-543663</link>
            <description><![CDATA[ On Wed, Aug 8, 2012 at 10:55 PM, Andrew Faulds &lt;ajf@ajf.me&gt; wrote:<br />
&gt; Hmm. This is just a quick thought:<br />
&gt;<br />
&gt; Considering the yield syntax will vary about needing () round it, why not<br />
&gt; make it a &quot;fake&quot; function (language construct).<br />
&gt;<br />
&gt; This way it's consistent: yield(), yield($v), yield($k =&gt; $v), $a = yield(),<br />
&gt; etc.<br />
&gt;<br />
&gt; (yield $x) is just messy as an expression. We don't have (isset $x), we have<br />
&gt; isset($x).<br />
<br />
There are two reasons why I would not choose that syntax:<br />
<br />
1. This would make &quot;yield&quot; look like a functions, without actually<br />
being a function. PHP has done this in the past quite often and I<br />
think it was a mistake. It is the reason why people try to write<br />
empty(someCall()). It looks like a function, so they expect it to<br />
behave like one. Similarly you also can't do $f = 'empty'; $f($foo),<br />
which again is confusing to people new to the language.<br />
<br />
2. Other languages that implement generators also use the &quot;yield $foo&quot;<br />
syntax (and also have the same parentheses requirements). So this<br />
makes PHP consistent with them.<br />
<br />
Nikita<br />
<br />
-- <br />
PHP Internals - PHP Runtime Development Mailing List<br />
To unsubscribe, visit: <a href="http://www.php.net/unsub.php" target="_blank"  rel="nofollow">http://www.php.net/unsub.php</a>]]></description>
            <dc:creator>Nikita Popov</dc:creator>
            <category>php-internals</category>
            <pubDate>Thu, 09 Aug 2012 18:00:07 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?7,508120,543413#msg-543413</guid>
            <title>RE: [PHP-DEV] Re: Generators in PHP</title>
            <link>http://www.serverphorums.com/read.php?7,508120,543413#msg-543413</link>
            <description><![CDATA[ &gt; -----Original Message-----<br />
&gt; From: Andrew Faulds [mailto:ajf@ajf.me]<br />
&gt; Sent: 25 July 2012 18:03<br />
<br />
[...]<br />
<br />
&gt; Fact: Adding a new name for a special kind of function as a syntax<br />
&gt; construct is going to cost (possibly unnecessary) time and energy,<br />
&gt; because now you have functions, and weird things that look almost<br />
&gt; like	<br />
&gt; functions but aren't and can only be used to make generators.<br />
<br />
That looks to me like a perfect argument *in favour* of the<br />
&quot;generator&quot; keyword! I'm a very literal kind of person, and I would<br />
absolutely want &quot;weird things that look almost like functions but<br />
[...] can only be used to make generators&quot; to be clearly labelled<br />
as such without having to hunt through the body of the not-quite-<br />
function.<br />
<br />
The signposting needn't even be as in-your-face as a generator<br />
keyword (either instead of or in addition to function): I could get<br />
behind a variation such as:<br />
<br />
   function f($x, $y) yields {<br />
      ...<br />
      yield $z;<br />
      ...<br />
   }<br />
<br />
Or even (stretching a bit to re-use an existing keyword!):<br />
<br />
   function f($x, $y) return {<br />
      ...<br />
      yield $z;<br />
      ...<br />
   }<br />
<br />
Although I like the concept of generators, I would be -1 for any<br />
implementation that doesn't differentiate them in some way from<br />
regular functions.<br />
<br />
Cheers!<br />
<br />
Mike<br />
<br />
-- <br />
Mike Ford,<br />
Electronic Information Developer, Libraries and Learning Innovation,  <br />
Portland PD507, City Campus, Leeds Metropolitan University,<br />
Portland Way, LEEDS,  LS1 3HE,  United Kingdom <br />
E: <a href="mailto:&#109;&#46;&#102;&#111;&#114;&#100;&#64;&#108;&#101;&#101;&#100;&#115;&#109;&#101;&#116;&#46;&#97;&#99;&#46;&#117;&#107;">&#109;&#46;&#102;&#111;&#114;&#100;&#64;&#108;&#101;&#101;&#100;&#115;&#109;&#101;&#116;&#46;&#97;&#99;&#46;&#117;&#107;</a>     T: +44 113 812 4730<br />
<br />
<br />
<br />
<br />
To view the terms under which this email is distributed, please go to <a href="http://disclaimer.leedsmet.ac.uk/email.htm" target="_blank"  rel="nofollow">http://disclaimer.leedsmet.ac.uk/email.htm</a><br />
<br />
-- <br />
PHP Internals - PHP Runtime Development Mailing List<br />
To unsubscribe, visit: <a href="http://www.php.net/unsub.php" target="_blank"  rel="nofollow">http://www.php.net/unsub.php</a>]]></description>
            <dc:creator>Ford, Mike</dc:creator>
            <category>php-internals</category>
            <pubDate>Thu, 09 Aug 2012 12:20:02 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?7,508120,543228#msg-543228</guid>
            <title>Re: Re: [PHP-DEV] Generators in PHP</title>
            <link>http://www.serverphorums.com/read.php?7,508120,543228#msg-543228</link>
            <description><![CDATA[ On 2012-08-09 08:42, Nikita Popov wrote:<br />
&gt;<br />
&gt; Without parenthesis their behavior in array definitions and nested<br />
&gt; yields is ambigous:<br />
&gt;<br />
&gt; array(yield $key =&gt; $value)<br />
&gt; // can be either<br />
&gt; array((yield $key) =&gt; $value)<br />
&gt; // or<br />
&gt; array((yield $key =&gt; $value))<br />
&gt;<br />
&gt; yield yield $key =&gt; $value;<br />
&gt; // can be either<br />
&gt; yield (yield $key) =&gt; $value;<br />
&gt; // or<br />
&gt; yield (yield $key =&gt; $value);<br />
&gt;<br />
&gt; Apart from that particular case there is the general operator<br />
&gt; precedence inclarity, e.g.<br />
&gt;<br />
&gt; yield $foo . $bar;<br />
&gt; // could be<br />
&gt; (yield $foo) . $bar;<br />
&gt; // or<br />
&gt; yield ($foo . $bar);<br />
&gt;<br />
Is this complicating yield a bit too much? All these ambiguities would <br />
go away if 'yield' had the same grammatical status as 'return' - in <br />
other words, if it were treated as a control-flow keyword rather than as <br />
an operator.<br />
<br />
<br />
<br />
-- <br />
PHP Internals - PHP Runtime Development Mailing List<br />
To unsubscribe, visit: <a href="http://www.php.net/unsub.php" target="_blank"  rel="nofollow">http://www.php.net/unsub.php</a>]]></description>
            <dc:creator>Morgan L. Owens</dc:creator>
            <category>php-internals</category>
            <pubDate>Thu, 09 Aug 2012 06:00:02 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?7,508120,543224#msg-543224</guid>
            <title>Re: Re: [PHP-DEV] Re: Generators in PHP</title>
            <link>http://www.serverphorums.com/read.php?7,508120,543224#msg-543224</link>
            <description><![CDATA[ On 2012-08-09 14:25, Larry Garfield wrote:<br />
&gt; On 07/27/2012 07:23 AM, Lester Caine wrote:<br />
&gt;&gt;<br />
&gt;&gt; Nikita - I am looking for a well reasoned argument as to why generator<br />
&gt;&gt; has to be added at all! 'Just because it can be' is not a valid<br />
&gt;&gt; argument, but perhaps you could add to the RFC the performance<br />
&gt;&gt; implication or advantage of what is being proposed. That would at<br />
&gt;&gt; least be some comparison with the current methods of doing the same<br />
&gt;&gt; thing?<br />
&gt;&gt;<br />
&gt;<br />
&gt; Anthony had a very good writeup on generators and how they compare to<br />
&gt; iterators last week:<br />
&gt;<br />
&gt; <a href="http://blog.ircmaxell.com/2012/07/what-generators-can-do-for-you.html" target="_blank"  rel="nofollow">http://blog.ircmaxell.com/2012/07/what-generators-can-do-for-you.html</a><br />
&gt;<br />
&gt; I think that does a good job of laying out the case for generators as<br />
&gt; &quot;low-effort iterators&quot;.<br />
&gt;<br />
I for one am lazy, and would much prefer writing:<br />
&lt;?php<br />
function append_iterator($first, $second)<br />
{<br />
     foreach($first as $i)<br />
     {<br />
         yield $i;<br />
     }<br />
     foreach($second as $i)<br />
     {<br />
         yield $i;<br />
     }<br />
}<br />
?&gt;<br />
<br />
to<br />
<br />
&lt;?php<br />
function append_iterator($first, $second)<br />
{<br />
     if(is_object($first) &amp;&amp; !($first instanceof Iterator))<br />
     {<br />
         $first = (array)$first;<br />
     }<br />
     if(is_array($first))<br />
     {<br />
         $first = new ArrayIterator($first);<br />
     }<br />
     if(is_object($second) &amp;&amp; !($second instanceof Iterator))<br />
     {<br />
         $second = (array)$second;<br />
     }<br />
     if(is_array($second))<br />
     {<br />
         $second = new ArrayIterator($second);<br />
     }<br />
     return new myAppendIterator($first, $second);<br />
}<br />
<br />
class myAppendIterator implements Iterator<br />
{<br />
	private $_state = 0;<br />
	private $_key;<br />
	private $_current;<br />
<br />
	private $first, $second;<br />
<br />
	public function __construct($first, $second)<br />
	{<br />
		$this-&gt;first = $first;<br />
		$this-&gt;second = $second;<br />
	}<br />
<br />
	public function rewind()<br />
	{<br />
		$this-&gt;first-&gt;rewind();<br />
		$this-&gt;second-&gt;rewind();<br />
		$this-&gt;state = 0;<br />
	}<br />
<br />
	public function current()<br />
	{<br />
		return $this-&gt;_current;<br />
	}<br />
<br />
	public function key()<br />
	{<br />
		return $this-&gt;_key;<br />
	}<br />
<br />
	public function next()<br />
	{<br />
		switch($this-&gt;_state)<br />
		{<br />
		case -1:<br />
			return;<br />
		case 0:<br />
			$this-&gt;first-&gt;rewind();<br />
			$this-&gt;_state = 1;<br />
		case 1:<br />
			if($this-&gt;first-&gt;valid())<br />
			{<br />
				$this-&gt;_current = $this-&gt;first-&gt;current();<br />
				$this-&gt;_key = $this-&gt;first-&gt;key();<br />
				$this-&gt;first-&gt;next();<br />
				return;<br />
			}<br />
			else<br />
			{<br />
				$this-&gt;second-&gt;rewind();<br />
				$this-&gt;_state = 2;<br />
			}<br />
		case 2:<br />
			if($this-&gt;second-&gt;valid())<br />
			{<br />
				$this-&gt;_current = $this-&gt;second-&gt;current();<br />
				$this-&gt;_key = $this-&gt;second-&gt;key();<br />
				$this-&gt;second-&gt;next();<br />
				return;<br />
			}<br />
			else<br />
			{<br />
				$this-&gt;_state = -1;<br />
				return;<br />
			}<br />
		}<br />
	}<br />
<br />
	public function valid()<br />
	{<br />
		return $this-&gt;_state != -1;<br />
	}<br />
}<br />
?&gt;<br />
<br />
&gt;<br />
&gt; One question, though: It looks based on the voting like finally {}<br />
&gt; blocks are going in.  So... what should happen in the following situation:<br />
&gt;<br />
&gt; function stuff() {<br />
&gt;    try {<br />
&gt;      foreach (range(1, 100) as $i) {<br />
&gt;        yield $i;<br />
&gt;      }<br />
&gt;    }<br />
&gt;    finally {<br />
&gt;      print &quot;All done&quot;;<br />
&gt;    }<br />
&gt; }<br />
&gt;<br />
&gt; Does &quot;All done&quot; get printed once, or 101 times?  Similarly:<br />
&gt;<br />
&gt; function things() {<br />
&gt;    $i = 1;<br />
&gt;    try {<br />
&gt;      while (true) {<br />
&gt;        yield $i++;<br />
&gt;      }<br />
&gt;    }<br />
&gt;    finally {<br />
&gt;      print &quot;All done&quot;;<br />
&gt;    }<br />
&gt; }<br />
&gt;<br />
&gt; That will run indefinitely.  So will &quot;All done&quot; ever print, or does that<br />
&gt; finally become unreachable?<br />
&gt;<br />
My own gut expectation (the answers that would surprise me the least) <br />
would be (a) once (because the foreach is _inside_ the try block, and <br />
the catch/finally handler is hence _outside_ the loop); and (b) the <br />
finally{} is unreachable (assuming that loop doesn't manage to throw an <br />
exception!) because control flow never gets to the end of the try block.<br />
<br />
<br />
-- <br />
PHP Internals - PHP Runtime Development Mailing List<br />
To unsubscribe, visit: <a href="http://www.php.net/unsub.php" target="_blank"  rel="nofollow">http://www.php.net/unsub.php</a>]]></description>
            <dc:creator>Morgan L. Owens</dc:creator>
            <category>php-internals</category>
            <pubDate>Thu, 09 Aug 2012 05:40:02 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?7,508120,543214#msg-543214</guid>
            <title>Re: [PHP-DEV] Re: Generators in PHP</title>
            <link>http://www.serverphorums.com/read.php?7,508120,543214#msg-543214</link>
            <description><![CDATA[ &gt;<br />
&gt; One question, though: It looks based on the voting like finally {} blocks<br />
&gt; are going in.  So... what should happen in the following situation:<br />
&gt;<br />
&gt; function stuff() {<br />
&gt;   try {<br />
&gt;     foreach (range(1, 100) as $i) {<br />
&gt;       yield $i;<br />
&gt;     }<br />
&gt;   }<br />
&gt;   finally {<br />
&gt;     print &quot;All done&quot;;<br />
&gt;   }<br />
&gt; }<br />
&gt;<br />
&gt; Does &quot;All done&quot; get printed once, or 101 times?  Similarly:<br />
&gt;<br />
&gt; function things() {<br />
&gt;   $i = 1;<br />
&gt;   try {<br />
&gt;     while (true) {<br />
&gt;       yield $i++;<br />
&gt;     }<br />
&gt;   }<br />
&gt;   finally {<br />
&gt;     print &quot;All done&quot;;<br />
&gt;   }<br />
&gt; }<br />
&gt;<br />
&gt; That will run indefinitely.  So will &quot;All done&quot; ever print, or does that<br />
&gt; finally become unreachable?<br />
&gt;<br />
&gt; (I have no clue what the behavior &quot;should&quot; be in these cases, just that it<br />
&gt; should be sorted out sooner rather than later.)<br />
&gt;<br />
<br />
<br />
Based on my understanding of both RFCs, I don't see that this would be<br />
a conflict or lead to unexpected behavior. As stated by the generators<br />
RFC: &quot;When you first call the generator function ($lines =<br />
getLinesFromFile($fileName)) the passed argument is bound, but nothing<br />
of the code is actually executed. Instead the function directly<br />
returns a Generator object.&quot;.<br />
<br />
So in the event we are calling the function stuff(), nothing should<br />
actually be executed, and as we iterate over the traversable object<br />
the generator should be &quot;passing control back and forth between the<br />
generator and the calling code&quot;. This would be indicated by the<br />
&quot;yield&quot; keyword present in the function. Meaning you should see the<br />
expected result and finally should only ever be called once in your<br />
first example.<br />
<br />
As for you second example... Obviously if you've created an infinite<br />
loop you've made everything outside of the loop unreachable, whether<br />
you're using generators or not.<br />
<br />
However, I'll let the author of the RFC provide any clarification or<br />
corrections where I might be wrong.<br />
<br />
-- <br />
PHP Internals - PHP Runtime Development Mailing List<br />
To unsubscribe, visit: <a href="http://www.php.net/unsub.php" target="_blank"  rel="nofollow">http://www.php.net/unsub.php</a>]]></description>
            <dc:creator>Sherif Ramadan</dc:creator>
            <category>php-internals</category>
            <pubDate>Thu, 09 Aug 2012 05:00:02 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?7,508120,543209#msg-543209</guid>
            <title>Re: [PHP-DEV] Re: Generators in PHP</title>
            <link>http://www.serverphorums.com/read.php?7,508120,543209#msg-543209</link>
            <description><![CDATA[ On 07/27/2012 07:23 AM, Lester Caine wrote:<br />
&gt; Nikita Popov wrote:<br />
&gt;&gt;&gt; I'll ask again since no one has answered ...<br />
&gt;&gt;&gt; &gt;<br />
&gt;&gt;&gt; &gt;In a different way ...<br />
&gt;&gt;&gt; &gt;Is the only thing that changes the 'function' into a 'generator' <br />
&gt;&gt;&gt; replacing<br />
&gt;&gt;&gt; &gt;the call to process the data with 'yield'? ( That would be <br />
&gt;&gt;&gt; 'SUSPEND' in an<br />
&gt;&gt;&gt; &gt;SQL procedure ) ...<br />
&gt;&gt;&gt; &gt;<br />
&gt;&gt;&gt; &gt;So how DOES an IDE work out the flow in order to correctly check that<br />
&gt;&gt;&gt; &gt;variables are defined?<br />
&gt;&gt;&gt; &gt;<br />
&gt;&gt;&gt; &gt;As always, my IDE provides a lot of 'sexy' stuff so that I don't <br />
&gt;&gt;&gt; need to<br />
&gt;&gt;&gt; &gt;have it built in to the language, and I still can't see how a lot <br />
&gt;&gt;&gt; of what is<br />
&gt;&gt;&gt; &gt;being loaded in helps with performance which is the only thing that <br />
&gt;&gt;&gt; I am<br />
&gt;&gt;&gt; &gt;interested in. Performance wise why is yield better than just directly<br />
&gt;&gt;&gt; &gt;calling a function to handle the data?<br />
&gt;&gt; Lester Caine and Alex Aulbach,<br />
&gt;&gt;<br />
&gt;&gt; may I ask you to continue this discussion in a separate thread? I am<br />
&gt;&gt; really interested in constructive responses about the generator RFC,<br />
&gt;&gt; but your discussion is generating a lot of noise, which makes it very<br />
&gt;&gt; hard for me to pick out the few mails that are of interest to me.<br />
&gt;&gt;<br />
&gt;&gt; If you could open a new thread (like &quot;Generator keyword&quot;) it would <br />
&gt;&gt; help a lot.<br />
&gt;<br />
&gt; Nikita - I am looking for a well reasoned argument as to why generator <br />
&gt; has to be added at all! 'Just because it can be' is not a valid <br />
&gt; argument, but perhaps you could add to the RFC the performance <br />
&gt; implication or advantage of what is being proposed. That would at <br />
&gt; least be some comparison with the current methods of doing the same <br />
&gt; thing?<br />
&gt;<br />
<br />
Anthony had a very good writeup on generators and how they compare to <br />
iterators last week:<br />
<br />
<a href="http://blog.ircmaxell.com/2012/07/what-generators-can-do-for-you.html" target="_blank"  rel="nofollow">http://blog.ircmaxell.com/2012/07/what-generators-can-do-for-you.html</a><br />
<br />
I think that does a good job of laying out the case for generators as <br />
&quot;low-effort iterators&quot;.<br />
<br />
I still think the syntax feels clunky to me, but that's probably because <br />
I'm not used to it from other languages.<br />
<br />
One question, though: It looks based on the voting like finally {} <br />
blocks are going in.  So... what should happen in the following situation:<br />
<br />
function stuff() {<br />
   try {<br />
     foreach (range(1, 100) as $i) {<br />
       yield $i;<br />
     }<br />
   }<br />
   finally {<br />
     print &quot;All done&quot;;<br />
   }<br />
}<br />
<br />
Does &quot;All done&quot; get printed once, or 101 times?  Similarly:<br />
<br />
function things() {<br />
   $i = 1;<br />
   try {<br />
     while (true) {<br />
       yield $i++;<br />
     }<br />
   }<br />
   finally {<br />
     print &quot;All done&quot;;<br />
   }<br />
}<br />
<br />
That will run indefinitely.  So will &quot;All done&quot; ever print, or does that <br />
finally become unreachable?<br />
<br />
(I have no clue what the behavior &quot;should&quot; be in these cases, just that <br />
it should be sorted out sooner rather than later.)<br />
<br />
--Larry Garfield<br />
<br />
-- <br />
PHP Internals - PHP Runtime Development Mailing List<br />
To unsubscribe, visit: <a href="http://www.php.net/unsub.php" target="_blank"  rel="nofollow">http://www.php.net/unsub.php</a>]]></description>
            <dc:creator>Larry Garfield</dc:creator>
            <category>php-internals</category>
            <pubDate>Thu, 09 Aug 2012 04:30:02 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?7,508120,543069#msg-543069</guid>
            <title>Re: [PHP-DEV] Generators in PHP</title>
            <link>http://www.serverphorums.com/read.php?7,508120,543069#msg-543069</link>
            <description><![CDATA[ On 08/08/12 21:43, Stas Malyshev wrote:<br />
&gt; Hi!<br />
&gt;<br />
&gt;<br />
&gt;&gt; <a href="https://wiki.php.net/rfc/generators#yield_keyword" target="_blank"  rel="nofollow">https://wiki.php.net/rfc/generators#yield_keyword</a><br />
&gt;&gt; <a href="https://wiki.php.net/rfc/generators#sending_values" target="_blank"  rel="nofollow">https://wiki.php.net/rfc/generators#sending_values</a><br />
&gt; I'm not sure $data = (yield $value) makes a lot of sense. Why we have<br />
&gt; two variables here? Why it is only operator in the language that<br />
&gt; requires parentheses around? All these complex parentheses rules seem<br />
&gt; unnecessarily complicated. I'd rather do it in a more simple way: yield<br />
&gt; in an expression means incoming yield. I.e.:<br />
&gt; $data = yield;<br />
&gt; foo(yield, 1, 2);<br />
&gt; list($a, $b) = yield;<br />
&gt;<br />
&gt; Same with:<br />
&gt; call(yield $value) - what is the meaning of $value here? Why not just<br />
&gt; call(yield)?<br />
&gt;<br />
&gt; I would also not support array((yield $key =&gt; $value)) - it seems to be<br />
&gt; really unclear how it works. I'd just have yield produce a value which<br />
&gt; was sent, and that's it, and you could use this value in the same way<br />
&gt; you'd use any other expression.<br />
&gt;<br />
&gt; Only question I have here is what happens if you use yield in the middle<br />
&gt; of function call expression, for example:<br />
&gt; call(foo(bar(), $foo, yield, 3), baz());<br />
&gt;<br />
&gt; We are kind of stopping the function in the middle of the function call<br />
&gt; and going to unrelated code here, and may never return back. Where the<br />
&gt; required cleanups, etc. should happen?<br />
&gt;<br />
&gt; Another question is, if my function is like this:<br />
&gt; function foo()<br />
&gt; {<br />
&gt; 	var_dump(yield);<br />
&gt; }<br />
&gt;<br />
&gt; And I do: foo()-&gt;current() - what happens? Do I get null there? What<br />
&gt; happens if after that I do send() on the same generator? In general,<br />
&gt; interaction between incoming and outgoing yields is not very clear,<br />
&gt; especially what happens when you combine them.<br />
&gt;<br />
&gt; Also, small point: yield is repeatably called &quot;statement&quot; in the doc,<br />
&gt; but in fact it can be both statement and expression with returning yield.<br />
&gt;<br />
Hmm. This is just a quick thought:<br />
<br />
Considering the yield syntax will vary about needing () round it, why <br />
not make it a &quot;fake&quot; function (language construct).<br />
<br />
This way it's consistent: yield(), yield($v), yield($k =&gt; $v), $a = <br />
yield(), etc.<br />
<br />
(yield $x) is just messy as an expression. We don't have (isset $x), we <br />
have isset($x).<br />
<br />
-- <br />
Andrew Faulds<br />
<a href="http://ajf.me/" target="_blank"  rel="nofollow">http://ajf.me/</a><br />
<br />
<br />
-- <br />
PHP Internals - PHP Runtime Development Mailing List<br />
To unsubscribe, visit: <a href="http://www.php.net/unsub.php" target="_blank"  rel="nofollow">http://www.php.net/unsub.php</a>]]></description>
            <dc:creator>Andrew Faulds</dc:creator>
            <category>php-internals</category>
            <pubDate>Wed, 08 Aug 2012 23:00:01 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?7,508120,543065#msg-543065</guid>
            <title>Re: [PHP-DEV] Generators in PHP</title>
            <link>http://www.serverphorums.com/read.php?7,508120,543065#msg-543065</link>
            <description><![CDATA[ Hi!<br />
<br />
<br />
&gt; <a href="https://wiki.php.net/rfc/generators#yield_keyword" target="_blank"  rel="nofollow">https://wiki.php.net/rfc/generators#yield_keyword</a><br />
&gt; <a href="https://wiki.php.net/rfc/generators#sending_values" target="_blank"  rel="nofollow">https://wiki.php.net/rfc/generators#sending_values</a><br />
<br />
I'm not sure $data = (yield $value) makes a lot of sense. Why we have<br />
two variables here? Why it is only operator in the language that<br />
requires parentheses around? All these complex parentheses rules seem<br />
unnecessarily complicated. I'd rather do it in a more simple way: yield<br />
in an expression means incoming yield. I.e.:<br />
$data = yield;<br />
foo(yield, 1, 2);<br />
list($a, $b) = yield;<br />
<br />
Same with:<br />
call(yield $value) - what is the meaning of $value here? Why not just<br />
call(yield)?<br />
<br />
I would also not support array((yield $key =&gt; $value)) - it seems to be<br />
really unclear how it works. I'd just have yield produce a value which<br />
was sent, and that's it, and you could use this value in the same way<br />
you'd use any other expression.<br />
<br />
Only question I have here is what happens if you use yield in the middle<br />
of function call expression, for example:<br />
call(foo(bar(), $foo, yield, 3), baz());<br />
<br />
We are kind of stopping the function in the middle of the function call<br />
and going to unrelated code here, and may never return back. Where the<br />
required cleanups, etc. should happen?<br />
<br />
Another question is, if my function is like this:<br />
function foo()<br />
{<br />
	var_dump(yield);<br />
}<br />
<br />
And I do: foo()-&gt;current() - what happens? Do I get null there? What<br />
happens if after that I do send() on the same generator? In general,<br />
interaction between incoming and outgoing yields is not very clear,<br />
especially what happens when you combine them.<br />
<br />
Also, small point: yield is repeatably called &quot;statement&quot; in the doc,<br />
but in fact it can be both statement and expression with returning yield.<br />
<br />
-- <br />
Stanislav Malyshev, Software Architect<br />
SugarCRM: <a href="http://www.sugarcrm.com/" target="_blank"  rel="nofollow">http://www.sugarcrm.com/</a><br />
(408)454-6900 ext. 227<br />
<br />
-- <br />
PHP Internals - PHP Runtime Development Mailing List<br />
To unsubscribe, visit: <a href="http://www.php.net/unsub.php" target="_blank"  rel="nofollow">http://www.php.net/unsub.php</a>]]></description>
            <dc:creator>Stas Malyshev</dc:creator>
            <category>php-internals</category>
            <pubDate>Wed, 08 Aug 2012 22:50:01 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?7,508120,543064#msg-543064</guid>
            <title>Re: [PHP-DEV] Generators in PHP</title>
            <link>http://www.serverphorums.com/read.php?7,508120,543064#msg-543064</link>
            <description><![CDATA[ On Wed, Aug 8, 2012 at 10:27 PM, Andrew Faulds &lt;ajf@ajf.me&gt; wrote:<br />
&gt; Hi Nikita,<br />
&gt;<br />
&gt; I notice you require brackets round yield $k =&gt; $v and yield $v. Is this the<br />
&gt; formal syntax, i.e. '(' T_YIELD var =&gt; var ')'? If so it makes sense in a<br />
&gt; way, but it feels a little hackish. Does yield $v cause some sort of parsing<br />
&gt; issue that putting it in brackets solves? I realise that it's less<br />
&gt; ambiguous, but I don't like the idea of it. PHP's syntax has enough special<br />
&gt; cases already IMO.<br />
<br />
Without parenthesis their behavior in array definitions and nested<br />
yields is ambigous:<br />
<br />
array(yield $key =&gt; $value)<br />
// can be either<br />
array((yield $key) =&gt; $value)<br />
// or<br />
array((yield $key =&gt; $value))<br />
<br />
yield yield $key =&gt; $value;<br />
// can be either<br />
yield (yield $key) =&gt; $value;<br />
// or<br />
yield (yield $key =&gt; $value);<br />
<br />
Apart from that particular case there is the general operator<br />
precedence inclarity, e.g.<br />
<br />
yield $foo . $bar;<br />
// could be<br />
(yield $foo) . $bar;<br />
// or<br />
yield ($foo . $bar);<br />
<br />
This obviously is not a problem per-se, but with yield-style unary<br />
operators the precedence rules are often hard to figure out. E.g. most<br />
people would probably think that<br />
<br />
if (include('foo.php') == true) { ... }<br />
<br />
would be check the return value of include, but it's actually not.<br />
Rather it includes the file ('foo.php') == true, which is ''.<br />
<br />
Another issue was a purely implementational: In order to support<br />
by-ref yielding I have to distinguish between variable and<br />
non-variable expressions, which breaks the usual precedence rules. I<br />
was not able to fix the shift/reduce conflicts that are created by<br />
this without requiring the parenthesis.<br />
<br />
Also I'd like to mention that Python also has the paren-requirement<br />
for yield-expressions. It even requires parens for a simple yield,<br />
i.e. you'd have to write &quot;data = (yield)&quot;. This is not necessary in<br />
PHP, because PHP has semicolons.<br />
<br />
Nikita<br />
<br />
-- <br />
PHP Internals - PHP Runtime Development Mailing List<br />
To unsubscribe, visit: <a href="http://www.php.net/unsub.php" target="_blank"  rel="nofollow">http://www.php.net/unsub.php</a>]]></description>
            <dc:creator>Nikita Popov</dc:creator>
            <category>php-internals</category>
            <pubDate>Wed, 08 Aug 2012 22:50:01 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?7,508120,543057#msg-543057</guid>
            <title>Re: [PHP-DEV] Generators in PHP</title>
            <link>http://www.serverphorums.com/read.php?7,508120,543057#msg-543057</link>
            <description><![CDATA[ On 08/08/12 21:14, Nikita Popov wrote:<br />
&gt; On Fri, Jul 27, 2012 at 8:09 PM, Nikita Popov &lt;nikita.ppv@gmail.com&gt; wrote:<br />
&gt;&gt;&gt; 5. Are multiple yields allowed? I.e. the rfc mentions something like<br />
&gt;&gt;&gt; yield yield $a - what that would mean? I'd allow yield only be applied<br />
&gt;&gt;&gt; to variable expression (lval) because double yield doesn't make sense to<br />
&gt;&gt;&gt; me, but maybe I miss something.<br />
&gt;&gt; yield yield $a would basically first yield $a and then receive some<br />
&gt;&gt; value (via send) and yield that value again. Nothing you'd normally do<br />
&gt;&gt; ;) It was mentioned only as a syntax ambiguity consideration.<br />
&gt;&gt;<br />
&gt;&gt; Actually I added some additional parenthesis requirements for yield.<br />
&gt;&gt; For example you'd have to write the above as `yield (yield $a)` now<br />
&gt;&gt; (which should be slightly more clear). I haven't yet reflected this<br />
&gt;&gt; change in the RFC, but I'll add a section on it later.<br />
&gt;&gt;<br />
&gt;&gt;&gt; 6. “Sending values” section seems to be missing. Especially useful would<br />
&gt;&gt;&gt; be to cover what happens with keys there and what is the syntax there -<br />
&gt;&gt;&gt; is it just &quot;$a = yield;&quot;? Or does it mean when yield is used in<br />
&gt;&gt;&gt; expression it becomes incoming yield? And, last but not least - do we<br />
&gt;&gt;&gt; need sending into generators at all?<br />
&gt;&gt; Yeah, I haven't written that section yet. But it is fairly simple: If<br />
&gt;&gt; you go $generator-&gt;send($foo) then $foo will be the result of the<br />
&gt;&gt; current `yield` expression. And yes, this also works with keys and<br />
&gt;&gt; values. All of the following are valid:<br />
&gt;&gt;<br />
&gt;&gt;      $data = yield;<br />
&gt;&gt;      $data = (yield $value);<br />
&gt;&gt;      $data = (yield $key =&gt; $value);<br />
&gt;&gt;<br />
&gt;&gt; The first case is the most common though. I.e. you usually use it<br />
&gt;&gt; either as a generator or a reverse generator, not both. But doing both<br />
&gt;&gt; is also common for cooperative multitasking etc.<br />
&gt;&gt;<br />
&gt;&gt; Regarding the last question: I think the feature is worth adding. It<br />
&gt;&gt; is a very powerful concept that is hard to implement otherwise. Useful<br />
&gt;&gt; in particular for things like parsing and multitasking.<br />
&gt;&gt;<br />
&gt;&gt;&gt; 6. What happens if you send into a by-ref generator? Is the data sent<br />
&gt;&gt;&gt; by-ref then? What if it's an expression that can't be send by-ref?<br />
&gt;&gt; No, sending is always by-value. By-ref only affects the yielding part.<br />
&gt; I now added the mentioned sections:<br />
&gt;<br />
&gt; <a href="https://wiki.php.net/rfc/generators#yield_keyword" target="_blank"  rel="nofollow">https://wiki.php.net/rfc/generators#yield_keyword</a><br />
&gt; <a href="https://wiki.php.net/rfc/generators#sending_values" target="_blank"  rel="nofollow">https://wiki.php.net/rfc/generators#sending_values</a><br />
&gt;<br />
&gt; I also added a list of error conditions:<br />
&gt;<br />
&gt; <a href="https://wiki.php.net/rfc/generators#error_conditions" target="_blank"  rel="nofollow">https://wiki.php.net/rfc/generators#error_conditions</a><br />
&gt;<br />
&gt; Sorry for the delay,<br />
&gt; Nikita<br />
&gt;<br />
Hi Nikita,<br />
<br />
I notice you require brackets round yield $k =&gt; $v and yield $v. Is this <br />
the formal syntax, i.e. '(' T_YIELD var =&gt; var ')'? If so it makes sense <br />
in a way, but it feels a little hackish. Does yield $v cause some sort <br />
of parsing issue that putting it in brackets solves? I realise that it's <br />
less ambiguous, but I don't like the idea of it. PHP's syntax has enough <br />
special cases already IMO.<br />
<br />
Regards,<br />
<br />
-- <br />
Andrew Faulds<br />
<a href="http://ajf.me/" target="_blank"  rel="nofollow">http://ajf.me/</a><br />
<br />
<br />
-- <br />
PHP Internals - PHP Runtime Development Mailing List<br />
To unsubscribe, visit: <a href="http://www.php.net/unsub.php" target="_blank"  rel="nofollow">http://www.php.net/unsub.php</a>]]></description>
            <dc:creator>Andrew Faulds</dc:creator>
            <category>php-internals</category>
            <pubDate>Wed, 08 Aug 2012 22:30:02 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?7,508120,543051#msg-543051</guid>
            <title>Re: [PHP-DEV] Generators in PHP</title>
            <link>http://www.serverphorums.com/read.php?7,508120,543051#msg-543051</link>
            <description><![CDATA[ On Fri, Jul 27, 2012 at 8:09 PM, Nikita Popov &lt;nikita.ppv@gmail.com&gt; wrote:<br />
&gt;&gt; 5. Are multiple yields allowed? I.e. the rfc mentions something like<br />
&gt;&gt; yield yield $a - what that would mean? I'd allow yield only be applied<br />
&gt;&gt; to variable expression (lval) because double yield doesn't make sense to<br />
&gt;&gt; me, but maybe I miss something.<br />
&gt;<br />
&gt; yield yield $a would basically first yield $a and then receive some<br />
&gt; value (via send) and yield that value again. Nothing you'd normally do<br />
&gt; ;) It was mentioned only as a syntax ambiguity consideration.<br />
&gt;<br />
&gt; Actually I added some additional parenthesis requirements for yield.<br />
&gt; For example you'd have to write the above as `yield (yield $a)` now<br />
&gt; (which should be slightly more clear). I haven't yet reflected this<br />
&gt; change in the RFC, but I'll add a section on it later.<br />
&gt;<br />
&gt;&gt; 6. “Sending values” section seems to be missing. Especially useful would<br />
&gt;&gt; be to cover what happens with keys there and what is the syntax there -<br />
&gt;&gt; is it just &quot;$a = yield;&quot;? Or does it mean when yield is used in<br />
&gt;&gt; expression it becomes incoming yield? And, last but not least - do we<br />
&gt;&gt; need sending into generators at all?<br />
&gt;<br />
&gt; Yeah, I haven't written that section yet. But it is fairly simple: If<br />
&gt; you go $generator-&gt;send($foo) then $foo will be the result of the<br />
&gt; current `yield` expression. And yes, this also works with keys and<br />
&gt; values. All of the following are valid:<br />
&gt;<br />
&gt;     $data = yield;<br />
&gt;     $data = (yield $value);<br />
&gt;     $data = (yield $key =&gt; $value);<br />
&gt;<br />
&gt; The first case is the most common though. I.e. you usually use it<br />
&gt; either as a generator or a reverse generator, not both. But doing both<br />
&gt; is also common for cooperative multitasking etc.<br />
&gt;<br />
&gt; Regarding the last question: I think the feature is worth adding. It<br />
&gt; is a very powerful concept that is hard to implement otherwise. Useful<br />
&gt; in particular for things like parsing and multitasking.<br />
&gt;<br />
&gt;&gt; 6. What happens if you send into a by-ref generator? Is the data sent<br />
&gt;&gt; by-ref then? What if it's an expression that can't be send by-ref?<br />
&gt;<br />
&gt; No, sending is always by-value. By-ref only affects the yielding part.<br />
<br />
I now added the mentioned sections:<br />
<br />
<a href="https://wiki.php.net/rfc/generators#yield_keyword" target="_blank"  rel="nofollow">https://wiki.php.net/rfc/generators#yield_keyword</a><br />
<a href="https://wiki.php.net/rfc/generators#sending_values" target="_blank"  rel="nofollow">https://wiki.php.net/rfc/generators#sending_values</a><br />
<br />
I also added a list of error conditions:<br />
<br />
<a href="https://wiki.php.net/rfc/generators#error_conditions" target="_blank"  rel="nofollow">https://wiki.php.net/rfc/generators#error_conditions</a><br />
<br />
Sorry for the delay,<br />
Nikita<br />
<br />
-- <br />
PHP Internals - PHP Runtime Development Mailing List<br />
To unsubscribe, visit: <a href="http://www.php.net/unsub.php" target="_blank"  rel="nofollow">http://www.php.net/unsub.php</a>]]></description>
            <dc:creator>Nikita Popov</dc:creator>
            <category>php-internals</category>
            <pubDate>Wed, 08 Aug 2012 22:20:02 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?7,508120,537428#msg-537428</guid>
            <title>Re: [PHP-DEV] Re: Generators in PHP</title>
            <link>http://www.serverphorums.com/read.php?7,508120,537428#msg-537428</link>
            <description><![CDATA[ 2012/7/28 Rasmus Lerdorf &lt;rasmus@lerdorf.com&gt;:<br />
&gt; Very early versions of PHP v1 actually had distinct list, map and set<br />
&gt; implementations but I replaced those early on with a unified hybrid<br />
&gt; ordered map implementation and just called it the &quot;Array&quot; type. The<br />
&gt; thinking was that in almost all situations in a Web app, an ordered map<br />
&gt; can solve the problem. It looks and acts enough like an array that it<br />
&gt; can be used in situations that call for an array and it eliminates the<br />
&gt; problem of presenting the user with 3 or 4 types and related keywords<br />
&gt; and syntax that forces them to try to figure out which one to use when.<br />
<br />
I think I remember that. I hated how it was done in Perl and I loved it in PHP.<br />
<br />
&gt; This decision was made in 1994 and apart from a few pedantic naming<br />
&gt; complaints over the years, I think this particular decision has stood<br />
&gt; the test of time.<br />
<br />
&gt; I don't think this generator question is any different. We need to<br />
&gt; explain generators in the simplest way possible. The simplest way to<br />
&gt; explain generators is to not even worry about them being generators at<br />
&gt; all. Simply say that functions can now return arrays one element at a<br />
&gt; time using the new yield keyword. That's all.<br />
<br />
Well. I think you're right, saying this is not technical but<br />
philosophical. So I will put aside all my technical arguments, because<br />
they won't bring us further here.<br />
<br />
From the sight of now we can say arrays like in PHP have been a good<br />
concept. But in 1994 I must say, that was a brave decision!<br />
So the question is: Can we say this for functions, too? What will we<br />
say over those &quot;functions&quot; in 2030?<br />
<br />
Thinking this from all sides I must admit, that you're right. Some<br />
details of my thinking:<br />
<br />
- There will be more than generators and such stuff, which - with the<br />
same technical reasons - will also need new keywords. And this in the<br />
end ugly.<br />
- In the long run, it always was a good idea to introduce as few as<br />
possible new language constructs, because it is easier to remember.<br />
- You will then programm without an IDE only in very rare cases.<br />
- Programmers will be used to it over time.<br />
<br />
BTW: This thinking brought me to other aspects, but that's another mail.<br />
<br />
And I have something on my mind, I can't forget: How can we reduce the<br />
fuckuops in the beginning as much as possible?<br />
Docs - ok! But I always come back to the same thinking: Is it enough?<br />
And I think not in this case, because of the big difference between<br />
now and then. It's a difference if you introduce a new thing in the<br />
beginning or after 18 years.<br />
<br />
Hm. I know, some will say &quot;not again&quot;, but how about an *optional*<br />
keyword? This follows also some &quot;standards&quot; in PHP (thinking of<br />
&quot;static&quot;, &quot;public&quot; etc. which are also &quot;some kind of optional&quot;, so we<br />
know that concept already).<br />
Optional keywords are also used in SQL, where it helps to make a query<br />
more self-descriptive. Not more or less should it be here.<br />
<br />
How it works: PHP will warn (E_STRICT) if using a function as<br />
generator without that optional keyword. Maybe it's possible to turn<br />
that feature off, if you don't like that and in future the default<br />
warning is removed. From aspect of parser the keyword &quot;generator&quot; will<br />
have no implications (handled like a comment), because it will only be<br />
a keyword, if &quot;function&quot; follows.<br />
<br />
Suggested syntax will look like this:<br />
<br />
            [generator] function bla() { ... yield ...}<br />
<br />
I think this could help to remove some of the ugliest fuckups, when<br />
introducing it. And - this is my secret hope :) - this will kill the<br />
need for discussion of this *now*. The future will show us, if this is<br />
accepted/needed or not. Because who knows? This gives also more<br />
options for the future and is in my eyes good design.<br />
<br />
-- <br />
Alex Aulbach<br />
<br />
-- <br />
PHP Internals - PHP Runtime Development Mailing List<br />
To unsubscribe, visit: <a href="http://www.php.net/unsub.php" target="_blank"  rel="nofollow">http://www.php.net/unsub.php</a>]]></description>
            <dc:creator>Alex Aulbach</dc:creator>
            <category>php-internals</category>
            <pubDate>Mon, 30 Jul 2012 15:40:02 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?7,508120,536959#msg-536959</guid>
            <title>Re: [PHP-DEV] Re: Generators in PHP</title>
            <link>http://www.serverphorums.com/read.php?7,508120,536959#msg-536959</link>
            <description><![CDATA[ On 07/28/2012 12:37 AM, Lester Caine wrote:<br />
&gt; Rasmus Lerdorf wrote:<br />
&gt;&gt;&gt;&gt; I don't think this generator question is any different. We need to<br />
&gt;&gt;&gt;&gt; &gt;&gt;explain generators in the simplest way possible. The simplest way to<br />
&gt;&gt;&gt;&gt; &gt;&gt;explain generators is to not even worry about them being<br />
&gt;&gt;&gt;&gt; generators at<br />
&gt;&gt;&gt;&gt; &gt;&gt;all. Simply say that functions can now return arrays one element at a<br />
&gt;&gt;&gt;&gt; &gt;&gt;time using the new yield keyword. That's all.<br />
&gt;&gt;&gt; &gt;<br />
&gt;&gt;&gt; &gt;It's this 'concept' that I am having trouble seeing in the general<br />
&gt;&gt;&gt; &gt;process that is required using PHP to generate web pages. At the end of<br />
&gt;&gt;&gt; &gt;the day I have to generate the finished page or sub-page so I need all<br />
&gt;&gt;&gt; &gt;the results anyway.<br />
&gt;&gt; Sure, but that doesn't mean it has to all be in memory at the same time.<br />
&gt;&gt; You can read lines from a large file line-by-line, process that line and<br />
&gt;&gt; output the result before you move onto the next line.<br />
&gt; <br />
&gt; Exactly ... when uploading the NLPG csv files I process them line at a<br />
&gt; time and store to the database. I always have ... which is why I don't<br />
&gt; recognise the initial 'complaint' that justified adding this. These<br />
&gt; files can be 100Mb+ so there is no way one would process them by reading<br />
&gt; the whole lot in as the 'example' gave. You just call the function that<br />
&gt; processes the particular type of line which is based on the first two<br />
&gt; characters ... after reading the line.<br />
<br />
Great, so you recognize the use-case.  Now you just need to get to the<br />
next step which is that instead of having the iterating part call out to<br />
the processors for each iteration sometimes it is convenient to have it<br />
be processor-centric and have the processors be able to call the<br />
iterator to get the next element without duplicating that code in every<br />
processor.<br />
<br />
-Rasmus<br />
<br />
<br />
-- <br />
PHP Internals - PHP Runtime Development Mailing List<br />
To unsubscribe, visit: <a href="http://www.php.net/unsub.php" target="_blank"  rel="nofollow">http://www.php.net/unsub.php</a>]]></description>
            <dc:creator>Rasmus Lerdorf</dc:creator>
            <category>php-internals</category>
            <pubDate>Sat, 28 Jul 2012 10:40:02 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?7,508120,536952#msg-536952</guid>
            <title>Re: [PHP-DEV] Re: Generators in PHP</title>
            <link>http://www.serverphorums.com/read.php?7,508120,536952#msg-536952</link>
            <description><![CDATA[ Rasmus Lerdorf wrote:<br />
&gt;&gt;&gt; I don't think this generator question is any different. We need to<br />
&gt;&gt;&gt; &gt;&gt;explain generators in the simplest way possible. The simplest way to<br />
&gt;&gt;&gt; &gt;&gt;explain generators is to not even worry about them being generators at<br />
&gt;&gt;&gt; &gt;&gt;all. Simply say that functions can now return arrays one element at a<br />
&gt;&gt;&gt; &gt;&gt;time using the new yield keyword. That's all.<br />
&gt;&gt; &gt;<br />
&gt;&gt; &gt;It's this 'concept' that I am having trouble seeing in the general<br />
&gt;&gt; &gt;process that is required using PHP to generate web pages. At the end of<br />
&gt;&gt; &gt;the day I have to generate the finished page or sub-page so I need all<br />
&gt;&gt; &gt;the results anyway.<br />
&gt; Sure, but that doesn't mean it has to all be in memory at the same time.<br />
&gt; You can read lines from a large file line-by-line, process that line and<br />
&gt; output the result before you move onto the next line.<br />
<br />
Exactly ... when uploading the NLPG csv files I process them line at a time and <br />
store to the database. I always have ... which is why I don't recognise the <br />
initial 'complaint' that justified adding this. These files can be 100Mb+ so <br />
there is no way one would process them by reading the whole lot in as the <br />
'example' gave. You just call the function that processes the particular type of <br />
line which is based on the first two characters ... after reading the line.<br />
<br />
-- <br />
Lester Caine - G8HFL<br />
-----------------------------<br />
Contact - <a href="http://lsces.co.uk/wiki/?page=contact" target="_blank"  rel="nofollow">http://lsces.co.uk/wiki/?page=contact</a><br />
L.S.Caine Electronic Services - <a href="http://lsces.co.uk" target="_blank"  rel="nofollow">http://lsces.co.uk</a><br />
EnquirySolve - <a href="http://enquirysolve.com/" target="_blank"  rel="nofollow">http://enquirysolve.com/</a><br />
Model Engineers Digital Workshop - <a href="http://medw.co.uk" target="_blank"  rel="nofollow">http://medw.co.uk</a><br />
Rainbow Digital Media - <a href="http://rainbowdigitalmedia.co.uk" target="_blank"  rel="nofollow">http://rainbowdigitalmedia.co.uk</a><br />
<br />
<br />
<br />
-- <br />
PHP Internals - PHP Runtime Development Mailing List<br />
To unsubscribe, visit: <a href="http://www.php.net/unsub.php" target="_blank"  rel="nofollow">http://www.php.net/unsub.php</a>]]></description>
            <dc:creator>Lester Caine</dc:creator>
            <category>php-internals</category>
            <pubDate>Sat, 28 Jul 2012 09:40:02 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?7,508120,536951#msg-536951</guid>
            <title>Re: [PHP-DEV] Re: Generators in PHP</title>
            <link>http://www.serverphorums.com/read.php?7,508120,536951#msg-536951</link>
            <description><![CDATA[ On 07/27/2012 11:59 PM, Lester Caine wrote:<br />
&gt; Rasmus Lerdorf wrote:<br />
&gt;&gt; I don't think this generator question is any different. We need to<br />
&gt;&gt; explain generators in the simplest way possible. The simplest way to<br />
&gt;&gt; explain generators is to not even worry about them being generators at<br />
&gt;&gt; all. Simply say that functions can now return arrays one element at a<br />
&gt;&gt; time using the new yield keyword. That's all.<br />
&gt; <br />
&gt; It's this 'concept' that I am having trouble seeing in the general<br />
&gt; process that is required using PHP to generate web pages. At the end of<br />
&gt; the day I have to generate the finished page or sub-page so I need all<br />
&gt; the results anyway. <br />
<br />
Sure, but that doesn't mean it has to all be in memory at the same time.<br />
You can read lines from a large file line-by-line, process that line and<br />
output the result before you move onto the next line.<br />
<br />
-Rasmus<br />
<br />
-- <br />
PHP Internals - PHP Runtime Development Mailing List<br />
To unsubscribe, visit: <a href="http://www.php.net/unsub.php" target="_blank"  rel="nofollow">http://www.php.net/unsub.php</a>]]></description>
            <dc:creator>Rasmus Lerdorf</dc:creator>
            <category>php-internals</category>
            <pubDate>Sat, 28 Jul 2012 09:20:02 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?7,508120,536950#msg-536950</guid>
            <title>Re: [PHP-DEV] Re: Generators in PHP</title>
            <link>http://www.serverphorums.com/read.php?7,508120,536950#msg-536950</link>
            <description><![CDATA[ Rasmus Lerdorf wrote:<br />
&gt; I don't think this generator question is any different. We need to<br />
&gt; explain generators in the simplest way possible. The simplest way to<br />
&gt; explain generators is to not even worry about them being generators at<br />
&gt; all. Simply say that functions can now return arrays one element at a<br />
&gt; time using the new yield keyword. That's all.<br />
<br />
It's this 'concept' that I am having trouble seeing in the general process that <br />
is required using PHP to generate web pages. At the end of the day I have to <br />
generate the finished page or sub-page so I need all the results anyway. Part of <br />
my own problem in understanding may be that all my persistent data is in a <br />
database, and processing the SQL queries to efficiently serve up only the data <br />
needed for that particular page is paramount for speed. SQL has the concept of <br />
SUSPEND in procedures, but one would not use that here due to the processing <br />
overheads. One builds the array of results and processes it to provide the data <br />
to be fed to the client either while getting the dataset back from the database <br />
( the html elements form part of the query ) or the much faster approach, you <br />
get only the data stored in the initial array, and then iterate that array to <br />
add the wrapper. Since in many shared hosting cases the database is on another <br />
machine, you want to keep the amount of traffic between machines as small as <br />
possible. OR is the point of this concept that we can suspend operation and <br />
return later to do the next set of the list?<br />
<br />
In the examples given so far, even the new ones on why 'callback' does not work, <br />
understanding WHAT the end list of data is going to contain is difficult to work <br />
out and picking up the increasing amount of similar code being added to <br />
libraries makes maintaining them ever more difficult. But then perhaps I'm just <br />
getting too old for this and it's time to throw in the towel :( I'm certainly <br />
not enjoying all the agro keeping things working at all ...<br />
<br />
-- <br />
Lester Caine - G8HFL<br />
-----------------------------<br />
Contact - <a href="http://lsces.co.uk/wiki/?page=contact" target="_blank"  rel="nofollow">http://lsces.co.uk/wiki/?page=contact</a><br />
L.S.Caine Electronic Services - <a href="http://lsces.co.uk" target="_blank"  rel="nofollow">http://lsces.co.uk</a><br />
EnquirySolve - <a href="http://enquirysolve.com/" target="_blank"  rel="nofollow">http://enquirysolve.com/</a><br />
Model Engineers Digital Workshop - <a href="http://medw.co.uk" target="_blank"  rel="nofollow">http://medw.co.uk</a><br />
Rainbow Digital Media - <a href="http://rainbowdigitalmedia.co.uk" target="_blank"  rel="nofollow">http://rainbowdigitalmedia.co.uk</a><br />
<br />
<br />
<br />
-- <br />
PHP Internals - PHP Runtime Development Mailing List<br />
To unsubscribe, visit: <a href="http://www.php.net/unsub.php" target="_blank"  rel="nofollow">http://www.php.net/unsub.php</a>]]></description>
            <dc:creator>Lester Caine</dc:creator>
            <category>php-internals</category>
            <pubDate>Sat, 28 Jul 2012 09:10:02 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?7,508120,536942#msg-536942</guid>
            <title>Re: [PHP-DEV] Re: Generators in PHP</title>
            <link>http://www.serverphorums.com/read.php?7,508120,536942#msg-536942</link>
            <description><![CDATA[ On 07/26/2012 11:36 PM, Alex Aulbach wrote:<br />
&gt; 1) The bigger the language grows, the more we need to think about how<br />
&gt; to implement new features.<br />
&gt; I think it's a bad argument to say &quot;we made this and that not so<br />
&gt; ideal, so we can make this also. Don't be so idealistic.&quot; :)<br />
&gt; I think it's a duty to make new things more logical and more<br />
&gt; self-explaining and more fitting into the rest. Always, and the bigger<br />
&gt; it is, the more it must be done.<br />
&gt; <br />
&gt; 2) We should do things better, if we can.<br />
&gt; This opens two questions. First: Is a new keyword better than none,<br />
&gt; second: can we?<br />
<br />
Both of these points essentially argue that naming the ordered maps<br />
&quot;arrays&quot; in PHP was somehow not ideal and we (well, I in this case)<br />
should have done better. I completely disagree. One of the strengths of<br />
PHP is that it scales. It scales up to the largest sites in the world<br />
while at the same time it scales down to weekend warriors. Doing both in<br />
the same codebase is a challenge.<br />
<br />
Scaling up is something very technical people like yourself understands<br />
well. It is usually all about getting the architecture right and<br />
removing global locks and other bottlenecks. However, scaling down is<br />
not a technical problem but rather a philosophical one. It is about the<br />
overall approach, coming up with ways to make complicated concepts<br />
simple to understand, great documentation with simple examples and<br />
presenting an approachable ecosystem which extends well beyond the<br />
language itself.<br />
<br />
Very early versions of PHP v1 actually had distinct list, map and set<br />
implementations but I replaced those early on with a unified hybrid<br />
ordered map implementation and just called it the &quot;Array&quot; type. The<br />
thinking was that in almost all situations in a Web app, an ordered map<br />
can solve the problem. It looks and acts enough like an array that it<br />
can be used in situations that call for an array and it eliminates the<br />
problem of presenting the user with 3 or 4 types and related keywords<br />
and syntax that forces them to try to figure out which one to use when.<br />
This decision was made in 1994 and apart from a few pedantic naming<br />
complaints over the years, I think this particular decision has stood<br />
the test of time.<br />
<br />
I don't think this generator question is any different. We need to<br />
explain generators in the simplest way possible. The simplest way to<br />
explain generators is to not even worry about them being generators at<br />
all. Simply say that functions can now return arrays one element at a<br />
time using the new yield keyword. That's all.<br />
<br />
-Rasmus<br />
<br />
-- <br />
PHP Internals - PHP Runtime Development Mailing List<br />
To unsubscribe, visit: <a href="http://www.php.net/unsub.php" target="_blank"  rel="nofollow">http://www.php.net/unsub.php</a>]]></description>
            <dc:creator>Rasmus Lerdorf</dc:creator>
            <category>php-internals</category>
            <pubDate>Sat, 28 Jul 2012 08:20:03 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?7,508120,536749#msg-536749</guid>
            <title>Re: [PHP-DEV] Generators in PHP</title>
            <link>http://www.serverphorums.com/read.php?7,508120,536749#msg-536749</link>
            <description><![CDATA[ On Thu, Jul 26, 2012 at 2:20 AM, Stas Malyshev &lt;smalyshev@sugarcrm.com&gt; wrote:<br />
&gt; Hi!<br />
&gt;<br />
&gt;&gt; The implementation is outlined in the RFC-stub here:<br />
&gt;&gt; <a href="https://wiki.php.net/rfc/generators" target="_blank"  rel="nofollow">https://wiki.php.net/rfc/generators</a><br />
&gt;&gt;<br />
&gt;&gt; Before going any further I'd like to get some comments about what you<br />
&gt;&gt; think of adding generator support to PHP.<br />
&gt;<br />
&gt; Some notes on the RFC:<br />
&gt; 1. I think we should support rewind() by just creating a new generator<br />
&gt; instance (i.e. doing the same that is done when generator is called for<br />
&gt; the first time). If it depends on the resource that generator changes as<br />
&gt; a side effect, so be it. rewindable() looks like unnecessary<br />
&gt; complication which IMHO will not be useful in most cases.<br />
<br />
I think the best thing to do is neither. I.e. don't support rewinding<br />
and also don't provide a rewindable() function. I think that the<br />
concept of generators implies that it is a one-time data stream.<br />
Rewinding would fight the very nature of the concept. I think the<br />
currently implemented behavior of rewind() being a no-op is okay, but<br />
one could obviously also throw an exception when rewind() is called<br />
more than once, to make errors easier to see.<br />
<br />
&gt; 2. I understand the pre-yield code is called on current(). What about<br />
&gt; key()? I think it makes sense to call it there too - i.e. pre-yield code<br />
&gt; is called whenever first key() or current() - it should be made explicit.<br />
<br />
All the Iterator functions (and send()) will move to the first yield<br />
before performing their respective action. This is also mentioned in<br />
the RFC:<br />
<br />
&gt; If the generator is not yet at a ''yield'' statement (i.e. was just created<br />
&gt; and not yet used as an iterator), then any call to ''rewind'', ''valid'', ''current'',<br />
&gt; ''key'', ''next'' or ''send'' will resume the generator until the next ''yield''<br />
&gt; statement is hit.<br />
<br />
&gt; 3. return values. I think non-empty return in generator should produce a<br />
&gt; notice or E_STRICT.<br />
<br />
Non-empty return values currently throw an E_COMPILE_ERROR. I think<br />
that's okay as doing `return $foo` in a generator is clearly some kind<br />
of bug.<br />
<br />
In the future, should yield delegation be implemented, the return<br />
value would become meaningful again, as it would be the result of the<br />
delegation instruction. This is important for coroutine-based parsing<br />
code, so that you can write $result = yield* $this-&gt;parseSomething();.<br />
<br />
&gt; 4. What happens to the state variables when generator is cloned? Just<br />
&gt; addref or real cloning for objects?<br />
<br />
Cloning currently just uses addref everywhere. I'm not really sure<br />
what the right behavior is in that situation. Generally I think that<br />
cloning a generator is a rather strange thing to do, so it might make<br />
sense to drop cloning-support altogether. At least I can't really<br />
imagine a use case for it.<br />
<br />
&gt; 5. Are multiple yields allowed? I.e. the rfc mentions something like<br />
&gt; yield yield $a - what that would mean? I'd allow yield only be applied<br />
&gt; to variable expression (lval) because double yield doesn't make sense to<br />
&gt; me, but maybe I miss something.<br />
<br />
yield yield $a would basically first yield $a and then receive some<br />
value (via send) and yield that value again. Nothing you'd normally do<br />
;) It was mentioned only as a syntax ambiguity consideration.<br />
<br />
Actually I added some additional parenthesis requirements for yield.<br />
For example you'd have to write the above as `yield (yield $a)` now<br />
(which should be slightly more clear). I haven't yet reflected this<br />
change in the RFC, but I'll add a section on it later.<br />
<br />
&gt; 6. “Sending values” section seems to be missing. Especially useful would<br />
&gt; be to cover what happens with keys there and what is the syntax there -<br />
&gt; is it just &quot;$a = yield;&quot;? Or does it mean when yield is used in<br />
&gt; expression it becomes incoming yield? And, last but not least - do we<br />
&gt; need sending into generators at all?<br />
<br />
Yeah, I haven't written that section yet. But it is fairly simple: If<br />
you go $generator-&gt;send($foo) then $foo will be the result of the<br />
current `yield` expression. And yes, this also works with keys and<br />
values. All of the following are valid:<br />
<br />
    $data = yield;<br />
    $data = (yield $value);<br />
    $data = (yield $key =&gt; $value);<br />
<br />
The first case is the most common though. I.e. you usually use it<br />
either as a generator or a reverse generator, not both. But doing both<br />
is also common for cooperative multitasking etc.<br />
<br />
Regarding the last question: I think the feature is worth adding. It<br />
is a very powerful concept that is hard to implement otherwise. Useful<br />
in particular for things like parsing and multitasking.<br />
<br />
&gt; 6. What happens if you send into a by-ref generator? Is the data sent<br />
&gt; by-ref then? What if it's an expression that can't be send by-ref?<br />
<br />
No, sending is always by-value. By-ref only affects the yielding part.<br />
<br />
Nikita<br />
<br />
-- <br />
PHP Internals - PHP Runtime Development Mailing List<br />
To unsubscribe, visit: <a href="http://www.php.net/unsub.php" target="_blank"  rel="nofollow">http://www.php.net/unsub.php</a>]]></description>
            <dc:creator>Nikita Popov</dc:creator>
            <category>php-internals</category>
            <pubDate>Fri, 27 Jul 2012 20:20:04 +0200</pubDate>
        </item>
    </channel>
</rss>
