Add "elif" to "for_stmt" and "while_stmt"

Hello! I think it will be useful in Python syntax if we can use "elif" in "for" and "while" statements besides "else" Example for i in range(j): ... elif i > 5: ... else: ... What you think about this change?

This change does not carry changes in the logic, only syntactic optimization. Actually how it should work Now the logic is written like this: (Code 1) for i in range (j): ... else: if i> 5: ... The idea is to shorten it to a record like this: (Code 2) for i in range (j): ... elif i> 5: ... In fact, AST will remain unchanged. Now AST for code 1 looks like this: For ( ..., orelse = [ If (...) ] ) It will look similar for code 2 Similar for the while loop: Now the code looks like this: while x: ... else: if y: ... And it will be like this: while x: ... elif y: ... As for the real cases where it will be applicable, I have already found several in our project For example, here in Tools/importbench/importbench.py while total_time <seconds: try: total_time + = timer.timeit (1) finally: cleanup () count + = 1 else: if total_time> seconds: count - = 1 Or lib/idlelib/pyparse.py while i <n: ch = code [i] i = i + 1 ... # some other huge calculations ... else: # didn't break out of the loop, so we're still # inside a string if (lno - 1) == firstlno: # before the previous \ n in code, we were in the first # line of the string continuation = C_STRING_FIRST_LINE else: continuation = C_STRING_NEXT_LINES вс, 15 дек. 2019 г. в 02:52, Ned Batchelder <ned@nedbatchelder.com>:

On Dec 15, 2019, at 02:08, Andrey KomIssarov <komissar.off.andrey@gmail.com> wrote:
This one doesn’t need any else at all, because there’s no break to else. Unless it raises somewhere (in which case it exits the whole function, not just the for-else) it will always hit the else. I think it’s much clearer and more readable to put that code at the top level than to put it in an else that always fires and sends me looking for the break that doesn’t exist. And of course that also solves the unnecessary extra indent problem you’re trying to solve. I’m also not sure what the logic is supposed to be here. Why do you want to decrement the count if you’ve run over seconds (which you always will) but not if you’ve exactly hit it (which you will on rare and effectively random cases, assuming that whatever timer.timeit does is similar to timeit.timeit and returns a high-resolution value as a float)? If I knew what the function was doing I could probably work it out, but in generally anything with floats that does if a<b and elif a>b without any code for a==b raises a flag and makes me want to stop and work it out.
Here at least there’s presumably a break for the else inside those huge calculations (there’s a comment about it). But, unlike the first example, the thing you’re testing in the if is completely unrelated to the loop condition, which I think would be confusing to put in the elif of a while/elif/else. It’s not logically inconsistent or anything, but I think for/else is complicated enough that I wouldn’t want to use it in code that makes the reader have to stop and think and track down something else at the same time. Also, look at your comments. They’re very clear as they are, with one bit attached to else and a separate bit attached to the if, each explaining what it means to get there. To use elif, you’d have to combine them into a single comment, which I think would also hurt readability. Do you have any examples where the else is useful like the second one, and related to the while test (or maybe the if test around the break) like the first one? I can imagine cases where this might be useful; maybe it’s even come up for me a few times. But if the motivating examples are cases where it would make the code less readable rather than more, that’s not a good sign.

14.12.19 23:37, komissar.off.andrey@gmail.com пише:
I sometimes with this feature (and also for "else" in a "try" statement). This would allow to save an indentation level in some cases. But: 1. "else" in a loop is confusing itself, and "elif" would confusing even more. 2. We use the same keyword "else" with different semantic in different statements. If we would use different keywords (like "otherwise" or "afterloop"), combining it with "if" would not look more natural than combining "else" and "for" into "elfor". 3. There are too small use cases for this. I need this maybe 1-3 times in a year that is nothing in comparison of other uses of "else" which cannot be combined with "if". So I never proposed this idea. I prefer to keep the grammar simpler.

This change does not carry changes in the logic, only syntactic optimization. Actually how it should work Now the logic is written like this: (Code 1) for i in range (j): ... else: if i> 5: ... The idea is to shorten it to a record like this: (Code 2) for i in range (j): ... elif i> 5: ... In fact, AST will remain unchanged. Now AST for code 1 looks like this: For ( ..., orelse = [ If (...) ] ) It will look similar for code 2 Similar for the while loop: Now the code looks like this: while x: ... else: if y: ... And it will be like this: while x: ... elif y: ... As for the real cases where it will be applicable, I have already found several in our project For example, here in Tools/importbench/importbench.py while total_time <seconds: try: total_time + = timer.timeit (1) finally: cleanup () count + = 1 else: if total_time> seconds: count - = 1 Or lib/idlelib/pyparse.py while i <n: ch = code [i] i = i + 1 ... # some other huge calculations ... else: # didn't break out of the loop, so we're still # inside a string if (lno - 1) == firstlno: # before the previous \ n in code, we were in the first # line of the string continuation = C_STRING_FIRST_LINE else: continuation = C_STRING_NEXT_LINES вс, 15 дек. 2019 г. в 02:52, Ned Batchelder <ned@nedbatchelder.com>:

On Dec 15, 2019, at 02:08, Andrey KomIssarov <komissar.off.andrey@gmail.com> wrote:
This one doesn’t need any else at all, because there’s no break to else. Unless it raises somewhere (in which case it exits the whole function, not just the for-else) it will always hit the else. I think it’s much clearer and more readable to put that code at the top level than to put it in an else that always fires and sends me looking for the break that doesn’t exist. And of course that also solves the unnecessary extra indent problem you’re trying to solve. I’m also not sure what the logic is supposed to be here. Why do you want to decrement the count if you’ve run over seconds (which you always will) but not if you’ve exactly hit it (which you will on rare and effectively random cases, assuming that whatever timer.timeit does is similar to timeit.timeit and returns a high-resolution value as a float)? If I knew what the function was doing I could probably work it out, but in generally anything with floats that does if a<b and elif a>b without any code for a==b raises a flag and makes me want to stop and work it out.
Here at least there’s presumably a break for the else inside those huge calculations (there’s a comment about it). But, unlike the first example, the thing you’re testing in the if is completely unrelated to the loop condition, which I think would be confusing to put in the elif of a while/elif/else. It’s not logically inconsistent or anything, but I think for/else is complicated enough that I wouldn’t want to use it in code that makes the reader have to stop and think and track down something else at the same time. Also, look at your comments. They’re very clear as they are, with one bit attached to else and a separate bit attached to the if, each explaining what it means to get there. To use elif, you’d have to combine them into a single comment, which I think would also hurt readability. Do you have any examples where the else is useful like the second one, and related to the while test (or maybe the if test around the break) like the first one? I can imagine cases where this might be useful; maybe it’s even come up for me a few times. But if the motivating examples are cases where it would make the code less readable rather than more, that’s not a good sign.

14.12.19 23:37, komissar.off.andrey@gmail.com пише:
I sometimes with this feature (and also for "else" in a "try" statement). This would allow to save an indentation level in some cases. But: 1. "else" in a loop is confusing itself, and "elif" would confusing even more. 2. We use the same keyword "else" with different semantic in different statements. If we would use different keywords (like "otherwise" or "afterloop"), combining it with "if" would not look more natural than combining "else" and "for" into "elfor". 3. There are too small use cases for this. I need this maybe 1-3 times in a year that is nothing in comparison of other uses of "else" which cannot be combined with "if". So I never proposed this idea. I prefer to keep the grammar simpler.
participants (9)
-
Anders Hovmöller
-
Andrew Barnert
-
Andrey KomIssarov
-
Chris Angelico
-
komissar.off.andrey@gmail.com
-
Ned Batchelder
-
python-ideas@marco.sulla.e4ward.com
-
Serhiy Storchaka
-
Siddharth Prajosh