Re: while expression feature proposal

Discussion in 'Python' started by Cameron Simpson, Oct 24, 2012.

  1. On 24Oct2012 16:54, Tim Chase <> wrote:
    | On 10/24/12 16:34, Ian Kelly wrote:
    | > On Wed, Oct 24, 2012 at 2:40 PM, Dan Loewenherz <> wrote:
    | >> So I'm sure a lot of you have run into the following pattern. I use it
    | >> all the time and it always has felt a bit awkward due to the duplicate
    | >> variable assignment.
    | >>
    | >> VAR = EXPR
    | >> while VAR:
    | >> BLOCK
    | >> VAR = EXPR
    | >
    | > The idiomatic way to do this is:
    | >
    | > while True:
    | > VAR = EXPR
    | > if not VAR:
    | > break
    | > BLOCK
    |
    | It may be idiomatic, but that doesn't stop it from being pretty
    | ugly.

    Yes, but more flexible because it accomodates loops where the natural
    place for the test is partway through the loop instead of right at the
    top, which is quite common.

    | I must say I really like the parity of Dan's
    | while EXPR as VAR:
    | BLOCK
    | proposal with the "with" statement.

    Well, it's nice. But usually EXPR will be a boolean. If you're inside
    the loop you know it's true and don't need VAR. Of course, the glaring
    counter example is things like regexp tests. I have a heap of code like
    this:

    m = re_FUNKYPATTERN.match(test_string)
    if m:
    do stuff with the results of the match, using "m"

    If I could write this as:

    if re_FUNKYPATTERN.match(test_string) as m:
    do stuff with the results of the match, using "m"

    then some cascading parse decisions would feel a bit cleaner. Where I
    current have this:

    m = re_CONSTRUCT1.match(line)
    if m:
    ... handle construct 1 ...
    else:
    m = re_CONSTRUCT2.match(line)
    if m:
    ... handle construct 2 ...
    else:
    m = re_CONSTRUCT3.match(line)

    I could have this:

    if re_CONSTRUCT1.match(line) as m:
    ... handle construct 1 ...
    elif re_CONSTRUCT2.match(line) as m:
    ... handle construct 2 ...
    elif re_CONSTRUCT3.match(line) as m:

    which is both more concise and also doesn't step inward.

    But I'm still -0 on it, because it supplants the glaringly obvious:

    m = ...

    assignment with the far less in your face:

    possibly-long-expr as m

    and I think it would get quite heavily used, to the detriment of
    assignment readability in general. At present the nature of most effects
    is at the left. An assignment is obvious on the left, an if/with/while/etc
    is visible at the left.

    With statements and except statements have concrete use cases for the
    "as" part that aren't doable without it, but the while/if...as form
    can always be written in the current convention.

    Cheers,
    --
    Cameron Simpson <>
    Cameron Simpson, Oct 24, 2012
    #1
    1. Advertising

  2. Cameron Simpson

    Paul Rubin Guest

    Cameron Simpson <> writes:
    > if re_FUNKYPATTERN.match(test_string) as m:
    > do stuff with the results of the match, using "m"


    class memo:
    def __call__(f, *args, **kw):
    self.result = f(*args, **kw)

    m = memo()

    if result(re_FUNKYPATTERN.match, test_string):
    do stuff with the results of the match,
    using "m.result"

    then

    if re_CONSTRUCT1.match(line) as m:
    ... handle construct 1 ...
    elif re_CONSTRUCT2.match(line) as m:
    ... handle construct 2 ...
    elif re_CONSTRUCT3.match(line) as m:

    becomes

    if m(re_CONSTRUCT1.match, line):
    .. handle construct 1 ...
    elif m(re_CONSTRUCT2.match, line):
    .. handle construct 2 ...
    Paul Rubin, Oct 24, 2012
    #2
    1. Advertising

  3. Cameron Simpson

    Paul Rubin Guest

    Paul Rubin <> writes:
    > class memo:
    > def __call__(f, *args, **kw):
    > self.result = f(*args, **kw)


    obviously add

    return self.result
    Paul Rubin, Oct 24, 2012
    #3
  4. On 24Oct2012 15:37, Paul Rubin <> wrote:
    | Cameron Simpson <> writes:
    | > if re_FUNKYPATTERN.match(test_string) as m:
    | > do stuff with the results of the match, using "m"
    |
    | class memo:
    | def __call__(f, *args, **kw):
    | self.result = f(*args, **kw)
    |
    | m = memo()
    | if result(re_FUNKYPATTERN.match, test_string):
    | do stuff with the results of the match,
    | using "m.result"
    |
    | then
    |
    | if re_CONSTRUCT1.match(line) as m:
    | ... handle construct 1 ...
    | elif re_CONSTRUCT2.match(line) as m:
    | ... handle construct 2 ...
    | elif re_CONSTRUCT3.match(line) as m:
    |
    | becomes
    |
    | if m(re_CONSTRUCT1.match, line):
    | .. handle construct 1 ...
    | elif m(re_CONSTRUCT2.match, line):
    | .. handle construct 2 ...

    Cute. Not sure I like it, but cute:)
    --
    Cameron Simpson <>

    If you do not read the paper, you are uninformed. If you do read the
    paper, you are misinformed. - Mark Twain
    Cameron Simpson, Oct 24, 2012
    #4
  5. Am 25.10.2012 00:26 schrieb Cameron Simpson:

    > If I could write this as:
    >
    > if re_FUNKYPATTERN.match(test_string) as m:
    > do stuff with the results of the match, using "m"
    >
    > then some cascading parse decisions would feel a bit cleaner. Where I
    > current have this:
    >
    > m = re_CONSTRUCT1.match(line)
    > if m:
    > ... handle construct 1 ...
    > else:
    > m = re_CONSTRUCT2.match(line)
    > if m:
    > ... handle construct 2 ...
    > else:
    > m = re_CONSTRUCT3.match(line)
    >
    > I could have this:
    >
    > if re_CONSTRUCT1.match(line) as m:
    > ... handle construct 1 ...
    > elif re_CONSTRUCT2.match(line) as m:
    > ... handle construct 2 ...
    > elif re_CONSTRUCT3.match(line) as m:


    I would do

    for r in re_CONSTRUCT1, re_CONSTRUCT2, re_CONSTRUCT3:
    m = r.match(line)
    if m: handle_construct

    or maybe

    actions = {re_CONSTRUCT1: action1, ...}

    def matching(line, *rr):
    for r in rr:
    m = r.match(line)
    if m: yield r; return

    for r in matching(line, *actions.keys()):
    actions[r]()
    break
    else:
    raise NoActionMatched() # or something like that

    Thomas
    Thomas Rachel, Oct 25, 2012
    #5
  6. On 2012-10-24, Cameron Simpson <> wrote:

    >| I must say I really like the parity of Dan's
    >| while EXPR as VAR:
    >| BLOCK
    >| proposal with the "with" statement.
    >
    > Well, it's nice. But usually EXPR will be a boolean.


    I guess that depends on what sort of programs you write. In my
    experience, EXPR is usually a read from a file/socket/pipe that
    returns '' on EOF. If VAR is not '', then you process, then you
    process it inside the loop.

    --
    Grant Edwards grant.b.edwards Yow! We're going to a
    at new disco!
    gmail.com
    Grant Edwards, Oct 25, 2012
    #6
  7. Am 25.10.2012 16:15 schrieb Grant Edwards:

    > I guess that depends on what sort of programs you write. In my
    > experience, EXPR is usually a read from a file/socket/pipe that
    > returns '' on EOF. If VAR is not '', then you process, then you
    > process it inside the loop.


    Right. The same as in

    if regex.search(string) as match:
    process it

    But with

    def if_true(expr):
    if expr: yield expr

    you can do

    for match in if_true(regex.search(string)):
    process it

    But the proposed if ... as ...: statment woulkd be more beautiful by far.

    Thomas
    Thomas Rachel, Oct 25, 2012
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Dan Loewenherz

    while expression feature proposal

    Dan Loewenherz, Oct 24, 2012, in forum: Python
    Replies:
    1
    Views:
    144
    Paul Rubin
    Oct 24, 2012
  2. Ian Kelly
    Replies:
    0
    Views:
    126
    Ian Kelly
    Oct 24, 2012
  3. Tim Chase
    Replies:
    0
    Views:
    144
    Tim Chase
    Oct 24, 2012
  4. Chris Angelico

    Re: while expression feature proposal

    Chris Angelico, Oct 24, 2012, in forum: Python
    Replies:
    0
    Views:
    169
    Chris Angelico
    Oct 24, 2012
  5. Tim Chase
    Replies:
    0
    Views:
    205
    Tim Chase
    Oct 24, 2012
Loading...

Share This Page