This is fairly similar to a recent thread suggesting an "or raise" construct ("x = f() or raise ValueError" as a shortcut for "x = f(); if not x: raise ValueError").  I suggested that "raise" be made a value-less expression, so that "x = f() or raise ..." can be intepreted normally.  As a side effect, this would make lambdas slightly more powerful too.

Having "return" and "break" as value-less expressions would be nice too.  The interaction with nested loops in generators would be the natural one, without any generator-specific syntax:

((x, y) if stay_in_inner(x, y) else break for x in X for y in Y)

is the same as

for x in X:
    for y in Y:
        if stay_in_inner(x, y):
            yield x, y
        else:
            break

or, with break-expression everywhere, as a separate generator:

for x in X:
    for y in Y:
        (yield x, y) if stay_in_inner(x, y) else break

whereas

((x, y) if stay_in_gen(x, y) else return for x in X for y in Y)

is the same as

for x in X:
    for y in Y:
        if stay_in_gen(x, y):
            yield x, y
        else:
            return

or

for x in X:
    for y in Y:
        (yield x, y) if stay_in_gen(x, y) else return

i.e. the intepretation of a genexp is still to take the nested "for"s and "if"s after the leading expression, add suitable colons, newlines and indentation, and insert the leading expression at the end.

Antony

2014-11-20 10:02 GMT-08:00 Nathaniel Smith <njs@pobox.com>:
On Thu, Nov 20, 2014 at 4:36 PM, Chris Angelico <rosuav@gmail.com> wrote:
> On Fri, Nov 21, 2014 at 3:21 AM, Nick Coghlan <ncoghlan@gmail.com> wrote:
>> That does also suggest another possible alternative to the "or stop()"
>> trick - allow *break* as an expression.
>
> Or just as a keyword component of a comprehension, in the same way
> 'for' is. Since 'if' already has meaning, [x for x in range(10) if x
>>= 5 break] would be confusing, so probably it'd have to be the
> slightly-awkward-to-read [x for x in range(10) break x >= 5], adding a
> termination condition to the preceding loop.

'break' is certainly better than 'return' -- currently 'break' means
"look for the nearest enclosing loop", not "look for the enclosing
function", so it'd preserve that at least.

[x for x in range(10) if x >= 5 else break]?

with 'else break' handled in the grammar as a non-compositional phrase
like 'is not'? Not sure how this interacts with multiple mixed for and
if clauses -- I've never wrapped my head around those semantics.

-n

--
Nathaniel J. Smith
Postdoctoral researcher - Informatics - University of Edinburgh
http://vorpus.org
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/