Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Python (http://www.velocityreviews.com/forums/f43-python.html)
-   -   No "side effect" assignment! (http://www.velocityreviews.com/forums/t322448-no-side-effect-assignment.html)

Tobiah 09-14-2003 09:50 PM

No "side effect" assignment!
 
Ok,

I miss the idiom that my other languages use,
something like:


while( foo = getmore()){
process(foo);
}


I can't seem to do this in python without gagging:

foo = getmore()
while foo:
process(foo)
foo = getmore()


Is that what ppl do? The manual sez that this is
so that newbs won't do:

if foo = bar:
process()

thinking that they are checking for equality.
I feel that in a few ways python suffers by catering
to the uninitiated. Usually however, there are
great workarounds (or even plain better ways to do the job),
which I am hopeful will be yielded by the list, as has
been it's record thus far to do.

Thanks,

Tobiah


Dave Kuhlman 09-14-2003 10:04 PM

Re: No "side effect" assignment!
 
Tobiah wrote:

[snip]
>
>
> I can't seem to do this in python without gagging:
>
> foo = getmore()
> while foo:
> process(foo)
> foo = getmore()


Then test your gag reflex on the following:

while 1:
foo = getmore()
if not foo:
break
process(foo)

Slips down pretty smoothly with me.

[snip]

Dave

--
Dave Kuhlman
http://www.rexx.com/~dkuhlman
dkuhlman@rexx.com

Tobiah 09-14-2003 10:12 PM

Re: No "side effect" assignment!
 
Ack!!! (slight gag reflex) :)

That's actually more lines, even if more readable.

Ok, my perl roots are showing, but I was thinking
of putting the following function into my standard
module:

def eq(thingy):
global _
_ = thingy
return _



Having done that, I can now say:

while eq(getmore()):
process(_)


It seems to me that adding support for the side effect
assignment would not break any existing scripts. Gee,
they did it for += ;)

Thanks,

Tobiah

> Then test your gag reflex on the following:
>
> while 1:
> foo = getmore()
> if not foo:
> break
> process(foo)
>
> Slips down pretty smoothly with me.
>
> [snip]
>
> Dave
>



John Roth 09-14-2003 10:41 PM

Re: No "side effect" assignment!
 

"Tobiah" <toby@rcsreg.com> wrote in message
news:0fbc28ebd2ba4810db3efef3a29f990a@news.teranew s.com...
> Ok,
>
> I miss the idiom that my other languages use,
> something like:
>
>
> while( foo = getmore()){
> process(foo);
> }
>
>
> I can't seem to do this in python without gagging:
>
> foo = getmore()
> while foo:
> process(foo)
> foo = getmore()
>
>
> Is that what ppl do? The manual sez that this is
> so that newbs won't do:
>
> if foo = bar:
> process()
>
> thinking that they are checking for equality.
> I feel that in a few ways python suffers by catering
> to the uninitiated. Usually however, there are
> great workarounds (or even plain better ways to do the job),
> which I am hopeful will be yielded by the list, as has
> been it's record thus far to do.


While one of Guido's reasons for not including assignment
as an expression was to avoid errors (and that's not always
a novice error,) Python provides similar functionality in the
'for' statement. In C, C++ and Java, 'for' is basically
syntactic sugar around a loop, in Python, it actually does
an assignment of the next element of a sequence.

Your example could be:

for foo in getmore:
process(foo)

as long as getmore is either a sequence or implements the
iterator protocol.

This isn't a total replacement for assignment as an expression,
but it does cover the overwhelming majority of use cases.

John Roth


>
> Thanks,
>
> Tobiah
>




Sean Ross 09-14-2003 11:48 PM

Re: No "side effect" assignment!
 
"Tobiah" <toby@rcsreg.com> wrote in message
news:0fbc28ebd2ba4810db3efef3a29f990a@news.teranew s.com...
> Ok,
>
> I miss the idiom that my other languages use,
> something like:
>
>
> while( foo = getmore()){
> process(foo);
> }
>

[snip]

If you must use assignments in expressions, you might find the following
recipes useful:
http://aspn.activestate.com/ASPN/Coo.../Recipe/202234
http://aspn.activestate.com/ASPN/Coo...n/Recipe/66061




Andrew Koenig 09-15-2003 12:10 AM

Re: No "side effect" assignment!
 
Tobiah> Ack!!! (slight gag reflex) :)
Tobiah> That's actually more lines, even if more readable.

Tobiah> Ok, my perl roots are showing, but I was thinking
Tobiah> of putting the following function into my standard
Tobiah> module:

Tobiah> def eq(thingy):
Tobiah> global _
Tobiah> _ = thingy
Tobiah> return _



Tobiah> Having done that, I can now say:

Tobiah> while eq(getmore()):
Tobiah> process(_)

You're right -- your Perl roots are showing.

How about this instead:

def make_generator(func):
while x = func():
yield x

for val in make_generator(getmore):
process(val)

--
Andrew Koenig, ark@acm.org

Erik Max Francis 09-15-2003 01:11 AM

Re: No "side effect" assignment!
 
Andrew Koenig wrote:

> How about this instead:
>
> def make_generator(func):
> while x = func():

^^^^^^^^^^

Not too likely in Python :-).

--
Erik Max Francis && max@alcyone.com && http://www.alcyone.com/max/
__ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
/ \ Youth is a period of missed opportunities.
\__/ Cyril Connolly

Tobiah 09-15-2003 01:24 AM

Re: No "side effect" assignment!
 
Erik Max Francis wrote:
> Andrew Koenig wrote:
>
>
>>How about this instead:
>>
>> def make_generator(func):
>> while x = func():

>
> ^^^^^^^^^^
>
> Not too likely in Python :-).
>


Heh! My point exactly :)


Asun Friere 09-15-2003 07:10 AM

Re: No "side effect" assignment!
 
Dave Kuhlman <dkuhlman@rexx.com> wrote in message news:<bk2okk$nrhg9$1@ID-139865.news.uni-berlin.de>...
> Tobiah wrote:
>
> [snip]
> >
> >
> > I can't seem to do this in python without gagging:
> >
> > foo = getmore()
> > while foo:
> > process(foo)
> > foo = getmore()

>
> Then test your gag reflex on the following:
>
> while 1:
> foo = getmore()
> if not foo:
> break
> process(foo)
>
> Slips down pretty smoothly with me.
>
> [snip]
>
> Dave


I am alone in feeling some slight unease at the sight of "while 1: ...
break"? I know this is considered somewhat pythonic, but apart from
the fact that there is only a single assignment statement is there
really any advantage to be gained by doing it this way? It seems to
be trading one aesthetic disadvantage for another, and imho, a
marginally less legible one.

In terms of pandering to newbies, I think the requirement that loop
conditions be expressions is much more squarely aimed at experienced
programmers, who would otherwise be tempted to write unintelligible
code by placing too much of the programs logic withing the loop
condition.

Duncan Booth 09-15-2003 08:51 AM

Re: No "side effect" assignment!
 
Tobiah <toby@rcsreg.com> wrote in
news:0fbc28ebd2ba4810db3efef3a29f990a@news.teranew s.com:

> I can't seem to do this in python without gagging:
>
> foo = getmore()
> while foo:
> process(foo)
> foo = getmore()
>
>
> Is that what ppl do?


I don't know about ppl, but Python programmers have a variety of ways of
structuring this code. The one that I think is simplest, but is often
overlooked is to use the builtin function 'iter'. It won't exactly replace
the code you have above, since your loop terminates as soon as getmore()
returns anything false (None, 0, False, '' would all terminate it). If
however you know the exact value to indicate termination (I'll guess
getmore() returns None when its done), you can write your loop:

for foo in iter(getmore, None):
process(foo)

If instead of a simple function call you had a more complex expression (say
getmore took a file as an argument), you might consider a lambda:

for foo in iter(lambda: getmore(aFile), None):
process(foo)


--
Duncan Booth duncan@rcp.co.uk
int month(char *p){return(124864/((p[0]+p[1]-p[2]&0x1f)+1)%12)["\5\x8\3"
"\6\7\xb\1\x9\xa\2\0\4"];} // Who said my code was obscure?


All times are GMT. The time now is 01:26 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.