<br><br><div class="gmail_quote">On Sat, Mar 15, 2008 at 3:21 PM, Guido van Rossum &lt;<a href="mailto:guido@python.org">guido@python.org</a>&gt; wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
This post does point out an inconistency in Thomas&#39;s patch:<br>
<br>
def f():<br>
 &nbsp;yield 1, 2, 3<br>
<br>
Yields a single three-tuple.<br>
<br>
But<br>
<br>
def f():<br>
 &nbsp;yield *[1, 2], 3<br>
<br>
Yields three separate values.</blockquote><div><br>Uhm, what? It doesn&#39;t, and it shouldn&#39;t, and I&#39;m not sure what makes you think it does.<br><br>&gt;&gt;&gt; def f():<br>...&nbsp;&nbsp;&nbsp;&nbsp; yield *[1, 2], 3<br>... <br>&gt;&gt;&gt; list(f())<br>
[(1, 2, 3)]<br><br>The comma makes the argument to &#39;yield&#39; a single item (a tuple) and the &#39;*&#39; is part of the item in the tuple. In other words, the * binds more tightly than the comma (which is not something I changed; the parser already worked this way and it&#39;s necessary for &#39;*a, b, c = ..&#39; to even work.&nbsp; &#39;yield *[1, 2], 3&#39; is parsed as &#39;yield (*[1, 2], 3)&#39;, not &#39;yield *([1, 2], 3)&#39;. What you suggest (three separate values) requires &#39;yield *(*[1, 2], 3)&#39;.<br>
<br>&gt;&gt;&gt; def f1():<br>...&nbsp;&nbsp;&nbsp;&nbsp; yield (*[1, 2], 3)<br>... <br>&gt;&gt;&gt; list(f1())<br>[(1, 2, 3)]<br><br>&gt;&gt;&gt; def f2():<br>...&nbsp;&nbsp;&nbsp;&nbsp; yield *([1, 2], 3)<br>... <br>&gt;&gt;&gt; list(f2())<br>[[1, 2], 3]<br><br>
&gt;&gt;&gt; def f3():<br>...&nbsp;&nbsp;&nbsp;&nbsp; yield *(*[1, 2], 3)<br>... <br>&gt;&gt;&gt; list(f3())<br>[1, 2, 3]<br><br> </div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
 &nbsp;I think this is inconsistent, since<br>
<br>
(1, 2, 3)<br>
<br>
and<br>
<br>
(*[1, 2], 3)<br>
<br>
are equivalent, and so are<br>
<br>
yield 1, 2, 3<br>
<br>
and<br>
<br>
yield (1, 2, 3)</blockquote><div><br>Yes, they are indeed all equivalent :-)<br>&nbsp;<br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br>
<br>
I&#39;m not sure how to solve this except by adopting a different syntax<br>
for the multiple-yield. Perhaps<br>
<br>
*yield x<br>
<br>
instead of<br>
<br>
yield *x<br>
<br>
???</blockquote><div><br>If there really were an inconsistency here, I would certainly not suggest fixing it that way, yuuueghh.<br><br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br>
<div class="Ih2E3d"><br>
On Sat, Mar 15, 2008 at 4:58 PM, Terry Reedy &lt;<a href="mailto:tjreedy@udel.edu">tjreedy@udel.edu</a>&gt; wrote:<br>
&gt;<br>
</div><div><div></div><div class="Wj3C7c">&gt; &nbsp;&quot;Guido van Rossum&quot; &lt;<a href="mailto:guido@python.org">guido@python.org</a>&gt; wrote in message<br>
&gt; &nbsp;news:ca471dc20803150915l27750346g8655f596f5035c69@mail.gmail.com...<br>
&gt;<br>
&gt; | Thomas Wouters suggests some new syntax:<br>
&gt;<br>
&gt; &nbsp;I see this as two suggestions:<br>
&gt; &nbsp;1. Complete the extension of the validity of *expression syntax from<br>
&gt; &nbsp;function call/definition to expression/assignment.<br>
&gt; &nbsp;2. Give *expression a related meaning in yield statements.<br>
&gt;<br>
&gt;<br>
&gt; &nbsp;|<br>
&gt; &nbsp;| <a href="http://bugs.python.org/issue2292" target="_blank">http://bugs.python.org/issue2292</a><br>
&gt; &nbsp;|<br>
&gt; &nbsp;| &gt;&gt;&gt; a, b, *c = range(5)<br>
&gt; &nbsp;|<br>
&gt; &nbsp;| &gt;&gt;&gt; *a, b, c = a, b, *c<br>
&gt; &nbsp;| &gt;&gt;&gt; a, b, c<br>
&gt; &nbsp;| ([0, 1, 2], 3, 4)<br>
&gt; &nbsp;| &gt;&gt;&gt; [ *a, b, c ]<br>
&gt; &nbsp;| [0, 1, 2, 3, 4]<br>
&gt;<br>
&gt; &nbsp;I understand &#39;f(*a)&#39; to mean &#39;execute the expression as if the items of<br>
&gt; &nbsp;iterable a has been written literally in the code (with &#39;as if&#39;<br>
&gt; &nbsp;optimizations allowed for special cases). &nbsp;The above follow the same rule.<br>
&gt; &nbsp;+1<br>
&gt; &nbsp;A tutorial written for Py3 without regard to history should then introduce<br>
&gt; &nbsp;*expressions in examples like the above first, and only later the usage for<br>
&gt; &nbsp;functions, as if things had been this way all along.<br>
&gt;<br>
&gt;<br>
&gt; &nbsp;| &gt;&gt;&gt; L = [ a, (3, 4), {5}, {6: None}, (i for i in range(7, 10)) ]<br>
&gt; &nbsp;| &gt;&gt;&gt; [ *item for item in L ]<br>
&gt; &nbsp;| [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]<br>
&gt;<br>
&gt; &nbsp;Since above will become equivalent to list(gen_exp), I see this as being<br>
&gt; &nbsp;tied to yield *exp.<br>
&gt;<br>
&gt;<br>
&gt; &nbsp;| Also, yielding everything from an iterator:<br>
&gt; &nbsp;|<br>
&gt; &nbsp;| &gt;&gt;&gt; def flatten(iterables):<br>
&gt; &nbsp;| ... &nbsp; &nbsp; for it in iterables:<br>
&gt; &nbsp;| ... &nbsp; &nbsp; &nbsp; &nbsp; yield *it<br>
&gt;<br>
&gt; &nbsp;Following the general rule above for *exp, that would be the same as yield<br>
&gt; &nbsp;tuple(it). &nbsp;But that is nearly useless, whereas the the implicit inner for<br>
&gt; &nbsp;loop meaning is quite useful, with, perhaps, a speedup over an explicit<br>
&gt; &nbsp;inner loop. &nbsp;Since yield is already pretty magical,a bit more might not<br>
&gt; &nbsp;hurt.<br>
&gt;<br>
&gt; &nbsp;But, ... what do you do with<br>
&gt; &nbsp; &nbsp; yield *a,b,c # a,b,c as above?<br>
&gt; &nbsp;Yield a 5-tuple? &nbsp;That would clash badly with &#39;yield *a&#39; not yielding a<br>
&gt; &nbsp;3-tuple.<br>
&gt; &nbsp;Raise an exception? &nbsp;That establishes/requires a new grammatical<br>
&gt; &nbsp;category -- yield_expression. &nbsp;But I would see this as preferable to the<br>
&gt; &nbsp;clash.<br>
&gt;<br>
&gt; &nbsp;Terry Jan Reedy<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt; &nbsp;_______________________________________________<br>
&gt; &nbsp;Python-3000 mailing list<br>
&gt; &nbsp;<a href="mailto:Python-3000@python.org">Python-3000@python.org</a><br>
&gt; &nbsp;<a href="http://mail.python.org/mailman/listinfo/python-3000" target="_blank">http://mail.python.org/mailman/listinfo/python-3000</a><br>
</div></div>&gt; &nbsp;Unsubscribe: <a href="http://mail.python.org/mailman/options/python-3000/guido%40python.org" target="_blank">http://mail.python.org/mailman/options/python-3000/guido%40python.org</a><br>
<div class="Ih2E3d">&gt;<br>
<br>
<br>
<br>
--<br>
--Guido van Rossum (home page: <a href="http://www.python.org/%7Eguido/" target="_blank">http://www.python.org/~guido/</a>)<br>
_______________________________________________<br>
</div><div><div></div><div class="Wj3C7c">Python-3000 mailing list<br>
<a href="mailto:Python-3000@python.org">Python-3000@python.org</a><br>
<a href="http://mail.python.org/mailman/listinfo/python-3000" target="_blank">http://mail.python.org/mailman/listinfo/python-3000</a><br>
Unsubscribe: <a href="http://mail.python.org/mailman/options/python-3000/thomas%40python.org" target="_blank">http://mail.python.org/mailman/options/python-3000/thomas%40python.org</a><br>
</div></div></blockquote></div><br><br clear="all"><br>-- <br>Thomas Wouters &lt;<a href="mailto:thomas@python.org">thomas@python.org</a>&gt;<br><br>Hi! I&#39;m a .signature virus! copy me into your .signature file to help me spread!