Re: for / while else doesn't make sense

2016-06-15 Thread Lawrence D’Oliveiro
On Thursday, June 16, 2016 at 1:51:54 AM UTC+12, Random832 wrote:
> ... and in particular it does not establish that break is in any way
> less structured than any other constructs that have keywords.

Interesting that those who objected to my use of while-True-break loops could 
not come up with any unified alternative way of writing them. Every single 
example I posted had to be handled differently, as opposed to my common way of 
dealing with them.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-15 Thread Lawrence D’Oliveiro
On Thursday, June 16, 2016 at 2:32:00 AM UTC+12, Rustom Mody wrote:

> Here is C.A.R Hoare's Turing award speech:
> https://www.cs.fsu.edu/~engelen/courses/COP4610/hoare.pdf
> 
> in which (2nd last page) he claims that Ada is a threat to civilization...
> because it has something as terrible as exceptions.

He was wrong about the dangers of Ada. It has been successfully used in many 
life-critical situations (e.g. the life support system on the International 
Space Station).

He was a fan of the simplicity of Pascal, though that speech says nothing about 
C (and C++ hadn’t been invented yet...). In the end, I guess, Pascal proved too 
fiddly to do things in that C could manage easily.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-15 Thread Steven D'Aprano
On Thu, 16 Jun 2016 03:03 am, Rustom Mody wrote:

> So break also has its uses. Lets just not pretend its structured


What's your definition of "structured" that makes "break" unstructured?

Suppose I have a language, L, with a keyword "fnord". How do I tell whether
the fnord feature makes the language unstructured or not?




-- 
Steven

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-15 Thread Steven D'Aprano
On Wed, 15 Jun 2016 09:19 pm, Rustom Mody wrote:

> On Wednesday, June 15, 2016 at 8:42:33 AM UTC+5:30, Steven D'Aprano wrote:
>> On Wed, 15 Jun 2016 01:33 am, Rustom Mody wrote:
[...]
>> > And break is a euphemism for goto
>> 
>> Sort of. A break is a jump, and a goto is a jump, but apart from that,
>> they're not really the same thing. A goto can jump (almost) anywhere.
>> Depending on the language, they can jump into the middle of functions, or
>> into the middle of loops. That's what makes them powerful enough to break
>> compositionality. But break can only jump to a single place: to the
>> statement that follows the for...else compound statement. It's more like
>> a return than a goto.
> 
> I thought there'd be many examples for showing that break is just goto in
> disguise... Evidently not
> 
> So here is an example in more detail for why/how   break=goto:
> 
> http://blog.languager.org/2016/06/break-is-goto-in-disguise.html

Quote: "For now lets just agree that break is not very different from goto"

Let's not.

Your argument seems to be:

"I can use GOTO to jump outside of a loop. I can use BREAK to jump outside
of a loop. Careless use of jumping out of a loop leads to a bug, regardless
of whether that jump is written as GOTO or BREAK. Therefore GOTO and BREAK
are the same thing."

but you have failed to consider:

"I can use GOTO to jump inside a loop. I *cannot* use BREAK to jump inside a
loop. I can use GOTO to jump back to before the loop. I *cannot* use BREAK
to jump back before the loop. In the most general case of completely
unstructured programming, I can use GOTO to jump I can use GOTO to jump out
of one function into the middle of another function, or any other arbitrary
line of code anywhere in my program. I *cannot* do the same with BREAK."


If you only consider the similarities, and not the differences, you would
erroneously conclude that all sorts of things that are actually quite
different are "similar".

"Cars are actually not so different from the Space Shuttle. Here's video of
the shuttle taxiing down the runway after returning from space. Here's a
video of a car driving along a road. Careless driving can run over
pedestrians, regardless of whether you are driving a car or taxiing a space
shuttle. Therefore cars and space shuttles are not that different."

Congratulations, you have discovered that mechanically replacing careless
use of GOTO with careless use of BREAK doesn't necessarily make the code
less buggy. That's a valuable lesson for cargo-cult programmers who think
that its the *word* "goto" that causes bad things to happen, and changing
the word magically will fix the bug. But to the rest of us, it's about as
insightful as the discovery that mechanically replacing "x*5"
with "x+x+x+x+x" won't fix the off-by-one error that you actually
needed "x*6".



-- 
Steven

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-15 Thread Random832
On Wed, Jun 15, 2016, at 13:18, Michael Selik wrote:
> On Wed, Jun 15, 2016, 10:28 AM Rustom Mody  wrote:
> 
> > Where did the question of "break can be written as goto" come from?
> >
> 
> Stephen said the "else" in for-else was "unconditional". He argued that
> neither the presence nor absence of a break should be considered a
> condition, because we don't consider the occurrence or non-occurrence of
> an
> exception (goto) as a condition of whether to run the else-clause.

Okay... so why don't we consider the else in *if*-else unconditional?
After all, the same logic applies: it only doesn't run if a statement
defined to jump past it (in one case, the true part of the if statement
- in the other case, a break) is run.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-15 Thread BartC

On 15/06/2016 18:03, Rustom Mody wrote:


OTOH Duff's device shows terrifyingly unstructured code with nary a goto/break
in sight


I agree, and these mostly originate in C. It's full of crude features 
that should have been pensioned off decades ago, but amazingly it is 
still around and highly influential!



So break also has its uses. Lets just not pretend its structured


It's a short-circuit operator that gets you to the end of the current 
loop block.


There's one here too:

   if a:
  b
  c
   else:
  d

It's called 'else' and is unconditional (when you finish executing the 
'c' line, you then skip to the end of the next block).


This is another short-circuit operator:

  if a and b(c):
 d
 e

(I assume Python has short-circuit evaluation; if not then plenty of 
languages do). When a is False, the b(c) function call is skipped.)


If that's not enough, then 'return' in most languages will let you 
return early from a routine, skipping the rest of the function.


--
Bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-15 Thread Michael Selik
On Wed, Jun 15, 2016, 10:28 AM Rustom Mody  wrote:

> Where did the question of "break can be written as goto" come from?
>

Stephen said the "else" in for-else was "unconditional". He argued that
neither the presence nor absence of a break should be considered a
condition, because we don't consider the occurrence or non-occurrence of an
exception (goto) as a condition of whether to run the else-clause.

>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-15 Thread Rustom Mody
On Wednesday, June 15, 2016 at 9:24:21 PM UTC+5:30, Random832 wrote:
> On Wed, Jun 15, 2016, at 10:20, Rustom Mody wrote:
> > Claim is that the damaging propensities of goto are replicable with
> > break.
> 
> The "damaging propensity" in this particular case simply comes from the
> fact that it's a statement that can appear in the body of an if
> statement (the real flaw that caused the bug here here was the optional
> braces of the if statement), which is just as true of anything else. It
> could have called a function that it shouldn't have called.

People have adduced various reasons:
1. Optionality of braces
2. gcc silently non-mentioning dead code
3. indentation and braces mismatch -- were it python(ish) the second goto would
be harmless dead code INSIDE the if
4. Careless merging
5. Culture of cut-paste
6. All kinds of soft questions -- code should be reviewed/pair-programmed/etc
7. Even more irrelevant soft point -- Apple is a bad company for being thus 
irresponsible
8. etc 

> 
> But a lot of people do claim that break should be generally "considered
> harmful" just like goto and never used at all because of this
> isomorphism.

Minor point: I dont think isomorphism is correct
As I said the goto can originate anywhere and target to anywhere (in function 
scope). Not break
longjmp can scale function scopes but has other restrictions like respecting the
stack, the setjmp-site needs to have been visited first.
IOW different unstructured constructs have differing properties

Major point:  "Considered harmful" should be considered harmful :-)
IOW cargo-cult programming without any understanding is worse than specific fads
There are things -- eg automata -- where the most faithful rendering is with
gotos: : labels for states, gotos for transitions.  Any 'more structured' 
solution is usually more messy.

OTOH Duff's device shows terrifyingly unstructured code with nary a goto/break 
in sight

So break also has its uses. Lets just not pretend its structured
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-15 Thread Random832
On Wed, Jun 15, 2016, at 10:20, Rustom Mody wrote:
> Claim is that the damaging propensities of goto are replicable with
> break.

The "damaging propensity" in this particular case simply comes from the
fact that it's a statement that can appear in the body of an if
statement (the real flaw that caused the bug here here was the optional
braces of the if statement), which is just as true of anything else. It
could have called a function that it shouldn't have called.

But a lot of people do claim that break should be generally "considered
harmful" just like goto and never used at all because of this
isomorphism.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-15 Thread Rustom Mody
On Wednesday, June 15, 2016 at 7:21:54 PM UTC+5:30, Random832 wrote:
> On Wed, Jun 15, 2016, at 07:19, Rustom Mody wrote:
> > I thought there'd be many examples for showing that break is just goto in
> > disguise... Evidently not
> >
> > So here is an example in more detail for why/how   break=goto:
> > 
> > http://blog.languager.org/2016/06/break-is-goto-in-disguise.html
> 
> So?
> 
> So are loops. So is any "if" statement whose body isn't itself a
> one-line goto. Showing that break can be written as a goto is
> uninteresting because _any_ form of flow control can be written as a
> goto, and in particular it does not establish that break is in any way
> less structured than any other constructs that have keywords.

Here is C.A.R Hoare's Turing award speech:
https://www.cs.fsu.edu/~engelen/courses/COP4610/hoare.pdf

in which (2nd last page) he claims that Ada is a threat to civilization...
because it has something as terrible as exceptions.

We may or may not agree with his threatening thoughts
Which is different from seeing the simple fact that exceptions are unstructured
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-15 Thread Rustom Mody
On Wednesday, June 15, 2016 at 7:21:54 PM UTC+5:30, Random832 wrote:
> On Wed, Jun 15, 2016, at 07:19, Rustom Mody wrote:
> > I thought there'd be many examples for showing that break is just goto in
> > disguise... Evidently not
> >
> > So here is an example in more detail for why/how   break=goto:
> > 
> > http://blog.languager.org/2016/06/break-is-goto-in-disguise.html
> 
> So?
> 
> So are loops. So is any "if" statement whose body isn't itself a
> one-line goto. Showing that break can be written as a goto is
> uninteresting because 

Where did the question of "break can be written as goto" come from?
Sure all structured constructs have their unstructured counterparts
And that is uninteresting as you say.

Claim is that the damaging propensities of goto are replicable with break.

Well to some extent... the goto can go from anywhere to anywhere within 
function scope, whereas the break's target-end is fixed -- the end of the 
loop/switch. However the starting end can be anywhere in there and that is
a potential for unstructured damage
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-15 Thread Chris Angelico
On Wed, Jun 15, 2016 at 11:51 PM, Random832  wrote:
> if(x) true_body; else false_body;
>
> is syntactic sugar for:
>
> if(!x) goto else;
> true_body;
> goto end;
> else: false_body;
> end: ;

And I remember writing GW-BASIC code like this, because we didn't have
block if. You could put a single statement after an if, but for
anything bigger than that, it was "negate the condition and GOTO the
bit after".

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-15 Thread Random832
On Wed, Jun 15, 2016, at 07:19, Rustom Mody wrote:
> I thought there'd be many examples for showing that break is just goto in
> disguise... Evidently not
>
> So here is an example in more detail for why/how   break=goto:
> 
> http://blog.languager.org/2016/06/break-is-goto-in-disguise.html

So?

So are loops. So is any "if" statement whose body isn't itself a
one-line goto. Showing that break can be written as a goto is
uninteresting because _any_ form of flow control can be written as a
goto, and in particular it does not establish that break is in any way
less structured than any other constructs that have keywords.

C's for loop:

for(i=0;i goto end;]
[continue within body -> goto inc;]

if(x) true_body; else false_body;

is syntactic sugar for:

if(!x) goto else;
true_body;
goto end;
else: false_body;
end: ;
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-15 Thread Rustom Mody
On Wednesday, June 15, 2016 at 5:57:51 PM UTC+5:30, BartC wrote:
> On 15/06/2016 12:19, Rustom Mody wrote:
> > On Wednesday, June 15, 2016 at 8:42:33 AM UTC+5:30, Steven D'Aprano wrote:
> 
> >> Sort of. A break is a jump, and a goto is a jump, but apart from that,
> >> they're not really the same thing. A goto can jump (almost) anywhere.
> >> Depending on the language, they can jump into the middle of functions, or
> >> into the middle of loops. That's what makes them powerful enough to break
> >> compositionality. But break can only jump to a single place: to the
> >> statement that follows the for...else compound statement. It's more like a
> >> return than a goto.
> >
> > I thought there'd be many examples for showing that break is just goto in 
> > disguise... Evidently not
> >
> > So here is an example in more detail for why/how   break=goto:
> >
> > http://blog.languager.org/2016/06/break-is-goto-in-disguise.html
> 
> That example is nothing to do with break vs. goto. You've just replaced 
> an erroneous goto with an erroneous break.

Precisely the point -- that that erroneous goto could be an erroneous break
with minor changes to the code (One needs to be inside a break-able statement
like for/while (or for C do/switch)

> 
> It's to do with C (or C-like syntax if not C) using braces for compound 
> statements at the same time as making them optional for a single statement.
> 
> With the wrong indentation applied, that sort of error can easily be 
> missed. Some tools may be able to pick that up.
> 
> (Another kind of error (C seems to have plenty of capacity in this 
> regard!) is forgetting the */ in a /* ... */ comment. Then code is 
> mysteriously ignored until the end of the next /* ... */ comment. 
> Although a syntax-highlighting editor will pick that up more easily.)

As the links point out there can be any amt of post-mortem analysis
- gcc silently stopped dead code warnings
- the misleading indent -- could be detected by tools
- etc

Doesnt change the fact that that misplaced goto could be a misplaced break
And either did/would JUMP OVER critical code wrongly

tl;dr:
A rose by any name smells sweet
A goto by any name goes-to
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-15 Thread BartC

On 15/06/2016 12:19, Rustom Mody wrote:

On Wednesday, June 15, 2016 at 8:42:33 AM UTC+5:30, Steven D'Aprano wrote:



Sort of. A break is a jump, and a goto is a jump, but apart from that,
they're not really the same thing. A goto can jump (almost) anywhere.
Depending on the language, they can jump into the middle of functions, or
into the middle of loops. That's what makes them powerful enough to break
compositionality. But break can only jump to a single place: to the
statement that follows the for...else compound statement. It's more like a
return than a goto.


I thought there'd be many examples for showing that break is just goto in 
disguise... Evidently not

So here is an example in more detail for why/how   break=goto:

http://blog.languager.org/2016/06/break-is-goto-in-disguise.html


That example is nothing to do with break vs. goto. You've just replaced 
an erroneous goto with an erroneous break.


It's to do with C (or C-like syntax if not C) using braces for compound 
statements at the same time as making them optional for a single statement.


With the wrong indentation applied, that sort of error can easily be 
missed. Some tools may be able to pick that up.


(Another kind of error (C seems to have plenty of capacity in this 
regard!) is forgetting the */ in a /* ... */ comment. Then code is 
mysteriously ignored until the end of the next /* ... */ comment. 
Although a syntax-highlighting editor will pick that up more easily.)


--
Bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-15 Thread Rustom Mody
On Wednesday, June 15, 2016 at 8:42:33 AM UTC+5:30, Steven D'Aprano wrote:
> On Wed, 15 Jun 2016 01:33 am, Rustom Mody wrote:
> 
> > On Tuesday, June 14, 2016 at 8:13:53 AM UTC+5:30, Steven D'Aprano wrote:
> >> No. The sun exploding was me gently mocking you for your comment
> >> disputing the "unconditional" part. Yes, you are technically right that
> >> technically the "else" block will only run if no "break" is reached, and
> >> no "return" is reached, no exception is raised, also that os._exit or
> >> os.abort aren't called, the CPU doesn't catch fire, and the world isn't
> >> destroyed.
> >> 
> >> If we try to enumerate all the things which could prevent the "else"
> >> block from running, we'll be here for decades. But, and this is the point
> >> that everyone seems to have missed, * every single one of those things*
> >> is completely independent of the for...else statement.
> >> 
> >> *Including* the presence or absence of a "break".
> > 
> > This is real wild:  A break that is inside a for is independent of the
> > for?!?!
> 
> If that's what I said, you would be right to question me. But that's not
> what I said.
> 
> It is legal syntax to have for...else without a break, or a break inside a
> for block with no else. And, if you really want to nitpick, you can even
> have a break statement without a for. (Just stick it inside a while loop
> instead.)
> 
> I know that's it's great fun to pick at nits without making a good faith
> effort to communicate, but honestly Rustom, your following comments do
> suggest that you understood what I was saying.
> 
> 
> [...]
> > This *desire* for what you call isolation is a standard tenet of
> > semantics and is right
> > 
> > It is called compositionality
> > 
> > Inn programming:
> > https://en.wikipedia.org/wiki/Denotational_semantics#Compositionality
> > 
> > More general linguistics:
> > https://en.wikipedia.org/wiki/Principle_of_compositionality
> 
> Thanks for that.
> 
> 
> > However gotos break compositionality unless one introduces heavy artillery
> > like continuations
> > 
> > And break is a euphemism for goto
> 
> Sort of. A break is a jump, and a goto is a jump, but apart from that,
> they're not really the same thing. A goto can jump (almost) anywhere.
> Depending on the language, they can jump into the middle of functions, or
> into the middle of loops. That's what makes them powerful enough to break
> compositionality. But break can only jump to a single place: to the
> statement that follows the for...else compound statement. It's more like a
> return than a goto.

I thought there'd be many examples for showing that break is just goto in 
disguise... Evidently not

So here is an example in more detail for why/how   break=goto:

http://blog.languager.org/2016/06/break-is-goto-in-disguise.html

[Return/yield are more interesting and complicated...]
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-14 Thread Rustom Mody
On Wednesday, June 15, 2016 at 8:42:33 AM UTC+5:30, Steven D'Aprano wrote:
> On Wed, 15 Jun 2016 01:33 am, Rustom Mody wrote:
> 
> > On Tuesday, June 14, 2016 at 8:13:53 AM UTC+5:30, Steven D'Aprano wrote:
> >> No. The sun exploding was me gently mocking you for your comment
> >> disputing the "unconditional" part. Yes, you are technically right that
> >> technically the "else" block will only run if no "break" is reached, and
> >> no "return" is reached, no exception is raised, also that os._exit or
> >> os.abort aren't called, the CPU doesn't catch fire, and the world isn't
> >> destroyed.
> >> 
> >> If we try to enumerate all the things which could prevent the "else"
> >> block from running, we'll be here for decades. But, and this is the point
> >> that everyone seems to have missed, * every single one of those things*
> >> is completely independent of the for...else statement.
> >> 
> >> *Including* the presence or absence of a "break".
> > 
> > This is real wild:  A break that is inside a for is independent of the
> > for?!?!
> 
> If that's what I said, you would be right to question me. But that's not
> what I said.
> 
> It is legal syntax to have for...else without a break, or a break inside a
> for block with no else. And, if you really want to nitpick, you can even
> have a break statement without a for. (Just stick it inside a while loop
> instead.)
> 
> I know that's it's great fun to pick at nits without making a good faith
> effort to communicate, but honestly Rustom, your following comments do
> suggest that you understood what I was saying.
> 
> 
> [...]
> > This *desire* for what you call isolation is a standard tenet of
> > semantics and is right
> > 
> > It is called compositionality
> > 
> > Inn programming:
> > https://en.wikipedia.org/wiki/Denotational_semantics#Compositionality
> > 
> > More general linguistics:
> > https://en.wikipedia.org/wiki/Principle_of_compositionality
> 
> Thanks for that.
> 
> 
> > However gotos break compositionality unless one introduces heavy artillery
> > like continuations
> > 
> > And break is a euphemism for goto
> 
> Sort of. A break is a jump, and a goto is a jump, but apart from that,
> they're not really the same thing. A goto can jump (almost) anywhere.
> Depending on the language, they can jump into the middle of functions, or
> into the middle of loops. That's what makes them powerful enough to break
> compositionality. But break can only jump to a single place: to the
> statement that follows the for...else compound statement. It's more like a
> return than a goto.
> 
> You can reason about for...else without the break, then reason about what
> the break does. This isn't hard, and its what people do even in the common
> use-case:
> 
> for x in seq:
> process(x)
> if condition:
> break
> else:
> fnord()
> spam()

Yon need to take an example of the
if condition: break
nested inside some more ifs
with those other conditions giving validity to the condition
eg outer condition being say y != 0
Inner if being 
if x/y == 0 : break

Now you would see that your reasoning about the inner needs potentially the 
FULL CONTEXT  of the outer.
This need to carry large context is the essential property of non-compositional 
semantics.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-14 Thread Steven D'Aprano
On Wed, 15 Jun 2016 01:33 am, Rustom Mody wrote:

> On Tuesday, June 14, 2016 at 8:13:53 AM UTC+5:30, Steven D'Aprano wrote:
>> No. The sun exploding was me gently mocking you for your comment
>> disputing the "unconditional" part. Yes, you are technically right that
>> technically the "else" block will only run if no "break" is reached, and
>> no "return" is reached, no exception is raised, also that os._exit or
>> os.abort aren't called, the CPU doesn't catch fire, and the world isn't
>> destroyed.
>> 
>> If we try to enumerate all the things which could prevent the "else"
>> block from running, we'll be here for decades. But, and this is the point
>> that everyone seems to have missed, * every single one of those things*
>> is completely independent of the for...else statement.
>> 
>> *Including* the presence or absence of a "break".
> 
> This is real wild:  A break that is inside a for is independent of the
> for?!?!

If that's what I said, you would be right to question me. But that's not
what I said.

It is legal syntax to have for...else without a break, or a break inside a
for block with no else. And, if you really want to nitpick, you can even
have a break statement without a for. (Just stick it inside a while loop
instead.)

I know that's it's great fun to pick at nits without making a good faith
effort to communicate, but honestly Rustom, your following comments do
suggest that you understood what I was saying.


[...]
> This *desire* for what you call isolation is a standard tenet of
> semantics and is right
> 
> It is called compositionality
> 
> Inn programming:
> https://en.wikipedia.org/wiki/Denotational_semantics#Compositionality
> 
> More general linguistics:
> https://en.wikipedia.org/wiki/Principle_of_compositionality

Thanks for that.


> However gotos break compositionality unless one introduces heavy artillery
> like continuations
> 
> And break is a euphemism for goto

Sort of. A break is a jump, and a goto is a jump, but apart from that,
they're not really the same thing. A goto can jump (almost) anywhere.
Depending on the language, they can jump into the middle of functions, or
into the middle of loops. That's what makes them powerful enough to break
compositionality. But break can only jump to a single place: to the
statement that follows the for...else compound statement. It's more like a
return than a goto.

You can reason about for...else without the break, then reason about what
the break does. This isn't hard, and its what people do even in the common
use-case:

for x in seq:
process(x)
if condition:
break
else:
fnord()
spam()

"If the condition is never true, then we loop through seq, calling
process(x) each time, then call fnord(), then call spam(). If the condition
becomes true at some point in the loop, we stop looping, and go straight to
calling spam()."

We can reason about the condition is true case separately from the condition
is false case. And we can do so without imagining that there is an
invisible "did_not_break" flag, or needing a second mental model to
understand this ever-so-slightly more complex example:

for x in seq:
process(x)
if condition:
break
else:
foo()
else:
fnord()
spam()



-- 
Steven

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-14 Thread Rustom Mody
On Wednesday, June 15, 2016 at 4:58:05 AM UTC+5:30, Lawrence D’Oliveiro wrote:
> On Wednesday, June 15, 2016 at 3:34:14 AM UTC+12, Rustom Mody wrote:
> 
> > And break is a euphemism for goto
> 
> Is this the old 
> “structured-programming-is-mathematically-equivalent-to-gotos” red herring 
> again?

Are you familiar with Duff's device? 

https://en.wikipedia.org/wiki/Duff%27s_device
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-14 Thread Rustom Mody
On Tuesday, June 14, 2016 at 8:13:53 AM UTC+5:30, Steven D'Aprano wrote:
> No. The sun exploding was me gently mocking you for your comment disputing
> the "unconditional" part. Yes, you are technically right that technically
> the "else" block will only run if no "break" is reached, and no "return" is
> reached, no exception is raised, also that os._exit or os.abort aren't
> called, the CPU doesn't catch fire, and the world isn't destroyed.
> 
> If we try to enumerate all the things which could prevent the "else" block
> from running, we'll be here for decades. But, and this is the point that
> everyone seems to have missed, * every single one of those things* is
> completely independent of the for...else statement.
> 
> *Including* the presence or absence of a "break".

This is real wild:  A break that is inside a for is independent of the for?!?!

Thats about as meaningful a statement as saying that the algebraic expression
"x² + 1" has a value independent of "x"

However see below

> 
> If you want to understand how Python statements work, you should understand
> them in isolation (as much as possible), which then allows you to
> extrapolate their behaviour in combination with other statements. Most
> lines of Python code are understandable in isolation, or at least close to
> isolation. You can get *very close* to a full understanding of Python by
> just reading one line at a time (with perhaps a bit of short term memory to
> remember if you are compiling a function, building a class, etc).
> 
> E.g. you don't need to understand for loops to understand if...else.
> 
> And vice versa: for...else has a well-defined meaning and operates in a
> simple fashion in isolation of other language features. Its not compulsory
> to put a "return" statement inside your for loop. Nor is it compulsory to
> put a "raise" inside it. And "break" is not compulsory either.

This *desire* for what you call isolation is a standard tenet of
semantics and is right

It is called compositionality

Inn programming: 
https://en.wikipedia.org/wiki/Denotational_semantics#Compositionality

More general linguistics: 
https://en.wikipedia.org/wiki/Principle_of_compositionality

However gotos break compositionality unless one introduces heavy artillery like
continuations

And break is a euphemism for goto
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-14 Thread Chris Angelico
On Tue, Jun 14, 2016 at 11:51 PM, Ian Kelly  wrote:
> On Tue, Jun 14, 2016 at 5:39 AM, alister  wrote:
>> On Tue, 14 Jun 2016 12:43:35 +1000, Steven D'Aprano wrote:
>>>
>>> On this list, I daresay somebody will insist that if their computer is
>>> on one of Jupiter's moons it will keep running fine and therefore I'm
>>> wrong.
>>>
>>
>> Anyone on a moon of Jupiter would not be able to get internet access
>> (TCP/IP time-outs mean that even Mars is outside of internet range. The
>> Moon at 1.3 light seconds might manage it ) so they could not be posting
>> here ;-)
>
> Well, TCP might be problematic, but radio transmission from Jupiter
> would still be faster than RFC 1149, which in its only field test took
> an average of 5200 seconds to send round-trip pings over a distance of
> 3 miles.

And I'm sure someone could figure out a "netnews-over-UDP" system.
After all, most people just post without thinking about responses
anyway, which is exactly what UDP is great at...

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-14 Thread Ian Kelly
On Tue, Jun 14, 2016 at 5:39 AM, alister  wrote:
> On Tue, 14 Jun 2016 12:43:35 +1000, Steven D'Aprano wrote:
>>
>> On this list, I daresay somebody will insist that if their computer is
>> on one of Jupiter's moons it will keep running fine and therefore I'm
>> wrong.
>>
>
> Anyone on a moon of Jupiter would not be able to get internet access
> (TCP/IP time-outs mean that even Mars is outside of internet range. The
> Moon at 1.3 light seconds might manage it ) so they could not be posting
> here ;-)

Well, TCP might be problematic, but radio transmission from Jupiter
would still be faster than RFC 1149, which in its only field test took
an average of 5200 seconds to send round-trip pings over a distance of
3 miles.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-14 Thread alister
On Tue, 14 Jun 2016 12:43:35 +1000, Steven D'Aprano wrote:
> 
> On this list, I daresay somebody will insist that if their computer is
> on one of Jupiter's moons it will keep running fine and therefore I'm
> wrong.
> 

Anyone on a moon of Jupiter would not be able to get internet access
(TCP/IP time-outs mean that even Mars is outside of internet range. The 
Moon at 1.3 light seconds might manage it ) so they could not be posting 
here ;-)



-- 
Drink Canada Dry!  You might not succeed, but it *__is* fun trying.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-13 Thread Michael Selik
On Mon, Jun 13, 2016 at 10:46 PM Steven D'Aprano 
wrote:

> On Tue, 14 Jun 2016 09:45 am, Michael Selik wrote:
> > On Sun, Jun 12, 2016 at 10:16 PM Steven D'Aprano 
> > wrote:
> >> On Mon, 13 Jun 2016 04:44 am, Michael Selik wrote:
> >> > On Sun, Jun 12, 2016 at 6:11 AM Steven D'Aprano <
> >> > steve+comp.lang.pyt...@pearwood.info> wrote:
> >> >
> >> >> - run the for block
> >> >> - THEN unconditionally run the "else" block
> >> >>
> >> > Saying "unconditionally" is a bit misleading here. As you say, it's
> >> > conditioned on completing the loop without break/return/raise.
> >>
> >> It's also conditional on the OS not killing the Python process,
> >> conditional on the CPU not catching fire, conditional on the user not
> >> turning the power of, and conditional on the sun not exploding and
> >> disintegrating the entire earth.
> >>
> >> In the absence of any event which interferes with the normal execution
> of
> >> code by the Python VM, and in the absence of one of a very few
> >> explicit "JUMP" statements which explicitly jump out of the compound
> >> for...else statement, the else clause is unconditionally executed after
> >> the for clause.
>
> > Saying that ``raise``, ``break``, and ``return`` are "one of a very few
> > explicit JUMP statements" implies that they are obscure.
>
> What? No. How do you get that?
>

The context. That was right after a list of several (mostly) oddball
situations. In my experience, that pattern of speech is usually used to
imply that everything listed is also exceptionally strange.

There's a simple mental model, one which has the advantage of actually
> matching the implementation: for...else executes else unconditionally, ...
> If Python 3.6 introduces a GOTO command, then my mental model of
> for...else doesn't need to change.
>

That's a good explanation. The documentation says, "A break statement
executed in the first suite terminates the loop without executing the else
clause’s suite." Do you think that qualification of "without executing the
else clause" is unnecessary/redundant?

Regardless of the implementation, I think that explanation -- if break,
then skip the else-clause -- helps clarify the purpose.

https://docs.python.org/3/reference/compound_stmts.html#the-for-statement

else: # only if no break occurs
> and then I would feel guilty for lying, because that comment is not, in
> fact, correct. Returning out of the function from inside the loop will also
> avoid running the else part, as will an exception.
>

I absolve you of guilt! :-) If you had written, "guaranteed to run if no
break," then lawyers will come after you. If you had written "if and only
if" some mathematicians might complain. As you wrote it, it's actually true.

An "if and only if" logical statement has two parts: "if no break, run
else-clause" and "if break, do not run else-clause". As you say, the first
part is false. But you only made the latter claim.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-13 Thread Steven D'Aprano
On Tue, 14 Jun 2016 09:45 am, Michael Selik wrote:

> On Sun, Jun 12, 2016 at 10:16 PM Steven D'Aprano 
> wrote:
> 
>> On Mon, 13 Jun 2016 04:44 am, Michael Selik wrote:
>>
>> > On Sun, Jun 12, 2016 at 6:11 AM Steven D'Aprano <
>> > steve+comp.lang.pyt...@pearwood.info> wrote:
>> >
>> >> - run the for block
>> >> - THEN unconditionally run the "else" block
>> >>
>> >
>> > Saying "unconditionally" is a bit misleading here. As you say, it's
>> > conditioned on completing the loop without break/return/raise.
>>
>> It's also conditional on the OS not killing the Python process,
>> conditional on the CPU not catching fire, conditional on the user not
>> turning the power of, and conditional on the sun not exploding and
>> disintegrating the entire earth.
>>
>> In the absence of any event which interferes with the normal execution of
>> code by the Python VM, and in the absence of one of a very few
>> explicit "JUMP" statements which explicitly jump out of the compound
>> for...else statement, the else clause is unconditionally executed after
>> the for clause.
>>
>> Happy now?
>>
> 
> I think most folks assume that their program will not run as expected if
> the sun explodes.

On this list, I daresay somebody will insist that if their computer is on
one of Jupiter's moons it will keep running fine and therefore I'm wrong.


> Saying that ``raise``, ``break``, and ``return`` are "one of a very few
> explicit JUMP statements" implies that they are obscure. 

What? No. How do you get that?

If I tell you that Python has only two loop constructs, for and while, would
that imply that they are rare and unusual? (Three if you count
comprehensions as distinct from the for statement.)

Python has only two conditional branches: if...elif..else, and the ternary
if operator. Does that make them obscure?

raise, break and return are all explicit JUMPs: they transfer execution to
some place other than the next executable line. There are others, including
continue, but they don't transfer execution past the for loop, so don't
matter in this context. None of this implies that they are obscure. I'm
sorry if you've never thought of a return or break as a JUMP before, but
that's what they are.


> Listing them in 
> addition to the sun exploding suggests that you think they are similarly
> unlikely and should be ignored as too bizarre to consider.

No. The sun exploding was me gently mocking you for your comment disputing
the "unconditional" part. Yes, you are technically right that technically
the "else" block will only run if no "break" is reached, and no "return" is
reached, no exception is raised, also that os._exit or os.abort aren't
called, the CPU doesn't catch fire, and the world isn't destroyed.

If we try to enumerate all the things which could prevent the "else" block
from running, we'll be here for decades. But, and this is the point that
everyone seems to have missed, * every single one of those things* is
completely independent of the for...else statement.

*Including* the presence or absence of a "break".

If you want to understand how Python statements work, you should understand
them in isolation (as much as possible), which then allows you to
extrapolate their behaviour in combination with other statements. Most
lines of Python code are understandable in isolation, or at least close to
isolation. You can get *very close* to a full understanding of Python by
just reading one line at a time (with perhaps a bit of short term memory to
remember if you are compiling a function, building a class, etc).

E.g. you don't need to understand for loops to understand if...else.

And vice versa: for...else has a well-defined meaning and operates in a
simple fashion in isolation of other language features. Its not compulsory
to put a "return" statement inside your for loop. Nor is it compulsory to
put a "raise" inside it. And "break" is not compulsory either.

If you think of for...else as being (in some sense) glued to break, then
what are you going to make of code with for...else and no break? That's
legal Python code, and somebody will write it, even if only by accident.

If you think of for...else as being glued to an if inside the for block,
then what are you going to make of code where the if already has an else?
Or code that unconditionally breaks inside the loop? Again, that's legal
code, even if useless. If you think that the for...else has to match an if
inside the loop, you'll have to invent special rules for when there is no
if, or ten of them, or they all are already matched with their own elses.

If you start thinking of it as code which is run conditionally "only if no
break was executed", that leads to people thinking of it in terms of some
sort of hidden flag that Python keeps to tell whether or not a break was
seen. A month or two ago, we had somebody, mislead by that mental model,
asking whether Python should expose that flag so he could write code
something like:

for x in seq:
   

Re: for / while else doesn't make sense

2016-06-13 Thread Michael Selik
On Sun, Jun 12, 2016 at 10:16 PM Steven D'Aprano 
wrote:

> On Mon, 13 Jun 2016 04:44 am, Michael Selik wrote:
>
> > On Sun, Jun 12, 2016 at 6:11 AM Steven D'Aprano <
> > steve+comp.lang.pyt...@pearwood.info> wrote:
> >
> >> - run the for block
> >> - THEN unconditionally run the "else" block
> >>
> >
> > Saying "unconditionally" is a bit misleading here. As you say, it's
> > conditioned on completing the loop without break/return/raise.
>
> It's also conditional on the OS not killing the Python process, conditional
> on the CPU not catching fire, conditional on the user not turning the power
> of, and conditional on the sun not exploding and disintegrating the entire
> earth.
>
> In the absence of any event which interferes with the normal execution of
> code by the Python VM, and in the absence of one of a very few
> explicit "JUMP" statements which explicitly jump out of the compound
> for...else statement, the else clause is unconditionally executed after the
> for clause.
>
> Happy now?
>

I think most folks assume that their program will not run as expected if
the sun explodes.

Saying that ``raise``, ``break``, and ``return`` are "one of a very few
explicit JUMP statements" implies that they are obscure. Listing them in
addition to the sun exploding suggests that you think they are similarly
unlikely and should be ignored as too bizarre to consider.

In contrast, I think raise, break, and return are quite common. Further, I
think you do too, despite what you are trying to imply. Maybe I read the
tone wrong. It's tough sometimes to hear someone's tone of voice in email.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-12 Thread Rustom Mody
On Monday, June 13, 2016 at 7:42:25 AM UTC+5:30, Steven D'Aprano wrote:
> On Mon, 13 Jun 2016 04:44 am, Michael Selik wrote:
> 
> > On Sun, Jun 12, 2016 at 6:11 AM Steven D'Aprano  wrote:
> > 
> >> - run the for block
> >> - THEN unconditionally run the "else" block
> >>
> > 
> > Saying "unconditionally" is a bit misleading here. As you say, it's
> > conditioned on completing the loop without break/return/raise.
> 
> It's also conditional on the OS not killing the Python process, conditional
> on the CPU not catching fire, conditional on the user not turning the power
> of, and conditional on the sun not exploding and disintegrating the entire
> earth.
> 
> In the absence of any event which interferes with the normal execution of
> code by the Python VM, and in the absence of one of a very few
> explicit "JUMP" statements which explicitly jump out of the compound
> for...else statement, the else clause is unconditionally executed after the
> for clause.
> 
> Happy now?

Wholesale business of strawmen doing brisk business?

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-12 Thread Steven D'Aprano
On Mon, 13 Jun 2016 04:44 am, Michael Selik wrote:

> On Sun, Jun 12, 2016 at 6:11 AM Steven D'Aprano <
> steve+comp.lang.pyt...@pearwood.info> wrote:
> 
>> - run the for block
>> - THEN unconditionally run the "else" block
>>
> 
> Saying "unconditionally" is a bit misleading here. As you say, it's
> conditioned on completing the loop without break/return/raise.

It's also conditional on the OS not killing the Python process, conditional
on the CPU not catching fire, conditional on the user not turning the power
of, and conditional on the sun not exploding and disintegrating the entire
earth.

In the absence of any event which interferes with the normal execution of
code by the Python VM, and in the absence of one of a very few
explicit "JUMP" statements which explicitly jump out of the compound
for...else statement, the else clause is unconditionally executed after the
for clause.

Happy now?



-- 
Steven

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-12 Thread Michael Selik
On Sun, Jun 12, 2016 at 6:11 AM Steven D'Aprano <
steve+comp.lang.pyt...@pearwood.info> wrote:

> - run the for block
> - THEN unconditionally run the "else" block
>

Saying "unconditionally" is a bit misleading here. As you say, it's
conditioned on completing the loop without break/return/raise.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-12 Thread Steven D'Aprano
On Sunday 12 June 2016 17:01, pavlovevide...@gmail.com wrote:

> On Thursday, May 19, 2016 at 9:43:56 AM UTC-7, Herkermer Sherwood wrote:
>> Most keywords in Python make linguistic sense, but using "else" in for and
>> while structures is kludgy and misleading. I am under the assumption that
>> this was just utilizing an already existing keyword. Adding another like
>> "andthen" would not be good.
[...]
>> I think perhaps "finally" should be added to for and while to do the same
>> thing as "else". What do you think?
> 
> I agree it's not the clearest name, but it does behave consistent with
> if...else.  

Er, not really.

if condition:
   print "A"
else:
   print "B"


Exactly one of "A" or "B", but NEVER both, will be printed.

for item in sequence:
print "A"
else:
print "B"

Normally we would expect that both "A" and "B" will be printed. There will be a 
variable number of "A"s printed, zero or more, and exactly one "B", but the 
point is that in general BOTH will run, which is the opposite of if...else.

The actual semantics are:

- run the for block
- THEN unconditionally run the "else" block

The only way to skip running the "else" block is to jump out of the entire 
for...else statement, using `return`, `raise` or `break`.



> Here's how I make sense of for...else.  Consider this loop:
> 
> for item in seq:
> if pred(item):
> use(item)
> break
> else:
> not_found()

That's the major intended use of "else", but note that it is NOT paired with 
the `if`. You can have:

def func():
for item in seq:
if pred(item):
use(item)
if condition:
return something
else:
different_use(item)
continue
do_more()
break
else:
not_found()


or any of an infinite number of other combinations. You can't really understand 
for...else correctly if you think of the "else" being partnered with an "if" 
inside the loop. What if there is no "if"? Or ten of them? Of if they all 
already have "else" clauses?



> This particular loop functions as a kind of a dynamic if...elif...else
> statement.  You can see that if you unroll the loop:
> 
> 
> if pred(seq[0]):
> use(seq[0])
> elif pred(seq[1]):
> use(seq[1])
> elif pred(seq[2]):
> use(seq[2])
> else:
> not_found()

They are only equivalent because of the "break". Take the break out, unroll the 
loop, and what you have is:

if pred(seq[0]):
use(seq[0])
if pred(seq[1]):
use(seq[1])
if pred(seq[2]):
use(seq[2])
not_found()

Put the break back in, and you have:


if pred(seq[0]):
use(seq[0])
GOTO foo  # not actual Python syntax, but see below
if pred(seq[1]):
use(seq[1])
GOTO foo
if pred(seq[2]):
use(seq[2])
GOTO foo
not_found()
label: foo

Admittedly GOTO isn't Python syntax, but this actually is the way that the 
bytecode is done: the else clause is executed unconditionally, and a break 
jumps past the else clause.

In Python 3.3, "break" is compiled to a JUMP_ABSOLUTE bytecode. You can see 
this for yourself using the dis module, e.g.:


import dis
code = compile("""
for i in seq:
this()
if condition:
break
that()
else:
another()
print("done")
""", "", "exec")
dis.dis(code)



> You will note that the else block is the same in both the rolled and unrolled
> versions, and has exactly the same meaning and usage.

But not in the general case. Only certain specific uses of for...else behave as 
you suggest.


> As for a more appropriate keyword, I don't like the examples I saw skimming
> this thread; neither "finally" nor "then" communicates that the block would
> executed conditionally.

The block isn't executed conditionally. The block is executed UNCONDITIONALLY. 
The only way to avoid executing the "else" block is to jump past it, using a 
return, raise of break.


> If you want my opinion, you might as well use something explicit and
> unambiguous, like "if_exhausted", for the block; 

But that is exactly what the else clause is NOT. That is an incredibly common 
mistake that people make, thinking that the "else" clause executes when the 
sequence is exhausted. At first, it *seems* to be the case:

py> seq = []
py> for item in seq:
... print("not empty!")
... else:
... print("empty")
... 
empty

but that wrong. 

py> seq = [1, 2]
py> for item in seq:
... print("not empty!")
... else:
... print("empty")
... 
not empty!
not empty!
empty
py> print(seq)  # not exhausted
[1, 2]


The else clause has nothing to do with whether or not the for block runs, or 
whether it is empty, or whether the iterable is exhausted after the loop is 
complete. The else clause simple runs directly after the for block, unless you 
skip it by using the Python equivalent of a GOTO.


> If you really want my opinion, it probably shouldn't be in the language at
> all, even though I happily use it from time to time, and my code is better
> for it.

o_O



> But it's not 

Re: for / while else doesn't make sense

2016-06-12 Thread pavlovevidence
On Thursday, May 19, 2016 at 9:43:56 AM UTC-7, Herkermer Sherwood wrote:
> Most keywords in Python make linguistic sense, but using "else" in for and
> while structures is kludgy and misleading. I am under the assumption that
> this was just utilizing an already existing keyword. Adding another like
> "andthen" would not be good.
> 
> But there is already a reserved keyword that would work great here.
> "finally". It is already a known keyword used in try blocks, but would work
> perfectly here. Best of all, it would actually make sense.
> 
> Unfortunately, it wouldn't follow the semantics of try/except/else/finally.
> 
> Is it better to follow the semantics used elsewhere in the language, or
> have the language itself make sense semantically?
> 
> I think perhaps "finally" should be added to for and while to do the same
> thing as "else". What do you think?

I agree it's not the clearest name, but it does behave consistent with 
if...else.  "finally" has a strong connotation for code that is guaranteed to 
be executed on the way out regardless of an exception, so it wouldn't be 
appropriate for this even if it were clearer (though it isn't IMO).

Here's how I make sense of for...else.  Consider this loop:

for item in seq:
if pred(item):
use(item)
break
else:
not_found()


This particular loop functions as a kind of a dynamic if...elif...else 
statement.  You can see that if you unroll the loop:


if pred(seq[0]):
use(seq[0])
elif pred(seq[1]):
use(seq[1])
elif pred(seq[2]):
use(seq[2])
else:
not_found()


You will note that the else block is the same in both the rolled and unrolled 
versions, and has exactly the same meaning and usage.

As for a more appropriate keyword, I don't like the examples I saw skimming 
this thread; neither "finally" nor "then" communicates that the block would 
executed conditionally.

If you want my opinion, you might as well use something explicit and 
unambiguous, like "if_exhausted", for the block; and you might as well add an 
"if_broken" block while you're at it (though it's not quite as useful since in 
most cases you could just put the code before the break).  Since it's only 
occasionally useful, there's no real need to make the keyword short.

If you really want my opinion, it probably shouldn't be in the language at all, 
even though I happily use it from time to time, and my code is better for it.  
But it's not useful enough that the language would really suffer without it, 
and it would save some users from something that can be quite confusing.


-- 
Carl Banks
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-10 Thread Gregory Ewing

Steven D'Aprano wrote:

I have a 2000 inch monitor, and by using a narrow proportional
font set to 5pt, I can display the entire Python standard library including
tests on screen at once. Then it's just a matter of using my trusty 4"
reflecting telescope to zoom in on any part of the screen I like.


You may think you're joking, but this sounds remarkably
similar to microfiche...

http://www.wisegeek.org/what-is-microfiche.htm

--
Greg
--
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-10 Thread Marko Rauhamaa
Ian Kelly :

> On Jun 10, 2016 6:37 AM, "Marko Rauhamaa"  wrote:
>> If your display can show 1,500 lines at once, that's your limit. Mine
>> shows 70.
>
> I disagree on that point. For a typical-size display, it's a
> reasonable guideline.

The point I'm making is that if I'm accusing you for writing functions
that are too long (they don't fit on my editor window), you can counter
that they fit perfectly well on yours.

No-one has 1,500-line editor windows, I suppose. However, screen sizes
have been going up and some people prefer to turn their screens into
portrait mode (tried it, made my neck hurt). Years back, I had 24 lines
on the screen. As screen sizes have gone up, I've allowed for longer
functions as well. Now I'm at 70. Of course, most functions tend to be
much shorter.


Marko
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-10 Thread Steven D'Aprano
On Sat, 11 Jun 2016 12:00 am, Ian Kelly wrote:

> On Jun 10, 2016 6:37 AM, "Marko Rauhamaa"  wrote:

>> If your display can show 1,500 lines at once, that's your limit. Mine
>> shows 70.
> 
> I disagree on that point. For a typical-size display, it's a reasonable
> guideline. But just because your 1500-line function fits in a single
> screen does not make it readable. 

I disagree. I have a 2000 inch monitor, and by using a narrow proportional
font set to 5pt, I can display the entire Python standard library including
tests on screen at once. Then it's just a matter of using my trusty 4"
reflecting telescope to zoom in on any part of the screen I like. This is
much more convenient than opening a single file at a time, or using a
tabbed interface, it is much more efficient to just swivel the telescope
and jump to the correct part of the code, and it rarely takes me more than
ten or fifteen minutes to find it.

And I can read the code in perfect clarity, provided I don't nudge or touch
the telescope in any way, or breathe too hard. Apart from "rn" which tends
to look like an "m", and its a bit hard to tell the difference between 0
and 0 or 1 I and l, or S and 5, and to be honest periods and commas are
completely invisible, but that's a small price to pay for the extra
efficiency of having all 641 thousand lines of code on screen all at once.



-- 
Steven

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-10 Thread Ian Kelly
On Jun 10, 2016 6:37 AM, "Marko Rauhamaa"  wrote:
>
> alister :
>
> > Or more simply a hard fixed RULE (MUST be less than X lines) is Bad.
>
> It's not X lines, it's "you must see the whole function at once."
>
> If your display can show 1,500 lines at once, that's your limit. Mine
> shows 70.

I disagree on that point. For a typical-size display, it's a reasonable
guideline. But just because your 1500-line function fits in a single screen
does not make it readable. In particular, if the function is deeply nested,
then it quickly becomes difficult to discern which code aligns with which.

A similar principle informs us that 70-100 columns is a reasonable line
length limit for readability even if your display can fit much more.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-10 Thread alister
On Fri, 10 Jun 2016 15:31:11 +0300, Marko Rauhamaa wrote:

> alister :
> 
>> Or more simply a hard fixed RULE (MUST be less than X lines) is Bad.
> 
> It's not X lines, it's "you must see the whole function at once."
> 
> If your display can show 1,500 lines at once, that's your limit. Mine
> shows 70.
> 
>> a flexible GUIDELINE on the other hand is reasonable.
> 
> There are rare exceptions to every rule.
> 
>> after all an efficient function could be be X=1 lines, abriatrily
>> spliting this could make the final function less readable & possibly
>> even longer in total.
> 
> Splitting functions requires taste and skill but, when done properly,
> guarantees easier reading and higher quality. As you refactor your
> function, you notice clumsy and questionable idioms and end up tidying
> the logic up in the process.
> 
> 
> Marko

you think I am arguing?
i am not (excpet possibly on symantics)

your "you must see the whole function on one page" stipulation should be 
treated as guidance & not a rule
preferably it should read "You 'SHOULD' be able to see the whole function 
on one page.

and as you quite rightly state there are always exceptions as enshrined 
in the zen

"Practicality beats Purity"



-- 
Must I hold a candle to my shames?
-- William Shakespeare, "The Merchant of Venice"
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-10 Thread Marko Rauhamaa
alister :

> Or more simply a hard fixed RULE (MUST be less than X lines) is Bad.

It's not X lines, it's "you must see the whole function at once."

If your display can show 1,500 lines at once, that's your limit. Mine
shows 70.

> a flexible GUIDELINE on the other hand is reasonable.

There are rare exceptions to every rule.

> after all an efficient function could be be X=1 lines, abriatrily
> spliting this could make the final function less readable & possibly
> even longer in total.

Splitting functions requires taste and skill but, when done properly,
guarantees easier reading and higher quality. As you refactor your
function, you notice clumsy and questionable idioms and end up tidying
the logic up in the process.


Marko
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-10 Thread alister
On Thu, 09 Jun 2016 18:19:23 +1000, Steven D'Aprano wrote:

> On Thursday 09 June 2016 10:34, Lawrence D’Oliveiro wrote:
> 
>> In my undergraduate Comp Sci classes, we used to discuss arbitrary
>> rules like limiting functions to n lines. With real-world experience,
>> it soon became clear that such rules were a waste of time. A function
>> should be just as big as it needs to be, no more, no less. The same
>> with a class, or a module. Or whatever other constructs your language
>> may have.
> 
> The opposite of "arbitrary limits" is not "no limits".
> 
> An arbitrary limit like "500 lines is the maximum size a function may
> be" is clearly arbitrary and not very helpful. (Also too high.)
> 
> Better is to understand that there is no hard cut-off between
> "acceptable" and "too long", but we can still judge that all else being
> equal, long functions are worse than short functions.
> 
> The real problem is complexity of functions. The more complex they are,
> the harder they are to write correctly, and the harder to maintain, and
> the more likely that they have bugs.
> 
> The length of a function is a very crude measure of complexity, but it
> *is* a measure of complexity, and people are right to look at long
> functions as a code smell and a sign that the function probably does too
> much, or is badly written,
> or that it could do with some refactoring to simplify it. Not in *every*
> case, but I've never yet seen a long (> 200 lines) function that wasn't
> improved by refactoring or splitting.



Or more simply a hard fixed RULE (MUST be less than X lines) is Bad.

a flexible GUIDELINE on the other hand is reasonable.

after all an efficient function could be be X=1 lines, abriatrily spliting 
this could make the final function less readable & possibly even longer 
in total.
 


-- 
Puns are little "plays on words" that a certain breed of person loves to
spring on you and then look at you in a certain self-satisfied way to
indicate that he thinks that you must think that he is by far the 
cleverest
person on Earth now that Benjamin Franklin is dead, when in fact what you
are thinking is that if this person ever ends up in a lifeboat, the other
passengers will hurl him overboard by the end of the first day even if 
they
have plenty of food and water.
-- Dave Barry, "Why Humor is Funny"
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-09 Thread Grady Martin

On 2016年05月19日 11時02分, Ian Kelly wrote:

"else" makes sense from a certain point of view, but I think that
logic may not be communicated well. At the start of each loop
iteration, the loop construct makes a test for whether the loop should
continue or not. If that test ever fails (i.e. if the condition of the
while loop is false), the else block is executed instead.


Thank you for the concise explanation.  (I enjoy new tools.)

As alluded to elsewhere, this distinction makes sense when loop breaking is 
involved.
--
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-09 Thread Steven D'Aprano
On Thursday 09 June 2016 10:34, Lawrence D’Oliveiro wrote:

> In my undergraduate Comp Sci classes, we used to discuss arbitrary rules like
> limiting functions to n lines. With real-world experience, it soon became
> clear that such rules were a waste of time. A function should be just as big
> as it needs to be, no more, no less. The same with a class, or a module. Or
> whatever other constructs your language may have.

The opposite of "arbitrary limits" is not "no limits".

An arbitrary limit like "500 lines is the maximum size a function may be" is 
clearly arbitrary and not very helpful. (Also too high.)

Better is to understand that there is no hard cut-off between "acceptable" and 
"too long", but we can still judge that all else being equal, long functions 
are worse than short functions.

The real problem is complexity of functions. The more complex they are, the 
harder they are to write correctly, and the harder to maintain, and the more 
likely that they have bugs.

The length of a function is a very crude measure of complexity, but it *is* a 
measure of complexity, and people are right to look at long functions as a code 
smell and a sign that the function probably does too much, or is badly written, 
or that it could do with some refactoring to simplify it. Not in *every* case, 
but I've never yet seen a long (> 200 lines) function that wasn't improved by 
refactoring or splitting.



-- 
Steve

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-08 Thread Lawrence D’Oliveiro
On Wednesday, June 8, 2016 at 5:27:41 PM UTC+12, Marko Rauhamaa wrote:

> Someone mentioned you had a 500-line function.

In my undergraduate Comp Sci classes, we used to discuss arbitrary rules like 
limiting functions to n lines. With real-world experience, it soon became clear 
that such rules were a waste of time. A function should be just as big as it 
needs to be, no more, no less. The same with a class, or a module. Or whatever 
other constructs your language may have.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-07 Thread Marko Rauhamaa
Lawrence D’Oliveiro :

> On Wednesday, June 8, 2016 at 10:07:05 AM UTC+12, Marko Rauhamaa wrote:
>> Lawrence D’Oliveiro:
>
>>> While elsewhere, you were criticizing my code for already being so
>>> terribly large...
>> 
>> Code can be large, only no function should be longer than ~70 lines
>> or wider than 79 columns. If your function grows above that limit,
>> you should refactor it and break it into multiple subroutines.
>
> It already had lots of subfunctions, in case you hadn’t noticed...

I didn't take a look at your code. Someone mentioned you had a 500-line
function.


Marko
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-07 Thread Marko Rauhamaa
Lawrence D’Oliveiro :

> On Tuesday, June 7, 2016 at 8:00:31 PM UTC+12, Marko Rauhamaa wrote:
>> I, too, insist that every function/method must be visible at once in the
>> editor window.
>
> From subprocess.py in the Python 3.5 distribution:
> [...]
> Is that “visible at once” in your editor window?

At home, no; at work, yes.

Anyway, I didn't write that piece of code so my insisting doesn't affect
it one way or another.


Marko
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-07 Thread Ethan Furman

On 06/01/2016 04:39 PM, Lawrence D’Oliveiro wrote:

[multiple apparent trolls redacted]

This thread is dead.  Please stop beating it.

--
~Ethan~
--
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-07 Thread Ned Batchelder
On Tuesday, June 7, 2016 at 9:29:59 PM UTC-4, Lawrence D’Oliveiro wrote:
> On Wednesday, June 8, 2016 at 12:32:01 PM UTC+12, Ned Batchelder wrote:
> 
> > Lawrence writes code in an unusual style...
> 
> “Unusual” I can deal with. But when some people react with outrage, then it 
> becomes clear they view my code as a personal attack.

This is why we should drop it.  It doesn't seem like people are trying to
understand each other, just score points and prove each other wrong. That
isn't going to lead anywhere good.

--Ned.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-07 Thread Lawrence D’Oliveiro
On Wednesday, June 8, 2016 at 12:32:01 PM UTC+12, Ned Batchelder wrote:
> On Tuesday, June 7, 2016 at 6:07:23 PM UTC-4, Lawrence D’Oliveiro wrote:
> > On Tuesday, June 7, 2016 at 8:00:31 PM UTC+12, Marko Rauhamaa wrote:
> > > I understand you are hurt when your code is criticized bluntly. However,
> > > you *did* stick your head out.
> > 
> > Don’t worry, I am not the thin-skinned type.
> > 
> > > I, too, insist that every function/method must be visible at once in the
> > > editor window.
> > 
> > From subprocess.py in the Python 3.5 distribution:
> > 
> > if _mswindows:
> > #
> > # Windows methods
> > #
> > def _get_handles(self, stdin, stdout, stderr):
> > """Construct and return tuple with IO objects:
> > 
> > ... 8< snip 8< ...
> > 
> > errwrite = self._make_inheritable(errwrite)
> > 
> > return (p2cread, p2cwrite,
> > c2pread, c2pwrite,
> > errread, errwrite)
> > 
> > Is that “visible at once” in your editor window?
> 
> Lawrence, Marko didn't write that function. Marko didn't claim that all
> functions fit in a window, just that he wants his to.

Given that he was (presumably) commenting on my code, naturally I understood 
his statement to apply to code that he had not written.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-07 Thread Lawrence D’Oliveiro
On Wednesday, June 8, 2016 at 12:32:01 PM UTC+12, Ned Batchelder wrote:

> Lawrence writes code in an unusual style...

“Unusual” I can deal with. But when some people react with outrage, then it 
becomes clear they view my code as a personal attack.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-07 Thread Ned Batchelder
On Tuesday, June 7, 2016 at 6:07:23 PM UTC-4, Lawrence D’Oliveiro wrote:
> On Tuesday, June 7, 2016 at 8:00:31 PM UTC+12, Marko Rauhamaa wrote:
> > I understand you are hurt when your code is criticized bluntly. However,
> > you *did* stick your head out.
> 
> Don’t worry, I am not the thin-skinned type.
> 
> > I, too, insist that every function/method must be visible at once in the
> > editor window.
> 
> From subprocess.py in the Python 3.5 distribution:
> 
> if _mswindows:
> #
> # Windows methods
> #
> def _get_handles(self, stdin, stdout, stderr):
> """Construct and return tuple with IO objects:
> 
> ... 8< snip 8< ...
> 
> errwrite = self._make_inheritable(errwrite)
> 
> return (p2cread, p2cwrite,
> c2pread, c2pwrite,
> errread, errwrite)
> 
> Is that “visible at once” in your editor window?

Lawrence, Marko didn't write that function. Marko didn't claim that all
functions fit in a window, just that he wants his to.

Lawrence writes code in an unusual style, not a style I would write in,
but we aren't going to be able to change his mind.  It seems like this 
discussion has gone beyond the productive stage.  We aren't going to 
come to consensus on coding style.

--Ned.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-07 Thread Ian Kelly
On Tue, Jun 7, 2016 at 3:58 PM, Lawrence D’Oliveiro
 wrote:
> On Tuesday, June 7, 2016 at 11:53:46 PM UTC+12, Ian wrote:
>> On Tue, Jun 7, 2016 at 1:52 AM, Lawrence D’Oliveiro wrote:
>
>>> Wow, that’s only twice the length of the code you’re replacing. Well done.
>>
>> Huh? The example that you posted was 17 lines, excluding comments. My
>> replacement code is 17 lines, excluding comments. Where are you
>> getting "twice the length" from?
>
> Maybe not twice. But your code for dealing with the include stack was 16 
> lines, as opposed to 13 in mine.

Well, I don't know how you're counting that. All the code for dealing
with the include stack is in the generate_lines function, which is 10
lines long. The remaining code is then simpler for not having to deal
with it. In the original version, I can't identify which lines are
"dealing with the include stack" because they're so intertwined. For
example, all the sporadic code checking for line == None or line !=
None only need to exist because of the include stack.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-07 Thread Lawrence D’Oliveiro
On Wednesday, June 8, 2016 at 10:07:05 AM UTC+12, Marko Rauhamaa wrote:
> Lawrence D’Oliveiro:

>> While elsewhere, you were criticizing my code for already being so
>> terribly large...
> 
> Code can be large, only no function should be longer than ~70 lines or
> wider than 79 columns. If your function grows above that limit, you
> should refactor it and break it into multiple subroutines.

It already had lots of subfunctions, in case you hadn’t noticed...
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-07 Thread Lawrence D’Oliveiro
On Tuesday, June 7, 2016 at 8:00:31 PM UTC+12, Marko Rauhamaa wrote:
> I understand you are hurt when your code is criticized bluntly. However,
> you *did* stick your head out.

Don’t worry, I am not the thin-skinned type.

> I, too, insist that every function/method must be visible at once in the
> editor window.

From subprocess.py in the Python 3.5 distribution:

if _mswindows:
#
# Windows methods
#
def _get_handles(self, stdin, stdout, stderr):
"""Construct and return tuple with IO objects:
p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite
"""
if stdin is None and stdout is None and stderr is None:
return (-1, -1, -1, -1, -1, -1)

p2cread, p2cwrite = -1, -1
c2pread, c2pwrite = -1, -1
errread, errwrite = -1, -1

if stdin is None:
p2cread = _winapi.GetStdHandle(_winapi.STD_INPUT_HANDLE)
if p2cread is None:
p2cread, _ = _winapi.CreatePipe(None, 0)
p2cread = Handle(p2cread)
_winapi.CloseHandle(_)
elif stdin == PIPE:
p2cread, p2cwrite = _winapi.CreatePipe(None, 0)
p2cread, p2cwrite = Handle(p2cread), Handle(p2cwrite)
elif stdin == DEVNULL:
p2cread = msvcrt.get_osfhandle(self._get_devnull())
elif isinstance(stdin, int):
p2cread = msvcrt.get_osfhandle(stdin)
else:
# Assuming file-like object
p2cread = msvcrt.get_osfhandle(stdin.fileno())
p2cread = self._make_inheritable(p2cread)

if stdout is None:
c2pwrite = _winapi.GetStdHandle(_winapi.STD_OUTPUT_HANDLE)
if c2pwrite is None:
_, c2pwrite = _winapi.CreatePipe(None, 0)
c2pwrite = Handle(c2pwrite)
_winapi.CloseHandle(_)
elif stdout == PIPE:
c2pread, c2pwrite = _winapi.CreatePipe(None, 0)
c2pread, c2pwrite = Handle(c2pread), Handle(c2pwrite)
elif stdout == DEVNULL:
c2pwrite = msvcrt.get_osfhandle(self._get_devnull())
elif isinstance(stdout, int):
c2pwrite = msvcrt.get_osfhandle(stdout)
else:
# Assuming file-like object
c2pwrite = msvcrt.get_osfhandle(stdout.fileno())
c2pwrite = self._make_inheritable(c2pwrite)

if stderr is None:
errwrite = _winapi.GetStdHandle(_winapi.STD_ERROR_HANDLE)
if errwrite is None:
_, errwrite = _winapi.CreatePipe(None, 0)
errwrite = Handle(errwrite)
_winapi.CloseHandle(_)
elif stderr == PIPE:
errread, errwrite = _winapi.CreatePipe(None, 0)
errread, errwrite = Handle(errread), Handle(errwrite)
elif stderr == STDOUT:
errwrite = c2pwrite
elif stderr == DEVNULL:
errwrite = msvcrt.get_osfhandle(self._get_devnull())
elif isinstance(stderr, int):
errwrite = msvcrt.get_osfhandle(stderr)
else:
# Assuming file-like object
errwrite = msvcrt.get_osfhandle(stderr.fileno())
errwrite = self._make_inheritable(errwrite)

return (p2cread, p2cwrite,
c2pread, c2pwrite,
errread, errwrite)

Is that “visible at once” in your editor window?
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-07 Thread Marko Rauhamaa
Lawrence D’Oliveiro :
> While elsewhere, you were criticizing my code for already being so
> terribly large...

Code can be large, only no function should be longer than ~70 lines or
wider than 79 columns. If your function grows above that limit, you
should refactor it and break it into multiple subroutines.


Marko
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-07 Thread Lawrence D’Oliveiro
On Tuesday, June 7, 2016 at 11:53:46 PM UTC+12, Ian wrote:
> On Tue, Jun 7, 2016 at 1:52 AM, Lawrence D’Oliveiro wrote:

>> Wow, that’s only twice the length of the code you’re replacing. Well done.
> 
> Huh? The example that you posted was 17 lines, excluding comments. My
> replacement code is 17 lines, excluding comments. Where are you
> getting "twice the length" from?

Maybe not twice. But your code for dealing with the include stack was 16 lines, 
as opposed to 13 in mine.

While elsewhere, you were criticizing my code for already being so terribly 
large...
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-07 Thread Lawrence D’Oliveiro
On Wednesday, June 8, 2016 at 12:28:02 AM UTC+12, Dan Sommers wrote:
> I notice plenty of break statements scattered throughout your loop
> bodies.  Mixing the loop's exit conditions in with the logic is equally
> unstructured.

Is this the old “structured-programming-is-mathematically-equivalent-to-gotos” 
red herring again?
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-07 Thread Dan Sommers
On Tue, 07 Jun 2016 00:53:31 -0700, Lawrence D’Oliveiro wrote:

> On Tuesday, June 7, 2016 at 3:34:39 PM UTC+12, Dan Sommers wrote:
> 
>> I used to write a lot of assembly code, for a lot of different CPUs, and
>> they all had a common, versatile looping form which could be arranged in
>> different ways to suit the problem at hand.  On most chips, it was (and
>> still is) called JMP.  The trouble began with multiple conditional
>> branching, call stack maintenance, and those other higher level
>> abstractions that made my assembly code so hard to follow.
> 
> You’ll notice I don’t use gotos in my code.

I notice plenty of break statements scattered throughout your loop
bodies.  Mixing the loop's exit conditions in with the logic is equally
unstructured.

> Next red-herring example, please...

I didn't say anything about a red-herring.  Please stick to the topic at
hand.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-07 Thread Ian Kelly
On Tue, Jun 7, 2016 at 1:52 AM, Lawrence D’Oliveiro
 wrote:
> Wow, that’s only twice the length of the code you’re replacing. Well done.

Huh? The example that you posted was 17 lines, excluding comments. My
replacement code is 17 lines, excluding comments. Where are you
getting "twice the length" from?
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-07 Thread Steven D'Aprano
On Tuesday 07 June 2016 17:52, Lawrence D’Oliveiro wrote:

> On Tuesday, June 7, 2016 at 4:36:37 PM UTC+12, Ian wrote:
>> A 500-line function? Yikes, what an eyesore. When you have to include
>> #end comments in order to visually match things up, that should be a
>> smell that your code is excessively complex.
> 
> Feel free to come up with a simpler version.

If I could work out what your convoluted version is supposed to do, I might 
give it a try.

[...]

>> def generate_lines():
>> nonlocal input_line
[snip code]

> Wow, that’s only twice the length of the code you’re replacing. Well done.

I count 18 lines in your version using while loops, excluding comments, but 
including placeholder ... lines, compared to 17 lines in Ian's version. How do 
you get "twice the length"?

Ian's version is also much simpler: there are no breaks and no variables being 
assigned to None so you can detect the end of the loop, and only three `if`s 
instead of six in your version. That makes Ian's objectively less complex than 
your example, assuming it does the same thing. (Although I'm a bit dubious 
about the use of nonlocal.)



-- 
Steve

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-07 Thread Marko Rauhamaa
Lawrence D’Oliveiro :

> On Tuesday, June 7, 2016 at 4:36:37 PM UTC+12, Ian wrote:
>> A 500-line function? Yikes, what an eyesore. When you have to include
>> #end comments in order to visually match things up, that should be a
>> smell that your code is excessively complex.
>
> [...]
>
> Wow, that’s only twice the length of the code you’re replacing. Well
> done.

I understand you are hurt when your code is criticized bluntly. However,
you *did* stick your head out.

I, too, insist that every function/method must be visible at once in the
editor window.


Marko
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-07 Thread Lawrence D’Oliveiro
On Tuesday, June 7, 2016 at 3:34:39 PM UTC+12, Dan Sommers wrote:

> I used to write a lot of assembly code, for a lot of different CPUs, and
> they all had a common, versatile looping form which could be arranged in
> different ways to suit the problem at hand.  On most chips, it was (and
> still is) called JMP.  The trouble began with multiple conditional
> branching, call stack maintenance, and those other higher level
> abstractions that made my assembly code so hard to follow.

You’ll notice I don’t use gotos in my code.

Next red-herring example, please...
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-07 Thread Lawrence D’Oliveiro
On Tuesday, June 7, 2016 at 4:36:37 PM UTC+12, Ian wrote:
> A 500-line function? Yikes, what an eyesore. When you have to include
> #end comments in order to visually match things up, that should be a
> smell that your code is excessively complex.

Feel free to come up with a simpler version.

> def generate_lines():
> nonlocal input_line
> while True:
> try:
> # Note input_line appears to be an iterator, not a string
> # as suggested by the name.
> yield next(input_line)
> except StopIteration:
> if include_stack:
> input_line = include_stack.pop()
> else:
> return
> 
> for line in generate_lines():
> if not include_stack:
> linenr += 1
> if ... line contains something special ...:
> ... process special line ...
> else:
> ... process regular line ...

Wow, that’s only twice the length of the code you’re replacing. Well done.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-06 Thread Ian Kelly
On Mon, Jun 6, 2016 at 6:51 PM, Lawrence D’Oliveiro
 wrote:
> On Sunday, June 5, 2016 at 11:43:20 PM UTC+12, Marko Rauhamaa wrote:
>> I often experiment with different loop constructs to find the one most
>> pleasing to the eye. Working directly off iterators is quite rare but a
>> while-vs-for consideration is frequent. Also, should the stepping part
>> be in the beginning, middle or end of the loop body?
>
> It is nice to have a common, versatile looping form which can be arranged in 
> different ways to suit the problem at hand. That’s why I like the C-style 
> for-statement.
>
> Here’s another example 
> , for the 
> consideration of those who don’t seem too familiar with looping:

A 500-line function? Yikes, what an eyesore. When you have to include
#end comments in order to visually match things up, that should be a
smell that your code is excessively complex. It took me a lot of
scrolling up and down just to figure out what the scopes of the
variables were.

> while True :
> while True :
> line = next(input_line, None)
> if line != None :
> if len(include_stack) == 0 :
> linenr += 1
> #end if
> break
> #end if
> if len(include_stack) == 0 :
> break
> input_line = include_stack.pop()
> #end while
> if line == None or ... line contains something special ... :
> ...
> if line == None :
> break
> ... process special line ...
> ... replace with None to indicate it’s been processed ...
> #end if
> if line != None :
> ... process regular line ...
> #end if
> #end while

def generate_lines():
nonlocal input_line
while True:
try:
# Note input_line appears to be an iterator, not a string
# as suggested by the name.
yield next(input_line)
except StopIteration:
if include_stack:
input_line = include_stack.pop()
else:
return

for line in generate_lines():
if not include_stack:
linenr += 1
if ... line contains something special ...:
... process special line ...
else:
... process regular line ...

Much simpler than the nested while loop hell above, and not a single
break needed (if you don't count the return, that is; in any case each
loop has a single exit point). I'd be tempted to refactor input_line
and include_stack into some sort of input context class and make
generate_lines a method of the class in order to avoid having those
variables be (effectively) global, but my goal was to keep this as
close to the original in design as possible.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-06 Thread Dan Sommers
On Mon, 06 Jun 2016 17:51:24 -0700, Lawrence D’Oliveiro wrote:

> It is nice to have a common, versatile looping form which can be
> arranged in different ways to suit the problem at hand. That’s why I
> like the C-style for-statement.

[example snipped]

I used to write a lot of assembly code, for a lot of different CPUs, and
they all had a common, versatile looping form which could be arranged in
different ways to suit the problem at hand.  On most chips, it was (and
still is) called JMP.  The trouble began with multiple conditional
branching, call stack maintenance, and those other higher level
abstractions that made my assembly code so hard to follow.  Why on Earth
would I use something so complicated as a DJNZ instruction when a
common, versatile sequence of decrement, test, and branch-on-not-zero
instructions was available?  And who needed a C-level for statment, let
alone local variables and a language-runtime-maintained function call
stack when I had a handful of common, versatile CPU registers?

http://www.catb.org/jargon/html/story-of-mel.html
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-06 Thread Lawrence D’Oliveiro
On Sunday, June 5, 2016 at 11:43:20 PM UTC+12, Marko Rauhamaa wrote:

> Then, you might overdo constructs like lambdas and maps.

Who says you can have too many lambdas?


-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-06 Thread Lawrence D’Oliveiro
On Sunday, June 5, 2016 at 11:43:20 PM UTC+12, Marko Rauhamaa wrote:
> I often experiment with different loop constructs to find the one most
> pleasing to the eye. Working directly off iterators is quite rare but a
> while-vs-for consideration is frequent. Also, should the stepping part
> be in the beginning, middle or end of the loop body?

It is nice to have a common, versatile looping form which can be arranged in 
different ways to suit the problem at hand. That’s why I like the C-style 
for-statement.

Here’s another example 
, for the 
consideration of those who don’t seem too familiar with looping:

while True :
while True :
line = next(input_line, None)
if line != None :
if len(include_stack) == 0 :
linenr += 1
#end if
break
#end if
if len(include_stack) == 0 :
break
input_line = include_stack.pop()
#end while
if line == None or ... line contains something special ... :
...
if line == None :
break
... process special line ...
... replace with None to indicate it’s been processed ...
#end if
if line != None :
... process regular line ...
#end if
#end while
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-05 Thread Marko Rauhamaa
Ned Batchelder :

> On Saturday, June 4, 2016 at 11:29:30 PM UTC-4, Lawrence D’Oliveiro wrote:
>> > > item_iter = iter(items)
>> > > while True :
>> > > item = next(item_iter, None)
>> > > if item == None :
>> > > break
>> > > if is_what_i_want(item) :
>> > > break
>> > > #end while
>
> OK. The best I can say is that you seem to think very differently
> about your code than I do. Re-implementing the logic of iteration just
> so you can make the two end conditions look similar seems like a very
> bad trade-off to me. It adds more lines, and more names, and as Steven
> points out, more opportunities to introduce errors.

I often experiment with different loop constructs to find the one most
pleasing to the eye. Working directly off iterators is quite rare but a
while-vs-for consideration is frequent. Also, should the stepping part
be in the beginning, middle or end of the loop body?

> I'm not sure what part of Python you are putting in the "bad"
> category. This example didn't involve for/else, so are you saying that
> break statements inside for-loops are a bad part?

It takes time to acclimatize to a new programming language. Initially,
you tend to shun odd-looking constructs like comprehensions. Then, you
might overdo constructs like lambdas and maps. Eventually, you'll find a
style the suits both you and the language.


Marko
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-05 Thread Ned Batchelder
On Saturday, June 4, 2016 at 11:29:30 PM UTC-4, Lawrence D’Oliveiro wrote:
> On Saturday, June 4, 2016 at 11:37:18 PM UTC+12, Ned Batchelder wrote:
> > On Friday, June 3, 2016 at 11:43:33 PM UTC-4, Lawrence D’Oliveiro wrote:
> > > On Saturday, June 4, 2016 at 3:00:36 PM UTC+12, Steven D'Aprano wrote:
> > > > You can exit a loop because you have run out of items to process, or 
> > > > you can
> > > > exit the loop because a certain condition has been met.
> > > 
> > > But why should they be expressed differently?
> > > 
> > > item_iter = iter(items)
> > > while True :
> > > item = next(item_iter, None)
> > > if item == None :
> > > break
> > > if is_what_i_want(item) :
> > > break
> > > #end while
> > 
> > Do you actually write loops like this?
> 
> Is that a non-trolling question? Yes. All the time.

OK. The best I can say is that you seem to think very differently about
your code than I do.  Re-implementing the logic of iteration just so you
can make the two end conditions look similar seems like a very bad
trade-off to me.  It adds more lines, and more names, and as Steven
points out, more opportunities to introduce errors.

> When a language has good and bad parts, it behooves the wise programmer to 
> concentrate on the good parts and try to ignore the bad.
> 
> Python’s for-loops have their uses—I *did* point this out too, did you not 
> notice?—but they are best confined to the situations that they are good at.

I'm not sure what part of Python you are putting in the "bad" category.
This example didn't involve for/else, so are you saying that break statements
inside for-loops are a bad part?

IIRC, this started as a comparison of Python's for loops and C's.  Do you
also write C for-loops as while statements if they have a break in them,
to make both of those end conditions similar?

I'm not trolling, I'm trying to understand your unusual approach.

--Ned.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-05 Thread Steven D'Aprano
On Sun, 5 Jun 2016 01:29 pm, Lawrence D’Oliveiro wrote:

> On Saturday, June 4, 2016 at 11:37:18 PM UTC+12, Ned Batchelder wrote:
>> On Friday, June 3, 2016 at 11:43:33 PM UTC-4, Lawrence D’Oliveiro wrote:
>> > On Saturday, June 4, 2016 at 3:00:36 PM UTC+12, Steven D'Aprano wrote:
>> > > You can exit a loop because you have run out of items to process, or
>> > > you can exit the loop because a certain condition has been met.
>> > 
>> > But why should they be expressed differently?
>> > 
>> > item_iter = iter(items)
>> > while True :
>> > item = next(item_iter, None)
>> > if item == None :
>> > break
>> > if is_what_i_want(item) :
>> > break
>> > #end while
>> 
>> Do you actually write loops like this?
> 
> Is that a non-trolling question? Yes. All the time.

Really? Well, you'd fail my code review, because that code is broken. If
items contains None, your loop will silently end early. That's a bug.


>> If this appeared in a code review, first we'd have a conversation about
>> what this code was meant to do ...
> 
> I would hope not.

Clearly. Nevertheless, its a conversation that needs to be had.


>> ...and then I would ask, "Why aren't you using a for loop?"
> 
> ... and then I would ask, “Didn’t you read my previous postings where I
> pointed out the issues with them?”

I don't think that very many people would agree with you or consider them
problems at all. They're more like features than problems. Your objections
to for-loops feel kind of like "I don't like bread knives because they make
it too easy to slice bread".

Okay, you don't like for-loops, because they make looping a fixed number of
times with an optional early exit too much of a "cognitive burden" for you.
You have my sympathy, but nobody else I've come across in nearly two
decades of Python programming finds them a cognitive burden.


> Here  is
> another example: see the section “Looping on Field Breaks”. 

That section was written by you and is not independent confirmation that
others agree with your issues with for-loops.


> A while-True scales gracefully to complex situations like that.

Graceful like a hippopotamus.

I don't know that the situation is complex, your description is pretty clear
and to the point:

Consider the following scenario: your sales company database has
a table of employees, and also a table of sales made by each
employee. You want to loop over these sale entries, and produce
some per-employee statistics.

but the while loop you have certainly is complex. If I understand your
intent correctly, then I think this is both more elegant and likely faster
than the while loop you use:


# Beware of bugs in the following code: 
# I have only proven it is correct, I haven't tested it.
rows = db_iter(
db = db,
cmd =
"select employees.name, sales.amount, sales.date from"
" employees left join sales on employees.id = sales.employee_id"
" order by employees.name, sales.date"
)
default = {'total sales': 0.0,
   'number of sales': 0,
   'earliest date': None,
   'latest date': None}
prev_employee_name = None
stats = {}
for (employee_name, amount, date) in rows:
if (employee_name != prev_employee_name 
and prev_employee_name is not None):
# Print the previous employee's stats
report(prev_employee_name, stats)
# and prepare for the next employee.
previous_employee_name = employee_name
stats = default.copy()
stats['total sales'] += amount
stats['number of sales'] += 1
if stats['earliest date'] is None:
stats['earliest date'] = date
stats['latest date'] = date

if prev_employee_name is not None:
report(prev_employee_name, stats)


No breaks needed at all, which makes it much more understandable: you know
instantly from looking at the code that it processes every record exactly
once, then exits.

But it is a *tiny* bit ugly, due to the need to print the last employee's
statistics after the loop is completed. We can fix that in two ways:

(1) Give up the requirement to print each employee's stats as they are
completed, and print them all at the end; or

(2) Put a sentinel at the end of rows.


The first may not be suitable for extremely large data sets, but it is
especially elegant:


rows = db_iter( ... # as above )
default = {'total sales': 0.0, 
   'number of sales': 0,
   'earliest date': None,
   'latest date': None}
stats = {}
for (employee_name, amount, date) in rows:
record = stats.setdefault(employee_name, default.copy())
stats['total sales'] += amount
stats['number of sales'] += 1
if stats['earliest date'] is None:
stats['earliest date'] = date
stats['latest date'] = date
for employee_name in stats:
report(employee_name, stats[employee_name])


As you now have all the statistics available, 

Re: for / while else doesn't make sense

2016-06-04 Thread Lawrence D’Oliveiro
On Saturday, June 4, 2016 at 11:37:18 PM UTC+12, Ned Batchelder wrote:
> On Friday, June 3, 2016 at 11:43:33 PM UTC-4, Lawrence D’Oliveiro wrote:
> > On Saturday, June 4, 2016 at 3:00:36 PM UTC+12, Steven D'Aprano wrote:
> > > You can exit a loop because you have run out of items to process, or you 
> > > can
> > > exit the loop because a certain condition has been met.
> > 
> > But why should they be expressed differently?
> > 
> > item_iter = iter(items)
> > while True :
> > item = next(item_iter, None)
> > if item == None :
> > break
> > if is_what_i_want(item) :
> > break
> > #end while
> 
> Do you actually write loops like this?

Is that a non-trolling question? Yes. All the time.

> If this appeared in a code review, first we'd have a conversation about
> what this code was meant to do ...

I would hope not.

> ...and then I would ask, "Why aren't you using a for loop?"

... and then I would ask, “Didn’t you read my previous postings where I pointed 
out the issues with them?”

Here  is another 
example: see the section “Looping on Field Breaks”. A while-True scales 
gracefully to complex situations like that. I much prefer universal, adaptable 
constructs, rather than having to remember different solutions for special 
cases.

> I suspect most Python programmers would be similarly confused about
> why you aren't using one of the central constructs of the language.

When a language has good and bad parts, it behooves the wise programmer to 
concentrate on the good parts and try to ignore the bad.

Python’s for-loops have their uses—I *did* point this out too, did you not 
notice?—but they are best confined to the situations that they are good at.

> What's next? "Why have both if and while? A goto will work for both!"

Passive-aggression aside, funny you should mention that. I use a goto-free 
structured-programming style in my C code, as exemplified here 
. I find it 
reduces problems with forgetting to free memory, or freeing it twice.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-04 Thread Lawrence D’Oliveiro
On Saturday, June 4, 2016 at 9:27:58 PM UTC+12, Steven D'Aprano wrote:
> Are you really questioning the need for for-loops to stop iterating
> when they reach the end of the sequence or iterator?

I just want to point out how you turn a discussion about the behaviour of loops 
into one about the behaviour of for-loops specifically.

> I'll give you the benefit of the doubt and assume you're not trolling.

Please, do not make this personal. That’s a sign of running out of rational 
things to say.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-04 Thread BartC

On 03/06/2016 17:22, Lawrence D’Oliveiro wrote:

On Friday, June 3, 2016 at 9:33:32 PM UTC+12, BartC wrote:

On 03/06/2016 03:47, Lawrence D’Oliveiro wrote:

On Friday, June 3, 2016 at 8:52:52 AM UTC+12, BartC wrote:

Simple iterative for-loops are more of a DIY effort...


There is one case that Python handles more nicely than C.


Just one case? Python is miles away from a C 'for'.


Yes, just one case. In Python you write a loop with one exit in one way, a loop 
with two exits in a different way, and a loop with more than two exits in yet 
another entirely different way. Can you say “cognitive burden”?


You mean like this:

 while True:
if a: break

 while True:
if a: break
...
if b: break

 while True:
if a: break
...
if b: break
...
if c: break


The for-statement in C handles most of my looping requirements.


(Yeah, you might find that does 'if' and 'goto' does as well! As well as 
most other control flow statements including multi-level breaks.)


--
Bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-04 Thread Ned Batchelder
On Friday, June 3, 2016 at 11:43:33 PM UTC-4, Lawrence D’Oliveiro wrote:
> On Saturday, June 4, 2016 at 3:00:36 PM UTC+12, Steven D'Aprano wrote:
> > You can exit a loop because you have run out of items to process, or you can
> > exit the loop because a certain condition has been met.
> 
> But why should they be expressed differently?
> 
> item_iter = iter(items)
> while True :
> item = next(item_iter, None)
> if item == None :
> break
> if is_what_i_want(item) :
> break
> #end while

Do you actually write loops like this? If this appeared in a code
review, first we'd have a conversation about what this code was
meant to do, and then I would ask, "Why aren't you using a for loop?"
I suspect most Python programmers would be similarly confused about
why you aren't using one of the central constructs of the language.

What's next? "Why have both if and while? A goto will work for both!"

--Ned.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-04 Thread Steven D'Aprano
On Sat, 4 Jun 2016 01:41 pm, Lawrence D’Oliveiro wrote:

> On Saturday, June 4, 2016 at 2:22:18 PM UTC+12, Steven D'Aprano wrote:
>> and a loop with two or more exits a *trivially different* way:
>> 
>> for x in seq:
>> do_something()
>> if condition:
>> break
>> if another_condition:
>> break
> 
> But that loop has 3 exits, written in two different ways. Why the special
> case?


Is that a serious question? Are you really questioning the need for
for-loops to stop iterating when they reach the end of the sequence or
iterator?

I'll give you the benefit of the doubt and assume you're not trolling.

A for-loop without "the special case" as you put it, would be an infinite
loop that loops forever unless you explicitly checked for an undefined
value:

for x in [1, 2, 3]:
print(x, end='')

# prints 1 2 3 UNDEFINED UNDEFINED UNDEFINED UNDEFINED ... 


meaning practically every loop would have to be written as:

for x in seq:
   if x is UNDEFINED:
   break
   process(x)


But at least now you don't have the cognitive burden of remembering that
for-loops are intended to loop over a finite number of items, then stop.

Alternatively, we could just have the for-loop raise an exception when it
passes the end of the sequence. For extra programming machismo, have it
dump core.

Thus the programmer would be responsible for (somehow!) determining how many
times it is safe to loop. This wouldn't be too onerous for sequences:

biggest = len(seq) - 1:
if biggest > -1:
for i, x in enumerate(seq):
process(x)
if i == biggest:
break


but I leave dealing with iterators as an exercise for the masochistic.


-- 
Steven

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-03 Thread Lawrence D’Oliveiro
On Saturday, June 4, 2016 at 3:00:36 PM UTC+12, Steven D'Aprano wrote:
> You can exit a loop because you have run out of items to process, or you can
> exit the loop because a certain condition has been met.

But why should they be expressed differently?

item_iter = iter(items)
while True :
item = next(item_iter, None)
if item == None :
break
if is_what_i_want(item) :
break
#end while
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-03 Thread Lawrence D’Oliveiro
On Saturday, June 4, 2016 at 2:22:18 PM UTC+12, Steven D'Aprano wrote:
> and a loop with two or more exits a *trivially different* way:
> 
> for x in seq:
> do_something()
> if condition:
> break
> if another_condition:
> break

But that loop has 3 exits, written in two different ways. Why the special case?
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-03 Thread Steven D'Aprano
On Sat, 4 Jun 2016 02:24 am, Lawrence D’Oliveiro wrote:

> On Saturday, June 4, 2016 at 3:52:42 AM UTC+12, Rob Gaddi wrote:
>> Lawrence D’Oliveiro wrote:
>> 
>>> The reason why I don’t like this is that there are two ways out of the
>>> Python for-statement, and they are written quite differently. Why the
>>> asymmetry? Logically, all ways out of a loop are of equal significance.
>> 
>> I wouldn't say that at all.  One is early termination due to success.
>> The other is that you've run out of things to try, and exit due to
>> exhaustion of the iterator.  They're two very different cases...
> 
> Different in what way? A loop exit is a loop exit. It causes termination
> of the loop.

You can exit a loop because you have run out of items to process, or you can
exit the loop because a certain condition has been met.

The canonical example is a search, where you need to process differently
depending on whether a match was found or not. In pseudo-code:


for item in items:
if condition(item):
# found match, exit loop
break

if match was found:
process match
else:
no match



-- 
Steven

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-03 Thread Steven D'Aprano
On Sat, 4 Jun 2016 02:22 am, Lawrence D’Oliveiro wrote:

> In Python you write a loop with one exit in one way, a loop with two exits
> in a different way, and a loop with more than two exits in yet another
> entirely different way. Can you say “cognitive burden”?

Yes I can, but I don't see the point.

In Python, you write a loop with one exit one way:

for x in seq:
do_something()


and a loop with two or more exits a *trivially different* way:

for x in seq:
do_something()
if condition:
break
if another_condition:
break


You can put as many or as few break statements in the loop as you like,
whether it is zero or one or ten or a thousand, the for-loop is written the
same way, with a slight difference only when going from the "no early exit"
case to "at least one early exit" case. How is this a cognitive burden?

Programming is about composing code from smaller components in this way.
Here is how you add two numbers:

result = a + b

and three numbers:

result = a + b + c

and four numbers:

result = a + b + c + d

This isn't three or more different ways to add numbers, depending on how
many numbers you have to add. It is ONE way to add, composed as many times
as you need it. For-loops are no different: you can exit the loop by
reaching the end and exiting, or you can exit early by using break. The
number of breaks is just composition.




-- 
Steven

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-03 Thread Lawrence D’Oliveiro
On Saturday, June 4, 2016 at 3:52:42 AM UTC+12, Rob Gaddi wrote:
> Lawrence D’Oliveiro wrote:
> 
>> The reason why I don’t like this is that there are two ways out of the
>> Python for-statement, and they are written quite differently. Why the
>> asymmetry? Logically, all ways out of a loop are of equal significance.
> 
> I wouldn't say that at all.  One is early termination due to success. 
> The other is that you've run out of things to try, and exit due to
> exhaustion of the iterator.  They're two very different cases...

Different in what way? A loop exit is a loop exit. It causes termination of the 
loop.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-03 Thread Lawrence D’Oliveiro
On Friday, June 3, 2016 at 9:33:32 PM UTC+12, BartC wrote:
> On 03/06/2016 03:47, Lawrence D’Oliveiro wrote:
>> On Friday, June 3, 2016 at 8:52:52 AM UTC+12, BartC wrote:
>>> Simple iterative for-loops are more of a DIY effort...
>>
>> There is one case that Python handles more nicely than C.
> 
> Just one case? Python is miles away from a C 'for'.

Yes, just one case. In Python you write a loop with one exit in one way, a loop 
with two exits in a different way, and a loop with more than two exits in yet 
another entirely different way. Can you say “cognitive burden”?

The for-statement in C handles most of my looping requirements. I rarely use 
while-loops, and do-whiles almost not at all--not for looping, anyway
.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-03 Thread Rob Gaddi
Lawrence D’Oliveiro wrote:

> On Friday, June 3, 2016 at 8:09:21 AM UTC+12, Rob Gaddi wrote:
>> Although your loop is really the _canonical_ use case for
>> 
>> for loopvar in range(initial_value, limit+1):
>> processing
>> if found_what_im_looking_for:
>> break
>> else:
>> do_whatever_it_is_you_do_when_its_not_found
>
> The reason why I don’t like this is that there are two ways out of the Python 
> for-statement, and they are written quite differently. Why the asymmetry? 
> Logically, all ways out of a loop are of equal significance.

I wouldn't say that at all.  One is early termination due to success. 
The other is that you've run out of things to try, and exit due to
exhaustion of the iterator.  They're two very different cases, the same
as if I had wrapped the loop in a function:

def roundabout():
   for var in iterable:
   if successful(var): return var
   raise ValueError("Nothing works; all is lost")

-- 
Rob Gaddi, Highland Technology -- www.highlandtechnology.com
Email address domain is currently out of order.  See above to fix.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-03 Thread BartC

On 03/06/2016 03:47, Lawrence D’Oliveiro wrote:

On Friday, June 3, 2016 at 8:52:52 AM UTC+12, BartC wrote:

Simple iterative for-loops are more of a DIY effort...


There is one case that Python handles more nicely than C. And that is iterating 
over a fixed set of values. E.g. in Python

for rendering in (False, True) :
...
#end for

versus the (slightly) more long-winded C:

for (bool rendering = false;;)
  {
...
if (rendering)
break;
rendering = true;
  } /*for*/



Just one case? Python is miles away from a C 'for'. There's:

- C's for loop, a glorified while loop where you have specify every 
single detail: for (i=a; i<=b; ++i), including writing your nominated 
loop index three times.


- A 'traditional' for loop, which iterates over the integers A to B or 0 
to N-1 without having to spell out everything: for i=a,b


- A 'forall' kind of loop which iterates over a set of values, which is 
what Python has: for i in x:


--
Bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-03 Thread BartC

On 03/06/2016 02:05, Lawrence D’Oliveiro wrote:

On Friday, June 3, 2016 at 8:52:52 AM UTC+12, BartC wrote:

One major objection was that C's 'for' isn't really a for-statement at
all (as it is understood in most other languages that haven't just
copied C's version), but is closer to a 'while' statement.


Apart from having local loop variables that get initialized just once. Not 
something you can fake with a “while” statement.


It's not hard. For:

  for (int A=B; C; D) {BODY}

you just write:

  {int A=B;
   while (C) {
 BODY;
 D;
   }
  }



That’s what makes C’s for-statement so versatile.



That's if you're into that. I've only ever use local variables with 
function-wide scope.


If your concern is with optimising, other languages can just have a rule 
about the validity of a for-loop index variable when the loop 
terminates. That's impossible in C because, it being so general purpose, 
there is no such thing as a for-loop index:


  a=0; b=1;
  for (c=2; d

Re: for / while else doesn't make sense

2016-06-02 Thread Lawrence D’Oliveiro
On Friday, June 3, 2016 at 8:52:52 AM UTC+12, BartC wrote:
> Simple iterative for-loops are more of a DIY effort...

There is one case that Python handles more nicely than C. And that is iterating 
over a fixed set of values. E.g. in Python

for rendering in (False, True) :
...
#end for

versus the (slightly) more long-winded C:

for (bool rendering = false;;)
  {
...
if (rendering)
break;
rendering = true;
  } /*for*/
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-02 Thread Lawrence D’Oliveiro
On Friday, June 3, 2016 at 8:52:52 AM UTC+12, BartC wrote:
> One major objection was that C's 'for' isn't really a for-statement at 
> all (as it is understood in most other languages that haven't just 
> copied C's version), but is closer to a 'while' statement.

Apart from having local loop variables that get initialized just once. Not 
something you can fake with a “while” statement.

That’s what makes C’s for-statement so versatile.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-02 Thread Lawrence D’Oliveiro
On Friday, June 3, 2016 at 8:09:21 AM UTC+12, Rob Gaddi wrote:
> Although your loop is really the _canonical_ use case for
> 
> for loopvar in range(initial_value, limit+1):
> processing
> if found_what_im_looking_for:
> break
> else:
> do_whatever_it_is_you_do_when_its_not_found

The reason why I don’t like this is that there are two ways out of the Python 
for-statement, and they are written quite differently. Why the asymmetry? 
Logically, all ways out of a loop are of equal significance.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-02 Thread BartC

On 02/06/2016 21:09, Rob Gaddi wrote:

Lawrence D’Oliveiro wrote:


On Friday, May 20, 2016 at 4:43:56 AM UTC+12, Herkermer Sherwood wrote:

Most keywords in Python make linguistic sense, but using "else" in for and
while structures is kludgy and misleading.


My objection is not to the choice of keyword, it’s to the whole design of the 
loop construct.

It turns out C-style for-loops “for (init; test; incr) ...” are very versatile. 
If my loop has more than one exit, I use the endless form “for (;;)” and do an 
explicit “break” for every exit condition.

Also, they let me declare a variable that is scoped to the loop, that is 
initialized just once before the loop starts, e.g.


I've had plenty of discussions on c.l.c on how much I dislike C's 'for' 
statement!





for (int loopvar = initial_value;;)
  {
if (loopvar == limit)
break;
... processing ...
if (found_what_im_looking_for)
break;
++loopvar;
  } /*for*/

I wish I could do this in Python...


loopvar = initial_value
while True:
do_your_loop_things
if you_want_to_break_then_just:
break
loopvar += 1


One major objection was that C's 'for' isn't really a for-statement at 
all (as it is understood in most other languages that haven't just 
copied C's version), but is closer to a 'while' statement. Simple 
iterative for-loops are more of a DIY effort:


  for (i=0; i

Re: for / while else doesn't make sense

2016-06-02 Thread Ian Kelly
On Thu, Jun 2, 2016 at 2:09 PM, Rob Gaddi
 wrote:
> The limited variable scoping is the only thing missing, and you can get
> around that by telling yourself you're not going to use that variable
> again, and then believing you on the matter.

Or you can actually limit the variable scope using a function:

def the_loop():
for loopvar in range(initial_value, limit+1):
processing
if found_what_im_looking_for:
return it
do_whatever_it_is_you_do_when_its_not_found

thing_i_was_looking_for = the_loop()
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-02 Thread Rob Gaddi
Lawrence D’Oliveiro wrote:

> On Friday, May 20, 2016 at 4:43:56 AM UTC+12, Herkermer Sherwood wrote:
>> Most keywords in Python make linguistic sense, but using "else" in for and
>> while structures is kludgy and misleading.
>
> My objection is not to the choice of keyword, it’s to the whole design of the 
> loop construct.
>
> It turns out C-style for-loops “for (init; test; incr) ...” are very 
> versatile. If my loop has more than one exit, I use the endless form “for 
> (;;)” and do an explicit “break” for every exit condition.
>
> Also, they let me declare a variable that is scoped to the loop, that is 
> initialized just once before the loop starts, e.g.
>
> for (int loopvar = initial_value;;)
>   {
> if (loopvar == limit)
> break;
> ... processing ...
> if (found_what_im_looking_for)
> break;
> ++loopvar;
>   } /*for*/
>
> I wish I could do this in Python...

loopvar = initial_value
while True:
do_your_loop_things
if you_want_to_break_then_just:
break
loopvar += 1

Although your loop is really the _canonical_ use case for

for loopvar in range(initial_value, limit+1):
processing
if found_what_im_looking_for:
break
else:
do_whatever_it_is_you_do_when_its_not_found

The limited variable scoping is the only thing missing, and you can get
around that by telling yourself you're not going to use that variable
again, and then believing you on the matter.

-- 
Rob Gaddi, Highland Technology -- www.highlandtechnology.com
Email address domain is currently out of order.  See above to fix.


-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-01 Thread Steven D'Aprano
On Thursday 02 June 2016 09:39, Lawrence D’Oliveiro wrote:

> Also, they let me declare a variable that is scoped to the loop


Why do you want variables scoped to the loop?



-- 
Steve

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-06-01 Thread Lawrence D’Oliveiro
On Friday, May 20, 2016 at 4:43:56 AM UTC+12, Herkermer Sherwood wrote:
> Most keywords in Python make linguistic sense, but using "else" in for and
> while structures is kludgy and misleading.

My objection is not to the choice of keyword, it’s to the whole design of the 
loop construct.

It turns out C-style for-loops “for (init; test; incr) ...” are very versatile. 
If my loop has more than one exit, I use the endless form “for (;;)” and do an 
explicit “break” for every exit condition.

Also, they let me declare a variable that is scoped to the loop, that is 
initialized just once before the loop starts, e.g.

for (int loopvar = initial_value;;)
  {
if (loopvar == limit)
break;
... processing ...
if (found_what_im_looking_for)
break;
++loopvar;
  } /*for*/

I wish I could do this in Python...
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-05-29 Thread Marko Rauhamaa
Random832 :

> On Thu, May 26, 2016, at 05:05, Marko Rauhamaa wrote:
>>3124  16   8   0
>>+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
>>| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
>>+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
>> ^ ^   ^   ^
>
> How does someone write the constant "0x8101010" and not realize that
> something's deeply wrong with their logic? I hope however it was
> implemented made it less obvious than that.

I don't know if the Sun Microsystems developer is around to answer the
question. However, judge not lest ye be judged...


Marko
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-05-29 Thread Random832
On Thu, May 26, 2016, at 05:05, Marko Rauhamaa wrote:
>3124  16   8   0
>+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
>| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
>+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> ^ ^   ^   ^

How does someone write the constant "0x8101010" and not realize that
something's deeply wrong with their logic? I hope however it was
implemented made it less obvious than that.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Exended ASCII and code pages [was Re: for / while else doesn't make sense]

2016-05-28 Thread Steven D'Aprano
On Sat, 28 May 2016 01:53 am, Rustom Mody wrote:

> On Friday, May 27, 2016 at 7:21:41 PM UTC+5:30, Random832 wrote:
>> On Fri, May 27, 2016, at 05:56, Steven D'Aprano wrote:
>> > On Fri, 27 May 2016 05:04 pm, Marko Rauhamaa wrote:
>> > 
>> > > They are all ASCII derivatives. Those that aren't don't exist.
>> > 
>> > *plonk*
>> 
>> That's a bit harsh, considering that this argument started ...
> 
> Is it now?
> For some reason I am reminded that when I was in junior school and we
> wanted to fight, we said "I am not talking to you!" made a certain gesture
> and smartly marched off.
> 
> I guess the gesture is culture-dependent and in these parts of the world
> it sounds like "*plonk*"

https://en.wikipedia.org/wiki/Plonk_%28Usenet%29



-- 
Steven

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Exended ASCII and code pages [was Re: for / while else doesn't make sense]

2016-05-27 Thread Rustom Mody
On Saturday, May 28, 2016 at 12:34:14 AM UTC+5:30, Marko Rauhamaa wrote:
> Random832 :
> 
> > On Fri, May 27, 2016, at 05:56, Steven D'Aprano wrote:
> >> On Fri, 27 May 2016 05:04 pm, Marko Rauhamaa wrote:
> >> > They are all ASCII derivatives. Those that aren't don't exist.
> >> *plonk*
> >
> > That's a bit harsh,
> 
> Everybody has a right to plonk anybody -- and even declare it
> ceremoniously.
> 
> Steven and I have recurring run-ins because Steven is an expert on
> numerous trees while I'm constantly trying to shift the discussion to
> the forest.

How disconnected...
Yours graph-theoretically,
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Exended ASCII and code pages [was Re: for / while else doesn't make sense]

2016-05-27 Thread Marko Rauhamaa
Random832 :

> On Fri, May 27, 2016, at 05:56, Steven D'Aprano wrote:
>> On Fri, 27 May 2016 05:04 pm, Marko Rauhamaa wrote:
>> > They are all ASCII derivatives. Those that aren't don't exist.
>> *plonk*
>
> That's a bit harsh,

Everybody has a right to plonk anybody -- and even declare it
ceremoniously.

Steven and I have recurring run-ins because Steven is an expert on
numerous trees while I'm constantly trying to shift the discussion to
the forest.


Marko
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Exended ASCII and code pages [was Re: for / while else doesn't make sense]

2016-05-27 Thread Chris Angelico
On Sat, May 28, 2016 at 2:09 AM, Random832  wrote:
> On Fri, May 27, 2016, at 11:53, Rustom Mody wrote:
>> And coding systems are VERY political.
>> Sure what characters are put in (and not) is political
>> But more invisible but equally political is the collating order.
>>
>> eg No one understands what jmf's gripes are... My guess is that a Euro
>> costs 3 times a Dollar.
>>
>> >>> "€".encode("UTF-8")
>> b'\xe2\x82\xac'
>> >>> "$".encode("UTF-8")
>> b'$'
>>
>> [Its another matter that this is not the evil deed of python but of
>> UTF-8!]
>
> AIUI jmf's issue is that python's string type (nothing to do with UTF-8)
> doesn't treat all strings equally. Strings that are only in Latin-1
> (including your dollar example) have only one byte per character,
> whereas strings with BMP characters have two bytes per character (he
> also has some more difficult to understand objections to the large fixed
> overhead and the cached UTF-8 version [which ASCII strings don't have])

The objection, thus, is "some strings perform faster than others do".
The only time that's ever been a serious consideration has been in
cryptography, where timing-based attacks can be used to leech info
about a private key. But this ain't that.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Exended ASCII and code pages [was Re: for / while else doesn't make sense]

2016-05-27 Thread Random832
On Fri, May 27, 2016, at 11:53, Rustom Mody wrote:
> And coding systems are VERY political.
> Sure what characters are put in (and not) is political
> But more invisible but equally political is the collating order.
> 
> eg No one understands what jmf's gripes are... My guess is that a Euro
> costs 3 times a Dollar.
> 
> >>> "€".encode("UTF-8")
> b'\xe2\x82\xac'
> >>> "$".encode("UTF-8")
> b'$'
> 
> [Its another matter that this is not the evil deed of python but of
> UTF-8!]

AIUI jmf's issue is that python's string type (nothing to do with UTF-8)
doesn't treat all strings equally. Strings that are only in Latin-1
(including your dollar example) have only one byte per character,
whereas strings with BMP characters have two bytes per character (he
also has some more difficult to understand objections to the large fixed
overhead and the cached UTF-8 version [which ASCII strings don't have])
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Exended ASCII and code pages [was Re: for / while else doesn't make sense]

2016-05-27 Thread Rustom Mody
On Friday, May 27, 2016 at 7:21:41 PM UTC+5:30, Random832 wrote:
> On Fri, May 27, 2016, at 05:56, Steven D'Aprano wrote:
> > On Fri, 27 May 2016 05:04 pm, Marko Rauhamaa wrote:
> > 
> > > They are all ASCII derivatives. Those that aren't don't exist.
> > 
> > *plonk*
> 
> That's a bit harsh, considering that this argument started ...

Is it now?
For some reason I am reminded that when I was in junior school and we wanted 
to fight, we said "I am not talking to you!" made a certain gesture and smartly
marched off.

I guess the gesture is culture-dependent and in these parts of the world it
sounds like "*plonk*"

Back in the adult world when pique is out of proportion to irritant we may guess
there is some politics around

And coding systems are VERY political.
Sure what characters are put in (and not) is political
But more invisible but equally political is the collating order.

eg No one understands what jmf's gripes are... My guess is that a Euro
costs 3 times a Dollar.

>>> "€".encode("UTF-8")
b'\xe2\x82\xac'
>>> "$".encode("UTF-8")
b'$'

[Its another matter that this is not the evil deed of python but of UTF-8!]
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Exended ASCII and code pages [was Re: for / while else doesn't make sense]

2016-05-27 Thread Random832
On Fri, May 27, 2016, at 05:56, Steven D'Aprano wrote:
> On Fri, 27 May 2016 05:04 pm, Marko Rauhamaa wrote:
> 
> > They are all ASCII derivatives. Those that aren't don't exist.
> 
> *plonk*

That's a bit harsh, considering that this argument started when you
invented your own definition of "ASCII derivative", which he never
accepted and has no obligation to accept, in order to prove that he's
wrong. That's called a straw-man argument.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Exended ASCII and code pages [was Re: for / while else doesn't make sense]

2016-05-27 Thread Steven D'Aprano
On Fri, 27 May 2016 05:04 pm, Marko Rauhamaa wrote:

> They are all ASCII derivatives. Those that aren't don't exist.

*plonk*




-- 
Steven

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Exended ASCII and code pages [was Re: for / while else doesn't make sense]

2016-05-27 Thread Marko Rauhamaa
Steven D'Aprano :

> I don't mind being corrected if I make a genuine mistake, in fact I
> appreciate correction. But being corrected for something I already
> acknowledged? That's just arguing for the sake of arguing.
> [...]
>> ASCII derivatives are in wide use in the Americas and Antarctica as
>> well. They have been spotted in Australia, New Zealand, Oceania and
>> Africa. You shouldn't be surprized if you run into them in Asia, either.
>
> Of course.
>
> But they're not *all encodings*, and while they're important, there
> are plenty of non-ASCII encodings and encodings which violate the "one
> byte equals one character" invariant followed by ASCII and
> extended-ASCII encodings.

They are all ASCII derivatives. Those that aren't don't exist.

   The vast majority of code pages in current use are supersets of ASCII
   https://en.wikipedia.org/wiki/Code_page#Relationship_to_ASCII>

Just like a byte is always 8 bits wide, and C's integers are all
two's-complement.


Marko
-- 
https://mail.python.org/mailman/listinfo/python-list


  1   2   3   >