Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Re: while expression feature proposal

Reply
Thread Tools

Re: while expression feature proposal

 
 
Cameron Simpson
Guest
Posts: n/a
 
      10-24-2012
On 24Oct2012 16:54, Tim Chase <(E-Mail Removed)> wrote:
| On 10/24/12 16:34, Ian Kelly wrote:
| > On Wed, Oct 24, 2012 at 2:40 PM, Dan Loewenherz <(E-Mail Removed)> 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 <(E-Mail Removed)>
 
Reply With Quote
 
 
 
 
Paul Rubin
Guest
Posts: n/a
 
      10-24-2012
Cameron Simpson <(E-Mail Removed)> 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 ...
 
Reply With Quote
 
 
 
 
Paul Rubin
Guest
Posts: n/a
 
      10-24-2012
Paul Rubin <(E-Mail Removed)> writes:
> class memo:
> def __call__(f, *args, **kw):
> self.result = f(*args, **kw)


obviously add

return self.result
 
Reply With Quote
 
Cameron Simpson
Guest
Posts: n/a
 
      10-24-2012
On 24Oct2012 15:37, Paul Rubin <(E-Mail Removed)> wrote:
| Cameron Simpson <(E-Mail Removed)> 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 <(E-Mail Removed)>

If you do not read the paper, you are uninformed. If you do read the
paper, you are misinformed. - Mark Twain
 
Reply With Quote
 
Thomas Rachel
Guest
Posts: n/a
 
      10-25-2012
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
 
Reply With Quote
 
Grant Edwards
Guest
Posts: n/a
 
      10-25-2012
On 2012-10-24, Cameron Simpson <(E-Mail Removed)> 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
 
Reply With Quote
 
Thomas Rachel
Guest
Posts: n/a
 
      10-25-2012
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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: while expression feature proposal Tim Chase Python 0 10-24-2012 10:54 PM
Re: while expression feature proposal Chris Angelico Python 0 10-24-2012 10:40 PM
while expression feature proposal Dan Loewenherz Python 1 10-24-2012 10:19 PM
Re: while expression feature proposal Tim Chase Python 0 10-24-2012 09:54 PM
Re: while expression feature proposal Ian Kelly Python 0 10-24-2012 09:34 PM



Advertisments