RFC: Assignment in Conditional

278 views
Skip to first unread message

Sean Reifschneider

unread,
Dec 22, 1998, 3:00:00 AM12/22/98
to
We all realize that assignment isn't an operator. It's easy enough to chant
that when someone asks about why they can't do "if line = fp.readline():".
However, it seems fairly clear that this restriction results in kludges
like:

while 1:
line = fp.readline()
if not line: break
print line

In a language which is touted as being so clear, I'm kind of surprised that
this hasn't received more attention.

It would seem that one could set up a variable or possibly a set of variables
which would contain the value of the expression in the last executed
conditional:

while fp.readline():
if re.match(whileVar, r'^\s*(\S+)\s*=\s*(\S+)\s*$'):
print 'Assignment "%s" = "%s"' % ( ifVar.group(1), ifVar.group(2) )

This has the benefit of allowing you to easily see the termination condition
for the while loop, instead of assuming it's infinite until you search
through (the possibly complex) body.

This would seem to eliminate the required kludge, while still keeping with the
basic spirit of Python. However, before going through and making a patch for
Python, I wanted to see what comments folks had on this idea.

The next logical step I could see would be adding a variant to conditionals:

while [ <word> = ] <expression>:

where if the optional [ <word> = ] part of the while statement were there it
would assign the expression value to <word> in addition to the whileVar. But
then what would be the point of having the whileVar?

Is the only concern that this will be confused with the "==" comparison
operator? In that case, would "while [ <word> assign_the_value_of ]
<expression>:" (or something similar) be more appropriate? Or perhaps
even something along the lines of "<word> = while <expression>:"?
That feels a bit strange, but surely won't be mistaken for a comparator...

The only issue I see with this is the scope of the "whileVar". Presumably
one could limit the scope by doing a "whileVar = None", or perhaps the
termination of a while would imply that?

Thanks,
Sean
--
I used to think that the brain was the most wonderful organ in
my body. Then I realized who was telling me this. -- Emo Phillips
Sean Reifschneider, Inimitably Superfluous <jafo...@tummy.com>
URL: <http://www.tummy.com/xvscan> HP-UX/Linux/FreeBSD/BSDOS scanning software.

Michael Scharf

unread,
Dec 22, 1998, 3:00:00 AM12/22/98
to
Sean Reifschneider wrote:
>
> We all realize that assignment isn't an operator. It's easy enough to chant
> that when someone asks about why they can't do "if line = fp.readline():".
> However, it seems fairly clear that this restriction results in kludges
> like:
>
> while 1:
> line = fp.readline()
> if not line: break
> print line
>
> In a language which is touted as being so clear, I'm kind of surprised that
> this hasn't received more attention.

This comes up every few month (search in dejanews for 'assignment expression'
and you'll find some answers).
http://www.dejanews.com/getdoc.xp?AN=160191343
http://www.dejanews.com/getdoc.xp?AN=421739003
http://www.dejanews.com/getdoc.xp?AN=421980085

Maybe something should go to the FAQ.


Michael
--
''''\ Michael Scharf
` c-@@ TakeFive Software
` > http://www.TakeFive.com
\_ V mailto:Michael...@TakeFive.co.at

Christian Tismer

unread,
Dec 22, 1998, 3:00:00 AM12/22/98
to
Sean Reifschneider wrote:
>
> We all realize that assignment isn't an operator. It's easy enough to chant
> that when someone asks about why they can't do "if line = fp.readline():".
> However, it seems fairly clear that this restriction results in kludges
> like:
>
> while 1:
> line = fp.readline()
> if not line: break
> print line
>
> In a language which is touted as being so clear, I'm kind of surprised that
> this hasn't received more attention.

It has. You can do the assignment inside a class instance and
iterate over this. Guido did this in a very elegant way.
Try this:

import fileinput
for line in fileinput.input():
process(line)

It doesn't read the whole bunch but behaves like a sequence
and enumerates all the input lines by its __getitem__ method.

If you think you must, here is also a minimal example
how to wrap an assignment by a small class.

class remember:
def __init__(self, func):
self.func = func
def __call__(self):
self.line = self.func()
return self.line

myline = remember(open('c:\\autoexec.bat').readline)
while myline():
print myline.line

All in all it is no big deal and not necessary.

cao - chris

--
Christian Tismer :^) <mailto:tis...@appliedbiometrics.com>
Applied Biometrics GmbH : Have a break! Take a ride on Python's
Kaiserin-Augusta-Allee 101 : *Starship* http://starship.skyport.net
10553 Berlin : PGP key -> http://pgp.ai.mit.edu/
we're tired of banana software - shipped green, ripens at home

Sean Reifschneider

unread,
Dec 23, 1998, 3:00:00 AM12/23/98
to
In article <368026D3...@appliedbiometrics.com>,

Christian Tismer <tis...@appliedbiometrics.com> wrote:
>It has. You can do the assignment inside a class instance and
>iterate over this. Guido did this in a very elegant way.

With all due respect, if it's so elegant why does Guido recommend not
using it for performance reasons? Search DejaNews if you're really
interested.

> import fileinput
> for line in fileinput.input():
> process(line)

This is one of the few places in the library where you can do something
similar to the above. If you don't care about performance, you can also
do:

for line in sys.stdin.readlines():
process(line)

so why do you need fileinput at all?

The point is that fileinput is the only place you get that nice syntax
(what if I'm reading data from sockets or pipes?). My proposal above
removes the need for kludges such as building classes so you can use
__getitem__.

>If you think you must, here is also a minimal example
>how to wrap an assignment by a small class.

[Example replacing 3 lines of code with 9 deleted]

>All in all it is no big deal and not necessary.

Perhaps so... One could make the same argument for a number of features
which have been added to Python (lambda, map, filter, multiple assignment
which may even tend to promote these discussions). Yet amazingly this
issue continues to be brought up...

Sean
--
Jackie Trehorn treats objects like women, man...
-- _The_Big_Lebowski_

Sean Reifschneider

unread,
Dec 23, 1998, 3:00:00 AM12/23/98
to
In article <36800B10...@gmx.de>,

Michael Scharf <Michael...@gmx.de> wrote:
>This comes up every few month (search in dejanews for 'assignment expression'
>and you'll find some answers).

At the risk of being monotonous, I'd like to repeat the first two lines of my
original post:



>We all realize that assignment isn't an operator. It's easy enough to chant
>that when someone asks about why they can't do "if line = fp.readline():".

What could I have done to make it more clear that I was talking about
changing the syntax for conditionals, *NOT* turning assignment into
an expression?

Sean
--
A smart terminal is not a smart*ass* terminal, but rather a terminal
you can educate. -- Rob Pike

Tim Peters

unread,
Dec 24, 1998, 3:00:00 AM12/24/98
to
[Sean Reifschneider]

> We all realize that assignment isn't an operator. It's easy
> enough to chant that when someone asks about why they can't do
"if line = fp.readline():".
> However, it seems fairly clear that this restriction results in kludges
> like:
>
> while 1:
> line = fp.readline()
> if not line: break
> print line
>
> In a language which is touted as being so clear, I'm kind of
> surprised that this hasn't received more attention.

It's received *enough* attention, though, that the very thought of replying
to yet another msg about it makes me a bit physically ill <0.7 wink>.

I've done more than my share of supplying stupid "workarounds", so I guess I
deserve that. In real life I always use the "kludge" you listed above.

> It would seem that one could set up a variable or possibly a set
> of variables which would contain the value of the expression in the
> last executed conditional:
>
> while fp.readline():
> if re.match(whileVar, r'^\s*(\S+)\s*=\s*(\S+)\s*$'):
> print 'Assignment "%s" = "%s"' % ( ifVar.group(1),
> ifVar.group(2) )


> This has the benefit of allowing you to easily see the
> termination condition for the while loop, instead of assuming it's
> infinite until you search through (the possibly complex) body.

Actually, when I see

while 1:

I assume the opposite: that it's a finite loop and I'll find an "if ...:
break" one or two lines down. I'm rarely disappointed <wink>.

> This would seem to eliminate the required kludge, while still
> keeping with the basic spirit of Python. However, before going
> through and making a patch for Python, I wanted to see what comments
> folks had on this idea.

Frankly, I hate it. Vars with magic names that change bindings as a result
of magical side-effects sounds more Perlish than Pythonish to me. The only
thing Python has like that now is the one-character "_" as a convenience in
interactive mode.

Believe it or not, I *do* sympathize with your complaint -- while I'm used
to it now, I've never *liked* writing "while 1:" (for the very reasons you
state), and think it would be peachy to peel the conditional banana.

> The next logical step I could see would be adding a variant to
> conditionals:
>
> while [ <word> = ] <expression>:
>
> where if the optional [ <word> = ] part of the while statement
> were there it would assign the expression value to <word> in addition
> to the whileVar.

Ack, no -- this is almost certainly what Guido was trying to *avoid*, i.e.
the ridiculous subtle bugs that pop up in C from writing

while (x = f()) { ... }

by mistake when

while (x == f()) { ... }

was intended. God knows, just last week I tracked down what turned out to
be a

assert(n = 1);

bug in C++ (that assert is a self-fulfilling prophecy <snarl>).

Every post-C language except the no-choice-in-the-matter C++, and Perl (&
now Ruby too, alas), has moved heaven and earth to avoid propagating this
miserable design error.

> But then what would be the point of having the whileVar?

Absolutely none -- which is good <wink>. I've said before that I favor

while x := f():

i.e. use the currently-unused ":=" to mean binding-as-expression.

> Is the only concern that this will be confused with the "==" comparison
> operator?

It's a major concern, yes. Whether it's Guido's only concern "in theory" I
don't know. Based on his well-known fear of lexical scoping <wink>, he
could also harbor some terror about abuses like:

while (sum := (x := f()) + (y := g()) + (z := h())) < (lim := i()):
print "sum", sum, "<", lim, "prod", x*y*z

But I think the best way to encourage clean code is to ridicule newbie code
postied to c.l.py <wink>.

> In that case, would
> while [ <word> assign_the_value_of ] <expression>:
> (or something similar) be more appropriate?

Definitely, if it flies at all.

> Or perhaps even something along the lines of
> <word> = while <expression>:
>

> That feels a bit strange, but surely won't be mistaken for
> a comparator...

This appears to be an instance of the ever-popular yet never-successful
c.l.py meta-strategy that when you can't get Guido to adopt a reasonable
suggestion, try an insane one <0.98 wink>.

> The only issue I see with this is the scope of the "whileVar". Presumably
> one could limit the scope by doing a "whileVar = None", or perhaps the
> termination of a while would imply that?

while e1():
while e2():
# what does whileVar mean here -- e1 or e2? e2, I guess.
# any way to get at e1?
# what does whileVar mean *here*? None? or is there some magical
# stack of whileVars and the binding to e1 got restored when the
# inner while terminated?
if whileVar in ('End', 'Quit'):
break
# and now what? I can't get at the value that caused the loop to break?

All of those irksome questions (& many more) are sidestepped cleanly by
letting the user bind their own vars explicitly when & as they feel they
need to.

the-most-disagreeble-supporter-you're-likely-to-find<wink>-ly y'rs - tim

Andrew M. Kuchling

unread,
Dec 24, 1998, 3:00:00 AM12/24/98
to
Tim Peters quoted:

>[Sean Reifschneider]
>> We all realize that assignment isn't an operator. It's easy
>> enough to chant that when someone asks about why they can't do
> "if line = fp.readline():".
>> However, it seems fairly clear that this restriction results in kludges
>> like:
>>
>> while 1:
>> line = fp.readline()
>> if not line: break
>> print line

IMHO the problem isn't not being able to do assignments, or
get the result of some expression, inside a while. It's that Python
only has 'while', and no do..while:

do:
line = fp.readline()
while not line


This is one of my few problems with the language, and though I've
gotten used to writing 'while 1'...'if something: break', it still
gives me a twinge of annoyance every time I do it.

(Aside: didn't someone suggest generalizing do...while once by
allowing conditions inside the block? Can't pull it up in Dejanews,
though.)

--
A.M. Kuchling http://starship.skyport.net/crew/amk/
>VERY cool mod, Peter. I'll be curious to see GvR's reaction to your
syntax.
Hm.
-- Nick Seidenman and Guido van Rossum, 1 Aug 1996


Guido van Rossum

unread,
Dec 24, 1998, 3:00:00 AM12/24/98
to
Before I go, here's a potential way out. Perhaps there could be an
alternate assignment operator, <-, which *is* allowed in expressions.
You could then write

while line <- fp.readline():
...process line...

I'm not sure I like it myself, but it would sure avoid the confusion
betwee = and ==, and I don't think that much confusion between < and
<- is likely.

Just a thought for the holidays,

--Guido van Rossum (home page: http://www.python.org/~guido/)

Guido van Rossum

unread,
Dec 24, 1998, 3:00:00 AM12/24/98
to
> do:
> line = fp.readline()
> while not line

But what if you want to do more with the line? Algol-68 had something
like this:

do:
...some code...
while condition:
...more code...

(except they also combined it with the for loop in some way).

PS Andrew: I won't be in today; happy Holidays,

Ivan Van Laningham

unread,
Dec 24, 1998, 3:00:00 AM12/24/98
to
Hi All, & Merry Christmas!

Guido van Rossum wrote:
>
> Before I go, here's a potential way out. Perhaps there could be an
> alternate assignment operator, <-, which *is* allowed in expressions.
> You could then write
>
> while line <- fp.readline():
> ...process line...
>
> I'm not sure I like it myself, but it would sure avoid the confusion
> betwee = and ==, and I don't think that much confusion between < and
> <- is likely.
>
> Just a thought for the holidays,
>

Eeeeuuwww. Sorry. The devil made me say it. But I *much* prefer Uncle
Timmy's ``:='' operator.

<- is-to- := -as-slugs-are-to-snails-ly y'rs,
Ivan
----------------------------------------------
Ivan Van Laningham
Callware Technologies, Inc.
iva...@callware.com
http://www.pauahtun.org
----------------------------------------------

Hans Nowak

unread,
Dec 24, 1998, 3:00:00 AM12/24/98
to
The amazing Guido van Rossum wrote:

>Before I go, here's a potential way out. Perhaps there could be an
>alternate assignment operator, <-, which *is* allowed in expressions. You
>could then write
>
> while line <- fp.readline():
> ...process line...

Cool, but wouldn't that collide with code like

while x<-2:
do_something()
x = x - 1
?

In other words, isn't there ambiguity between "while x < -2" and "while x <-
2"? If so, how will it be resolved?

+ Zephyr Falcon | Storm Seeker | Hans Nowak
+ Homepage (under construction): http://www.cuci.nl/~hnowak/
+ You call me a masterless man. You are wrong. I am my own master.
+ May Grandma Moses cheat on your fiance with your cream and sour onion chips!

Tim Peters

unread,
Dec 24, 1998, 3:00:00 AM12/24/98
to
[Guido van Rossum]

> Before I go, here's a potential way out. Perhaps there could be an
> alternate assignment operator, <-, which *is* allowed in expressions.
> You could then write
>
> while line <- fp.readline():
> ...process line...

That's the one I keep suggesting, although I've spelled it := for backward
compatibility (e.g. "while i<-3:" already means something else; ":=" is
never legit now), and because that digraph does mean assignment in several
other languages Python would not be ashamed to eat dinner with. Note that
the colon here won't confuse pymode (or other simple but not braindead
regexp-based parsers) either.

> I'm not sure I like it myself, but it would sure avoid the confusion

> between = and ==, and I don't think that much confusion between < and
> <- is likely.

Trust me: you'll never *really* like it, because it opens a door to all
sorts of obfuscated abuse. But you *would* like it in tasteful code that
you and I write, and we can bully everyone else into playing nice too by
merciless public shaming of bad taste <wink>.

"if m := regexpobject(match):"-dreaming-ly y'rs - tim

jim....@mci.com

unread,
Dec 24, 1998, 3:00:00 AM12/24/98
to
Hans Nowak wrote:

> The amazing Guido van Rossum wrote:
>

> >Before I go, here's a potential way out. Perhaps there could be an
> >alternate assignment operator, <-, which *is* allowed in expressions. You
> >could then write
> >
> > while line <- fp.readline():
> > ...process line...
>

> Cool, but wouldn't that collide with code like
>
> while x<-2:
> do_something()
> x = x - 1
> ?
>
> In other words, isn't there ambiguity between "while x < -2" and "while x <-
> 2"? If so, how will it be resolved?

Significance of whitespace--another mechanism courtesy of 'The Amazing Guido".

Christopher Tavares

unread,
Dec 24, 1998, 3:00:00 AM12/24/98
to

Guido van Rossum wrote in message
<1998122414...@eric.cnri.reston.va.us>...

>> do:
>> line = fp.readline()
>> while not line
>
>But what if you want to do more with the line? Algol-68 had something
>like this:
>
> do:
> ...some code...
> while condition:
> ...more code...
>
>(except they also combined it with the for loop in some way).


I'm just a python nobody, but I have to say that I *REALLY*, *REALLY* like
this. It's completely general, easy to understand, and lets us avoid the
damn assignment morass. The only down side is the new keyword. Well, maybe
Python 1.6?

This is similar to something from my obscure computer languages collection.
Anyone out there remember Basic-09? This was a language that combined the
best of Basic and Pascal (kinda like VB combines the worst <G>). There was a
control structure there that worked like this:

do
.... some stuff ...
exitif condition
... stuff on exit ...
endexit
.... more stuff ....
loop

This worked very well in practice, although I never saw a real reason for
the ... stuff on exit ... section.

-Chris


Tim Peters

unread,
Dec 25, 1998, 3:00:00 AM12/25/98
to
[Andrew M. Kuchling]

> IMHO the problem isn't not being able to do assignments, or
> get the result of some expression, inside a while. It's that Python
> only has 'while', and no do..while:
>
> do:
> line = fp.readline()
> while not line

I don't understand what you're suggesting there: like, where does the
*code* go? If it's after the "line =" but before the "while" as in C, it
would have to look like

do:
line = fp.readline()
if line:
code goes here
code goes here
code goes here
while not line

to do the same thing, and that's no improvement over

while 1:
line = fp.readline()
if not line:
break

code goes here
code goes here
code goes here

Or does the condition on the "while" magically get evaluated right after the
first stmt following the "do" is executed <wink/shiver>?

> This is one of my few problems with the language, and though I've
> gotten used to writing 'while 1'...'if something: break', it still
> gives me a twinge of annoyance every time I do it.

Same here.

> (Aside: didn't someone suggest generalizing do...while once by
> allowing conditions inside the block? Can't pull it up in Dejanews,
> though.)

Terry Reedy made a good pitch, in thread

Proposal: do-while-(do) (was [Q] Perl vs. Python)

from late June. I still recommend that people read Knuth's classic
"Structured Programming with Gotos" for a slew of creative approaches.

Assignment-as-expression is good for more than just exit-at-the-top loops,
though. It can be genuinely helpful whenever a function may return a
special-case value. Most frequently this year, I've dutifully replied to
msg after msg griping about:

m = re.search(re1, line)
if m:
xxx(m)
else:
m = re.search(re2, line)
if m:
yyy(m)
else:
m = re.search(e3, line)
if m:
zzz(m)
else:
poop()

etc. There are other ways to write this, but I twinge too at trotting them
out because there's really no way as simple or clear as the obvious thing
the complainer *wants* to do:

if m := re.search(re1, line):
xxx(m)
elif m := re.search(re2, line):
yyy(m)
elif m := re.search(re3, line):
zzz(m)
else:
poop()

I'd trade the reduction in artificial nesting (or clever convolution to
avoid it some other way) for the chance that some dribbler will abuse it:

def fac(n):
a=long(n or 1)
while(n:=n-1)>1 and a:=a*n:pass
return a

it-would-sure-make-obfuscated-python-contests-more-fun<wink>-ly y'rs - tim

Magnus L. Hetland

unread,
Dec 25, 1998, 3:00:00 AM12/25/98
to

I'm a bit tired -- sorry if I ramble on a bit :)

"Christopher Tavares" <tav...@connix.com> writes:

> Guido van Rossum wrote in message
> <1998122414...@eric.cnri.reston.va.us>...

> >> do:
> >> line = fp.readline()
> >> while not line

(I guess that should be "while line"...)

> >
> >But what if you want to do more with the line? Algol-68 had something
> >like this:
> >
> > do:
> > ...some code...
> > while condition:
> > ...more code...
> >

Meaning...?

> >(except they also combined it with the for loop in some way).

(And the if/else, and the def and ... seems a bit convoluted. ;)

> I'm just a python nobody, but I have to say that I *REALLY*, *REALLY* like
> this. It's completely general, easy to understand,

Okay, call me stupid, but I don't think it's easy to understand. Does
it mean the same as:

while 1:
...some code...
if not condition: break
...more code...

? Actually I think this is clearer (although not as "pretty"). I
usually relate these control structures to natural language... This
latter thing means:

Until I tell you otherwise:
Do something
If some condition: Stop everything
Do something more

The thing above might be stated as:

Do something while some condition is true do something else.

What does that mean? It's not even a proper sentence...

Oh well...

> and lets us avoid the
> damn assignment morass.

Yes, it does... However, going from while to do--while is very simple.

do:
line = fp.readline()
print line
while line

is the same as

line = fp.readline()
while line:
print line
line = fp.readline()

Now this seems pretty clear to me. And if we wanted to have the
functionality of the do--while loop without sacrificing standard
Python syntax, how about using repeat--until without the "repeat"?

until not line:
line = fp.readline()
print line

(This executes the body once before checking the condition)

Or maybe it should be possible to do something like...

while line=fp.readline(); line:
print line

> The only down side is the new keyword. Well, maybe
> Python 1.6?

New keyword ... that sounds more like P2...

> do
> .... some stuff ...
> exitif condition
> ... stuff on exit ...
> endexit
> .... more stuff ....
> loop

Sounds cool enough... and quite similar to the standard "while 1: ...
if condition: break ..." thing. Almost identical, in fact :)

My professor Arne Halaas published an article on another control
structure in 1975, which is quite general. He called it "detect". It
works like this:

DETECT <event1> OR <event2> OR ... OR <eventn>
IN
...
NI

The events can be either constants or event-variables given some value
(I'm not quite clear on their function... ;)

The event constants are used in the loop like this:

<event3> {some code};

Thus if the event is detected by the surrounding DETECT-block, the
code in the {} part is executed and execution is resumed after the NI
part of the DETECT-block. Several events could be used, like in

<event1> OR <event2> {some code};

These indicator statements may be mixed with ordinary code (sorta like
break statements). In his article, Halaas uses the example of the
Quicksort Partition algorithm using what might be seen as two
coroutines moving element up and down:
(Array elements A(m)..A(n) are to be partitioned)

i := m-1; j := n;
v := A(n);
DETECT partition done
IN
DETECT downmovej
IN
i := i+1;
IF i=j THEN partition done;
IF A(i)>v THEN downmovej {A(j):=A(i);};
NI
DETECT upmovei
IN
j := j-1;
IF j=i THEN partition done;
IF A(j)<v THEN upmovei {A(i):=A(j);};
NI
NI
A(j):= v

A suitable Python syntax for this sort of thing might be (I'm changing
it a bit here, I guess -- removing the {}-part, making it necessary to
use if-statements. I think that would be clearer in Python...):

i = m-1
j = n
v = A[n]

detect "Partition_done":

detect "Move j down":
i = i+1
if i==j: break "Partition done"
if A[i] < v:
A[j] = A[i]
break "Move j down"

detect "Move i up":
j = j-1
if j==i: break "Partition done"
if A[j] < v:
A[i] = A[j]
break "Move i up"

A[j] = v

This looks quite like labelled breaks, I guess... (The use of strings
in the above is arbitrary -- one might easily have a separate label
type or something...)

One advantage of the detect structure (as Halaas points out) is that
the events may be used to make the code document itself quite nicely.
You clearly see why things are happening.

Now -- back to the original problem...

detect "End of file":
line = fp.readline()
if not line: break "End of line"
print line

I kind of like this approach (though I'm sure my syntax suggestions
leave a lot to be desired). In the simple example above, the labels
may not be very useful, but the partition example shows how they may
be. Anyway, even in this simple example, I think the mechanism looks
prettier than arbitrarily looping forever, and then later breaking
out... At least here you show what you are waiting for.

And if we *must* use the endless looping solution (without any labels)
can't we *please* have a separate keyword like "loop"? "while 1" seems
so arbitrary...

loop:


line = fp.readline()
if not line: break
print line

That isn't so bad, is it? (Of course it can't be nested -- but the
"detect" structure can...)

And lastly: Any errors or shortcomings in the detect-presentation
above are mine alone.

--

Magnus
Lie
Hetland www.pvv.org/arcadia <arc...@pvv.org>

Magnus L. Hetland

unread,
Dec 26, 1998, 3:00:00 AM12/26/98
to

"Tim Peters" <tim...@email.msn.com> writes:

[...]

Just a thought -- what about a statement/expression-expression, like
(statement; ... statement; expression) returning the value of the
expression?

Then things like

while l = fp.readline():
print l

could be written

while (l = fp.readline(); l):
print l

I suggested this, without the parentheses in a former post, but that
was only for while loops and if sentences etc. A general construct
like this could be used anywhere... (I got the idea from the "Tiger"
language...)

>
> if m := re.search(re1, line):
> xxx(m)
> elif m := re.search(re2, line):
> yyy(m)
> elif m := re.search(re3, line):
> zzz(m)
> else:
> poop()
>

if (m = re.search(rel, line); m):
xxx(m)
.
.
.

Or alternatively:

if m=re.search(rel, line); m:
xxx(m)
.
.
.

Seems logical to me...

>
> def fac(n):
> a=long(n or 1)
> while(n:=n-1)>1 and a:=a*n:pass
> return a
>

def fac(n):
a=long(n or 1)

while (n=n-1;n)>1 and (a=a*n;a): pass
return a

Doesn't look *too* bad, does it? (Isn't this how the comma operator
works in C?)

Tim Peters

unread,
Dec 26, 1998, 3:00:00 AM12/26/98
to
[Magnus L. Hetland]
> ...

> My professor Arne Halaas published an article on another control
> structure in 1975, which is quite general. He called it "detect".

See Knuth's "Structured Programming with Gotos" for variants of this
approach; they were quite popular in the 70's, if not in actual languages at
least as a topic in unread papers <wink>.

> ...


> And if we *must* use the endless looping solution (without any labels)
> can't we *please* have a separate keyword like "loop"? "while 1" seems
> so arbitrary...

There's nothing magic about 1! You can (& I sometimes do) write stuff like:

while "fp has more stuff":


line = fp.readline()
if not line:
break

process(line)

This is a bit slower than "while 1:" today, but nothing a peephole optimizer
couldn't safely squash out of existence.

Similarly in C or C++ it's often better to write

assert(!"wow -- unto the root is born a brother!");

than

assert(0);

high-on-christmas-cashews-and-chocolate-ly y'rs - tim

scott cotton

unread,
Dec 27, 1998, 3:00:00 AM12/27/98
to

This sounds wonderful, absolutely wonderful, except that I
agree that ':=' would be preferable. It'd force a bit of
reprogramming python-mode.el i would guess, though.

Some other operator ideas:

?= (i like this one...)
@= (hmmm.)

scott

On Thu, Dec 24, 1998 at 09:36:47AM -0500, Guido van Rossum wrote:
| Before I go, here's a potential way out. Perhaps there could be an
| alternate assignment operator, <-, which *is* allowed in expressions.
| You could then write
|
| while line <- fp.readline():
| ...process line...
|

| I'm not sure I like it myself, but it would sure avoid the confusion

| betwee = and ==, and I don't think that much confusion between < and
| <- is likely.
|

| Just a thought for the holidays,
|

Dirk Heise

unread,
Dec 27, 1998, 3:00:00 AM12/27/98
to
> On Thu, Dec 24, 1998 at 09:36:47AM -0500, Guido van Rossum wrote:
> | Before I go, here's a potential way out. Perhaps there could be an
> | alternate assignment operator, <-, which *is* allowed in expressions.
> | You could then write
> |
> | while line <- fp.readline():
> | ...process line...
> |
> | I'm not sure I like it myself, but it would sure avoid the confusion
> | betwee = and ==, and I don't think that much confusion between < and
> | <- is likely.

while a <-4:

Have another go ;-)

Dirk


Evan Simpson

unread,
Dec 27, 1998, 3:00:00 AM12/27/98
to
Well, as long as you seem to be considering the candidates, I shall once
again put forward my own ugly little brainchild, to wit:

while =line= fp.readline():
#process line

Which, for those who haven't already seen it struck down in its youth, is
simply the extension of "x = y = z = 0" type notation into an expression via
the leading "=". It is illegal in current code, requires no additional
keywords or symbols, and absolutely cannot produce "="/"==" errors in sane
human beings (or Tims, I believe).

Failing that, ":=" is a fine alternative.

Guido van Rossum wrote in message
<1998122414...@eric.cnri.reston.va.us>...

Allen Ethridge

unread,
Dec 28, 1998, 3:00:00 AM12/28/98
to

Guido van Rossum wrote:

> Before I go, here's a potential way out. Perhaps there could be an
> alternate assignment operator, <-, which *is* allowed in expressions.
> You could then write

> while line <- fp.readline():
> ...process line...

> I'm not sure I like it myself, but it would sure avoid the confusion
> betwee = and ==, and I don't think that much confusion between < and
> <- is likely.

> Just a thought for the holidays,

What about "->", as in

while fp.readline() -> line:
...process line...

It'd sure make me for more at home with Python. And it's really
quite pleasant once you get used to it. But I'm to new to Python
to come up with any "a->b" ambiguities.

Allen

Bjorn Pettersen

unread,
Dec 28, 1998, 3:00:00 AM12/28/98
to
I thought there was something I didn't like about <-, but I couldn't put my
finger on it... until I typed:

def f(x):
return x

y = -20

while y<-f(5):
print y

bjornbjornbjornbjornbjorn...

Ivan Van Laningham wrote:

> Hi All, & Merry Christmas!
>

> Guido van Rossum wrote:
> >
> > Before I go, here's a potential way out. Perhaps there could be an
> > alternate assignment operator, <-, which *is* allowed in expressions.
> > You could then write
> >
> > while line <- fp.readline():
> > ...process line...
> >
> > I'm not sure I like it myself, but it would sure avoid the confusion
> > betwee = and ==, and I don't think that much confusion between < and
> > <- is likely.
> >
> > Just a thought for the holidays,
> >
>

jim....@mci.com

unread,
Dec 28, 1998, 3:00:00 AM12/28/98
to
All,

Sorry if this is a FAQ.
Looked in the mailing list since 12/7--no mention.
Looked in the FAQ--not there.
Searched in ftp site, website, SIG archives, Starship--not there.

I'm having difficulty installing Python on my NT Workstation box.

When I try to install, it says I must have admin rights and to log in as
admin to install.

I do have admin rights, but can't perform the installation as another user.

Couldn't we check for admin rights, rather than for login as admin?

I do not have (and won't get) the Admin login.

help!

TIA,

--jim


Magnus L. Hetland

unread,
Dec 29, 1998, 3:00:00 AM12/29/98
to
Allen Ethridge <ethr...@onramp.net> writes:

> Guido van Rossum wrote:
[...]


>
> What about "->", as in
>

Good idea -- as opposed to <-... But I still don't *quite* see the
need for it. I do agree that more powerful control structures may be
desirable, but this is a very small addition, at the cost of new
syntax.

> while fp.readline() -> line:
> ...process line...

At the cost of writing the assignment once more, you can have this:

line = fp.readline()
while line:

...process line...
line = fp.readline()

This is quite clear and simple, in my opinion -- and it is general
too, as opposed to the "while x=spam():" thing. It can be used in
f.eks.

x = 1
while x < 10:
print x
x = x+1

Quite standard, and quite readable.

In the case of counting down, you could write

while x-1 -> x:
print x

I must say I find that less readable, although I admit it is more
succinct.

If what you need it for is primarily iterating throug lines in file
objects, why not use:

for line in fp.readlines():
...process line...

That is simpler than all of the above, IMHO.

And another idea.... How about a local variable "it", like in
HyperTalk and all its variations? I fondly remember writing:

get the square of 2
put it into x

We could have something like:

while fp.readline():
print it

Or

while fp.readline():
line = it
...process line...

This could be used in other structures too...

if contents: process(it)

I mean -- that's the problem here, isn't it? Retaining the value of
the fp.readline() after the check? (To solve that, one might of course
make fp the instance of an iteration class which has a separate method
for checking...

while fp.has_more_lines():
print fp.readline()

)

A-bit-tired-with-my-brain-all-over'ly yrs

Magnus L. Hetland

unread,
Dec 29, 1998, 3:00:00 AM12/29/98
to

How about another keyword like "indexing"?

while line updated line=fp.readline():
print line

Maybe even

for line updated line=fp.readline():
print line

That is -- "for all the lines in the sequence created by the update
'line=fp.readline()'". When the updated variable is None, the sequence
has ended... (Of cours, one could not use "false" as an ending
condition here, or you could not iterate over boolean information etc.)

Oh, well -- it was just a thought.

jim....@mci.com

unread,
Dec 29, 1998, 3:00:00 AM12/29/98
to
Registry problem--got the site admin to do the installation.


jim....@mci.com wrote:

> All,

Gordon McMillan

unread,
Dec 29, 1998, 3:00:00 AM12/29/98
to
Jim Kraai wrote:

> I'm having difficulty installing Python on my NT Workstation box.
>

> When I try to install, it says I must have admin rights and to log
> in as admin to install.
>
> I do have admin rights, but can't perform the installation as
> another user.
>
> Couldn't we check for admin rights, rather than for login as admin?
>

> I do not have (and won't get) the Admin login.

I think it is checking rights, not the login (since I do it under my
login). I doubt you really have full admin rights. I suspect the
right in question is to modify the HKEY_LOCAL_MACHINE section of the
registry.

- Gordon

Bjorn Pettersen

unread,
Jan 4, 1999, 3:00:00 AM1/4/99
to
The problem with

line = fp.readline()
while line:
...

line = fp.readline()

is if you have to do other things before you assign to line (you'll then
need to keep your code in sync). Which leads to the ugly while 1
idiom....

Using

for line in fp.readlines():
...

would work great, except it's quite a strain when the file length
approches 1Gb (actually a long time before that, but you get my point...)
It is also not general.

Check out the other threads on this topic for lots of reasons why people
need this feature.

-- bjorn


Christopher G. Petrilli

unread,
Jan 4, 1999, 3:00:00 AM1/4/99
to
Bjorn Pettersen <bj...@roguewave.com> wrote:
> line = fp.readline()
> while line:
> ...
> line = fp.readline()

> is if you have to do other things before you assign to line (you'll then
> need to keep your code in sync). Which leads to the ugly while 1
> idiom....

It's not "perfect" but I regularly process files that are several
hundered megabytes with Python (building data-structures in memory that
are 50-100Mb each) without any problem with this. If this is something
I have to suffer with because any solution is a kludge, then I'll live
with it.

> Using

> for line in fp.readlines():
> ...

> would work great, except it's quite a strain when the file length
> approches 1Gb (actually a long time before that, but you get my point...)
> It is also not general.

Have you checked out the fileinput module? This works great for a lot
of things.

> Check out the other threads on this topic for lots of reasons why people
> need this feature.

Always be careful of the implied differences between need and WANT. I
want a lot of things, I haven't found a single thing in 3 years in
Python that I absolutely NEED to be added because it's fatal without it.

ALl languages have idioms.

Chris
--
| Christopher Petrilli
| petr...@amber.org

Evan Simpson

unread,
Jan 4, 1999, 3:00:00 AM1/4/99