Suggestion for language addition

Hi folks, I have a few decades of experience with software engineering using assembler, C, FORTRAN, Pascal, Ada and a fair number of other languages. I've been using Python as well for a number of years now. Both Pascal and Ada have "end" statements, which make the code (at least for me :-) ) a lot more readable and maintainable, especially if the code within if/while/for statements gets longer and nested deeper. These statements exist in these languages for a good reason. I had a look in the archives to see if someone else already proposed this but couldn't find anything, so here goes. Please let me know whether you think this idea is worth to convert to a PEP. thanks, Jan Idea: To include optional "end if", "end while", "end for" and "end <function name>", "end <class name>" in the language. The Python interpreter would test that any "end" matches with the correct corresponding statements and have the correct indentation, in other words throw an error if you would write "end if" where an "end while" should be. This will be a great help preventing errors with procedural logic, that I now have to painstakingly debug at runtime, especially after moving bits of code around. Python editors would ideally highlight "if" and "end if" just like they now highlight "if". By default different colors could be picked for "if" and "end if", "while" and "end while" etc. All this is completely optional of course, so it won't break any existing code. Advantages: - better readability and maintainability - help prevent procedural logic mistakes - editors could use this for improved highlighting of code Disadvantages: - none :-) it's optional, just like the typing that was introduced in Python 3 Code example: def func (i: int, j: int, k: int) -> None: if (i == 3): while (i < 15): i += 1 if (k == 8): lots of other code (think a page or more) lots of other code here is more code <- to which if or while does this belong? and a bit more further code The code could be rewritten like this: def func (i: int, j: int, k: int) -> None: if (i == 3): while (i < 15): i += 1 if (k == 8): lots of other code (think a page or more) lots of other code end if end while (writing "end if" would throw an error at parse time) here is more code and a bit more end if end func further code Looking forward to your feedback! regards, Jan NEW ZEALAND

This is a nonstarter — meaningful indentation is a pretty baked-in ( and liked ) part of the language. And yes, it’s been brought up many times before on this list. And it already exists: for item in a_sequence: do_some_stuff #end for :-) -CHB PS: I’m pretty sure some has written an import hook that does something like this — but mostly as a joke. On Mon, Dec 2, 2019 at 3:12 PM Jan Bakuwel <jan.bakuwel@gmail.com> wrote:
-- Christopher Barker, PhD Python Language Consulting - Teaching - Scientific Software Development - Desktop GUI and Web Development - wxPython, numpy, scipy, Cython

On Mon, Dec 2, 2019 at 3:12 PM Jan Bakuwel <jan.bakuwel@gmail.com> wrote:
This is your actual problem: you have a whole page of code nested four times. That’s not going to be readable no matter what editor support you have; you need to refactor it. With smaller blocks of code where the whole thing does fit easily on the screen, you usually don’t get lost—and if you do, most editors already help you. They can draw a different colored line down the left side of each block, or have a keystroke to briefly highlight the start of the current block (I use that in emacs whenever I’m forced to edit code that someone insisted on writing with 2 or even 1 space per indent—or, worse, inconsistent indents), or collapse the current block to an outline (which would actually be less useful if the outline had to show 3 lines instead of 2). Sure, none of that is sufficient with huge blocks of code, but I don’t see how an “end if” would help. Who cares if they’re the same color when you can’t see them both anyway (which, by definition, you can’t when there’s a page or more of code between them)? All the “end if” really tells you is that some block whose start you can’t see ends here, which you can already tell from the dedent. (And, unlike C, where you need a closing brace because the dedent could be a lie, in Python it syntactically means the very thing you hope it means.)

To play the devil's advocate... (1) Using the (possible, future) PEG parser <https://github.com/gvanrossum/pegen/> this would be easy to add to the grammar, as long as it's optional. (2) It can actually help readability in some cases, especially when e.g. 'for' and 'if' alternate. (3) I have been known to hold a ruler against my screen to double-check indentation. On Mon, Dec 2, 2019 at 8:51 PM Andrew Barnert via Python-ideas < python-ideas@python.org> wrote:
-- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...>

On Dec 2, 2019, at 21:00, Guido van Rossum <guido@python.org> wrote:
3) I have been known to hold a ruler against my screen to double-check indentation.
Well, if that isn’t part of your integrated development environment, you just need to switch to emacs and give it control of a 3D printer and a robot and it can integrate holding up a ruler for you. :) But more seriously, the unobtrusive colored vertical indent-guide lines (that I think Sublime popularized, but lots of editors do it now, including at least two variations for emacs) really do solve this for me just as well, even with horrible random-indentation code. The only reason I still use the keystroke to highlight the start of the block instead is too many decades of muscle memory using emacs. That doesn’t help when there’s so much code in the inner block that it doesn’t fit on the screen, so I can’t trace the line up to the start. But does a ruler help any better? And would an “end for”?

For me it's really easy given your example without the end statements. I suppose your use case is actually about much longer code, with much more cyclomatic complexity. I recommend you run McCabe's algorithm instead to help refactor your code. https://pypi.org/project/mccabe/

Hi Guido, On 3/12/19 6:00 pm, Guido van Rossum wrote:
To play the devil's advocate...
Thanks :-)
It seems quite a few folks missed the most important argument, which is that apart from the readability argument, there's also the argument that the Python interpreter can help find issues in the code at parse time instead of at run time (way more time intensive) as writing a "end for" where an "end while" should be gets flagged immediately. cheers, Jan

I was playing the devil's advocate in jest. There is no way this will be added to Python, for a large variety of sociological and software engineering reasons. While some of the responses may to you seem like they come from inexperienced people who have not carefully read your argument, consider that to us, your proposal appears to come from yet another person who is relatively new to Python asking for their favorite feature from language X without understanding how that feature would interact with the rest of Python. On Tue, Dec 3, 2019 at 2:13 PM Jan Bakuwel <jan.bakuwel@gmail.com> wrote:
-- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...>

Hi Guido, On 4/12/19 1:06 pm, Guido van Rossum wrote:
I was not implying at all that any response was from inexperienced people. However no-one, at least not in a way clear to me, responded to the value of the suggestion to get early warnings (ie. at parse time) when an "end while" is written where an "end if" should have been written. While I like Python a lot, I do miss the support of advanced compilers that tell me at compile time where I made a typo or logic error so I find myself spending relatively more time debugging at runtime. Not a worry as Python easily makes up for the lost time for 1000+ reasons. I'm just thinking aloud how it could, in my eyes, be even better while also considering the sociological and software engineering impact on the Python community to the best of my abilities. I appreciate that I have much less experience with Python than many of the folks on the list here. So please help me understand how the suggested feature would, in any way, unfavorably interact with the rest of Python as you say. cheers, Jan

Jan Bakuwel writes:
That's inherent in an implementation that compiles "just in time" to run and "module at a time", as Python implementations generally (always?) do. After all, if you really made a syntax *error*, Python will error out at compile-time. So that presumably isn't what you're talking about. Is it that the error reporting isn't as precise? Or something else?
If it were optional, I wouldn't use it, and I work with a couple million lines of code that won't be changed. So it would be a WTF? every time I saw it. As you pointed out yourself, it's programmer time, not lines of code or machine time, that's expensive. Because of the way the Python parser works, it would also likely be implemented as be a keyword, and that would require changing a ton of code (eg, the 'end' argument to print()), which would kill the idea. (Exceptions to the rule that a keyword is globally reserved have been granted in the past, but I believe they were intended to be deprecated on introduction, and eventually turned into "full" keywords.) Steve

On Tuesday, December 3, 2019 at 7:54:03 PM UTC-5, Jan Bakuwel wrote:
I can see how you would find it useful, and I can also see why you're getting a lot of opposition. One compromise suggestion is to take Andrew's advice and add your own # end for's. Then take Serhiy's advice and add the check to a linter. After you've been coding like this for a while, start your movement to popularize "# end for" :)

Hi all, Thanks for the feedback on the list. I just got here but enjoy the discussion. Here's my summary of what I've read. - What I've suggested has been brought up many times before. In other words, there are a lot of people who think this is useful. - People focus on the silly example and suggest that the code needs refactoring but that is besides the point. There are plenty use cases where this would be very helpful, for example and especially after refactoring code to safeguard procedural logic. Explicitly defining where your "end while" is quickly tells you if it has become an "end if" after refactoring. - Many people like and prefer meaningful indentation. My proposal does not have any impact on them as they can continue to do that. People, like me, who value meaningful indentation "plus" if you like would very much appreciate this language addition. - I can't say much about the effort required to add this to the language but as far as I can tell it's pretty straight forward? Should I write a PEP? I believe I'll need a sponsor - any takers? cheers, Jan PS if I can use a hook, I'd be very happy to hear more about how I'd go about that. It would mean I wouldn't have to wait but could possibly already start using this :-) !

On Dec 3, 2019, at 14:34, Jan Bakuwel <jan.bakuwel@gmail.com> wrote:
People focus on the silly example and suggest that the code needs refactoring but that is besides the point.
You’re the one who gave that example as motivation, and who specifically highlighted the “more than a page of code” thing; it’s not something everyone else invented and read into your example. If that example is a bad argument for your proposal, the burden of coming up with a good argument for your proposal is on you. (After all, the default for any proposal is to not change anything.) If there are “plenty use cases”, provide one that isn’t silly instead of one that is. While you’re at it, you might want to show some other languages. I think part of the reaction against it comes from the languages people are familiar with. Python, Swift, Ruby, and most other languages people tout as “readable” just have a generic end or } or dedent or whatever for all blocks. So does C and all of descendants. But PHP has endfor, and pl/SQL, and sh has for/do/done… and those aren’t languages people want to use. Maybe that’s an unfair prejudice—but if so, if you can point people to better examples, it might help overcome that.

Hi Andrew, On 4/12/19 5:15 pm, Andrew Barnert wrote:
Fair enough. See below for a link to a few examples in the Ada programming language.
If that example is a bad argument for your proposal, the burden of coming up with a good argument for your proposal is on you. (After all, the default for any proposal is to not change anything.) If there are “plenty use cases”, provide one that isn’t silly instead of one that is.
Yeah, ok. I have a feeling though that even if I would provide a real-life use case that people would argue that they can read it fine without the end statements or that I should refactor the code so all blocks would easily fit on a page or that the code should not be nested deeper than X levels. It's clear that I failed to convince even a single person so it's time to drop it. Great to have this list to test the waters so to speak :-)
While you’re at it, you might want to show some other languages. I think part of the reaction against it comes from the languages people are familiar with. Python, Swift, Ruby, and most other languages people tout as “readable” just have a generic end or } or dedent or whatever for all blocks. So does C and all of descendants. But PHP has endfor, and pl/SQL, and sh has for/do/done… and those aren’t languages people want to use. Maybe that’s an unfair prejudice—but if so, if you can point people to better examples, it might help overcome that.
As mentioned, my suggestion comes from my experience with the Ada programming language. Ada even has "named loops", a really cool feature that allows you to exit an outer loop inside an inner loop by "exiting" the loop referring to it's name (https://en.wikibooks.org/wiki/Ada_Programming/Control#Loop_with_condition_at...). In my opinion, Ada is one of the most well designed programming languages aiming at reducing anomalies and thus more reliable systems. From the article on Wikipedia "For these reasons, Ada is widely used in critical systems, where any anomaly <https://en.wikipedia.org/wiki/Anomaly_in_software> might lead to very serious consequences, e.g., accidental death, injury or severe financial loss. Examples of systems where Ada is used include avionics <https://en.wikipedia.org/wiki/Avionics>, air traffic control <https://en.wikipedia.org/wiki/Air_traffic_control>, railways, banking, military and space technology." https://en.wikipedia.org/wiki/Ada_%28programming_language%29 Thanks all, for your time and engagement, it's much appreciated. regards, Jan

On Wed, Dec 4, 2019 at 7:28 PM Jan Bakuwel <jan.bakuwel@gmail.com> wrote:
It's clear that I failed to convince even a single person so it's time to drop it. Great to have this list to test the waters so to speak :-)
This is exactly why not every idea needs a PEP :) Discuss first, PEP later. ChrisA

On Wed, Dec 4, 2019, 3:31 AM Jan Bakuwel <jan.bakuwel@gmail.com> wrote:
While I am among the everybody not convinced by needing "end" constructs, I've often wanted named loops. I know approaches to this have been proposed many times, and they all have their own warts. E.g. an ad hoc pseudo code that may or may not match any previous proposal: for x in stuff as outer: for y in other_stuff as inner: ... if cond: break outer But we all manage without it.

On Wed, 4 Dec 2019 at 21:16, Anders Hovmöller <boxed@killingar.net> wrote:
I guess what is meant is this: from contextlib import suppress class Exit(BaseException): pass stuff = [10, 20, 30] other_stuff = [1, 2, 3] with suppress(Exit): for x in stuff: for y in other_stuff: print(x, y) if x + y > 21: raise Exit You can so the same with try/except: class Exit(BaseException): pass stuff = [10, 20, 30] other_stuff = [1, 2, 3] try: for x in stuff: for y in other_stuff: print(x, y) if x + y > 21: raise Exit except Exit: pass I dislike both of the above though. My suggestion would be to use a function rather than exceptions: stuff = [10, 20, 30] other_stuff = [1, 2, 3] def func(): for x in stuff: for y in other_stuff: print(x, y) if x + y > 21: return func() In this example it might seem awkward to introduce a function just for this but normally in context the function can have a more reasonable purpose and a good name and return something useful etc. -- Oscar

These are all a little bit ugly IMO. I've never written the contextlib.suppress style, but I have the others. Usually what I'll actually do is: for x in stuff: break_outer = False for y in other_stuff: do_whatever(x, y) if cond: break_outer = True break if break_outer: break I think this is also ugly noise, but it feels like less of a cognitive load than Oscar's approaches. On Wed, Dec 4, 2019 at 5:56 PM Oscar Benjamin <oscar.j.benjamin@gmail.com> wrote:
-- Keeping medicines from the bloodstreams of the sick; food from the bellies of the hungry; books from the hands of the uneducated; technology from the underdeveloped; and putting advocates of freedom in prisons. Intellectual property is to the 21st century what the slave trade was to the 16th.

On Dec 4, 2019, at 14:56, Oscar Benjamin <oscar.j.benjamin@gmail.com> wrote:
I think the majority of the time, refactoring it into a function actually makes it better, or at least neutral. The problem is that occasionally it really does make it significantly worse, and that’s when you really wish named break existed. But I think two people already said that’s about once/year for them? That sounds about right to me, too.

On Dec 4, 2019, at 12:14, Mike Miller <python-ideas@mgmiller.net> wrote:
If you want to change this from an aside to a real proposal, it’s probably worth starting a new thread (and providing a real-life use case—if we all run into it once a year, many people probably won’t remember exactly what it looked like when they last ran into it, and how much their workaround bothered them).

Actually, I found it's rejected PEP: https://www.python.org/dev/peps/pep-3136/. It looks like the first of several ideas there matches my ad hoc syntax. It *was* 2007, in distant pre-walrus memory. But I'm not sure the SC would revisit Guido's ruling. On Wed, Dec 4, 2019, 6:45 PM Andrew Barnert via Python-ideas < python-ideas@python.org> wrote:

On Dec 4, 2019, at 16:04, David Mertz <mertz@gnosis.cx> wrote:
Given that the PEP was incomplete (no implementation strategy, no argument for one of the options over the others), that its rationale had a lot of incorrect statements (like claiming that C, C++, and Ruby all have labeled break when none of them do, and C++ had recently rejected the idea), and that there’s no motivating example, maybe you could argue for a better version of the proposal to be reconsidered. On the other hand, except maybe for the last point, Guido already dismissed all of that and instead rejected it just because “code so complicated to require this feature is very rare”, and I don’t think you can really argue against that. (I mean, if you found tons of examples of stdlib and github code that could be improved by labeled break, that would actually constitute a good argument, but I don’t think it’s likely that you could find that much.)

On 5/12/19 1:03 pm, David Mertz wrote:
Whoops, didn't realise my remark let this discussion continue in a different direction :-) Just read Guido's reason for rejecting named loops, interesting. It seems we have different ideas about what "code clarity" means and that's perfectly fine of course. Beauty is in the eye of the beholder. To refer once again to Ada (sorry), that language was explicitly designed taking core software engineering principles and various issues with existing languages into account to create "the perfect language" for systems that must not fail (if we can help it). I like systems that don't fail :-). Various key elements are covered, such as readability and predictability. In other words, everything in that language is geared towards that, including named loops. But I digress. Regarding those named loops, I do get across that from time to time (not every month) but don't think that it only occurs in complicated code. I also don't see how it can be "abused". So far when I used it, it was the most elegant way to leave an inner loop. If one can have nested loops then, I think, one should be able to break or continue out of any of those loops without having to resort to yet another single use function that has no other purpose. Raising an exception is an obvious alternative but I've learned that exceptions are expensive. If that's not the case in Python, I'll have to unlearn that :-) Where it comes to the far reaching effects of such a change I'll have to respectfully bow my head and follow the lead of those who know. Guido brings up the topic of using goto (bad) and return (good) in his rejection. I've seen multiple returns in Python functions. I think that is a bad idea; a goto would be better than multiple returns as it results in more predictive behaviour and facilitates having only one clean "exit" point of the function. Compilers (or in case of Python: smart IDEs) can then help find errors in logic that otherwise would only surface at runtime. Don't get me wrong though... I've never needed a goto since I stopped using Basic a few centuries ago. It's easy to avoid. But multiple returns should, following the same logic, ideally not be supported by the language as code using those will be less clear than code that doesn't. cheers, Jan

On Dec 4, 2019, at 17:55, Jan Bakuwel <jan.bakuwel@gmail.com> wrote:
Just read Guido's reason for rejecting named loops, interesting. It seems we have different ideas about what "code clarity" means and that's perfectly fine of course. Beauty is in the eye of the beholder. To refer once again to Ada (sorry), that language was explicitly designed taking core software engineering principles and various issues with existing languages into account to create "the perfect language" for systems that must not fail (if we can help it)
Note that it was designed taking core software engineering principles of the 1970s and the distinct languages of the 1970s into account to create “the perfect Pascal”. A lot has changed in the nearly 40 years since the report was published. For just two examples: The notion of what a type system can do has been vastly extended, meaning that Haskell and Rust and Swift can prevent all kinds of errors that nobody believed could possibly be prevented in 1980. And advances in multithreading have opened a whole new class of problems that nobody could have even imagined, much less tried to solve, in 1980, so Go and Java have tools to verify lock-free behavior; Ada does not.
Regarding those named loops, I do get across that from time to time (not every month) but don't think that it only occurs in complicated code. I also don't see how it can be "abused". So far when I used it, it was the most elegant way to leave an inner loop. If one can have nested loops then, I think, one should be able to break or continue out of any of those loops without having to resort to yet another single use function that has no other purpose. Raising an exception is an obvious alternative but I've learned that exceptions are expensive. If that's not the case in Python, I'll have to unlearn that :-)
Yes, you have to unlearn it. Exceptions are not that expensive in Python (and in a lot of other modern languages)—but even if they were, you’d still have to deal with the fact that Python uses them pervasively. Every for loop ends with an exception being thrown and caught, whether you like it or not.
Guido brings up the topic of using goto (bad) and return (good) in his rejection. I've seen multiple returns in Python functions. I think that is a bad idea; a goto would be better than multiple returns as it results in more predictive behaviour and facilitates having only one clean "exit" point of the function.
I’ve never understood this idea. The dogma comes from C, where functions usually have to do a lot of explicit cleanup at the end, which means an early return complicates that cleanup, often in really messy ways that people get wrong all the time. So it makes sense for C. But most languages are not C. Even C++ programmers quickly figured out that this doesn’t even extend to their closely-related language as long as you use it properly. But other people keep trying to extend it to languages like Python where there’s not even a “if you use it properly” condition. Storing a value in an otherwise-unnecessary variable and then making sure you correctly break out of and/or skip over all of the remaining flow control to safely arrive at the end of a function is complicated. Returning early doesn’t have those problems. And if you don’t like early return, how could you possibly like labeled break? It’s a similar goto in disguise, it means every loop now has multiple clean exit points that you have to keep track of possibly buried deep down in the nesting, it means any explicit cleanup might get skipped accidentally… if none of that is a problem for labeled break, why is any of it a problem for early return?
Compilers (or in case of Python: smart IDEs) can then help find errors in logic that otherwise would only surface at runtime.
Why do early returns make that any harder? (Other than eliminating some of the sources of those logic errors in the first place, which doesn’t seem like a bad thing.) What’s an example of a logic error that a compiler could catch without early return but can’t catch with it?

Hi Andrew, On 5/12/19 3:43 pm, Andrew Barnert wrote:
Does Python have tools to do that? I hit one of those snags a few weeks ago. Today's Ada is not the 80-ies Ada either. Fact is, it's still used for mission critical systems and for good reasons. Let me put it this way: I doubt we'll see Python used in aircraft control systems, but will happily stand corrected if I got that wrong. Ada wouldn't be used today if it would be 40 years old technology.
Regarding those named loops, I do get across that from time to time (not every month) but don't think that it only occurs in complicated code. I also don't see how it can be "abused". So far when I used it, it was the most elegant way to leave an inner loop. If one can have nested loops then, I think, one should be able to break or continue out of any of those loops without having to resort to yet another single use function that has no other purpose. Raising an exception is an obvious alternative but I've learned that exceptions are expensive. If that's not the case in Python, I'll have to unlearn that :-) Yes, you have to unlearn it. Exceptions are not that expensive in Python (and in a lot of other modern languages)—but even if they were, you’d still have to deal with the fact that Python uses them pervasively. Every for loop ends with an exception being thrown and caught, whether you like it or not.
Sweet, thanks :-) Done.
I think it's harder to understand how a function works if that function has various ways it could end instead of just one. Maybe that's just me thinking that is cleaner. What is clean is, to a certain extend, in the eye of the beholder. An example of a logic error would be where a variable is used before it's being assigned, which could be the case for one of the returns but not for the other. regards, Jan

05.12.19 04:43, Andrew Barnert via Python-ideas пише:
Yes, you have to unlearn it. Exceptions are not that expensive in Python (and in a lot of other modern languages)—but even if they were, you’d still have to deal with the fact that Python uses them pervasively. Every for loop ends with an exception being thrown and caught, whether you like it or not.
Raising and catching an exception in the C code is much cheaper than in the Python code. In Python you instantiate an exception and set its traceback, context and clause, in C you can just store several threadlocal pointers (most of them NULLs). In python you execute complex bytecode to catch an exception, in C you just read and compare few pointers in common case. StopIteration is not even raised in most case internally in the C code, it is raised only when leaked to the Python code. So exceptions are still expensive in Python, even comparing with other Python code. But outside of tight loops or if you do some input/output, they are proper tool for control flow.

My little experiments in 3.7 show exception setup is about 40% more costly than just a do-nothing loop, but execution of is about 9x more expensive than doing nothing, so actually very little cost if your loop only rarely catches the exception (I assume you'll probably actually do something inside the loop, which would reduce the proportional overhead of try-setup). no try : 0.000022s : N= 1000 : stddev=0.00000 unraised : 0.000030s : N= 1000 : stddev=0.00005 raised : 0.000180s : N= 1000 : stddev=0.00000 from tools.timethis import timethis # Dabeaz's timing tool. N = 1_000 for __ in range(1_000): with timethis("no try"): for _ in range(N): pass with timethis("unraised"): for _ in range(N): try: pass except ZeroDivisionError: pass with timethis("raised"): for _ in range(N): try: raise ZeroDivisionError except ZeroDivisionError: pass On Wed, Dec 4, 2019 at 9:22 PM Serhiy Storchaka <storchaka@gmail.com> wrote:

On 04/12/2019 23:41:19, Andrew Barnert via Python-ideas wrote:
This could lead (in complicated examples) to code would be harder to maintain than if it used named loops, but it is concise it is backward-compatible it could AFAIK be checked at compile time (for more "break"s than enclosing loops) it does not require a new keyword IMO it would handle a large majority of use cases. Rob Cliffe

Hi Chris, On 3/12/19 5:07 pm, Christopher Barker wrote:
This is a nonstarter — meaningful indentation is a pretty baked-in ( and liked ) part of the language.
I know. However why not have something that suits even more people. Meaningful indentation is great (and liked here) too... but it could be even better for those valuing that while those who do not don't have to use it.
And yes, it’s been brought up many times before on this list.
Sorry. Newbie here. If being brought up many times, implementing it would be 100% backwards compatible and those relying solely on meaningful indentation can continue to do so .... sounds like a perfect candidate for a PEP to me. Glad to hear I'm not the only one :-)
Yeah. That's I'm doing now. What I'm suggesting does not exist however. The bit that's missing is that the Python interpreter would check that and "end" matches the correct begin.
Having the interpreter check more at parse time saves a significant amount of time in more complex projects - no joke :-)

On 4/12/19 11:06 am, Jan Bakuwel wrote:
If being brought up many times, .... sounds like a perfect candidate for a PEP to me.
The implication is that it has been brought up AND REJECTED multiple times. But you do have a point -- a rejected PEP would provide documentation of the reasons against for anyone bringing it up again in the future. -- Greg

Jan Bakuwel writes:
Interesting. Has it been rejected as PEP or as an idea?
In this context "PEP" and "idea" are interchangeable, except that "ideas" aren't listed in PEP 0.
Having a list of "rejected" ideas/PEPs with the reasons why it was rejected would indeed be great to have.
The list is in PEP 0. The reasons are in the PEPs themselves.

On Dec 3, 2019, at 16:54, Jan Bakuwel <jan.bakuwel@gmail.com> wrote:
We do have a list of rejected PEPs. It’s a category in the overall list of PEPs (PEP 0). And the rejection reasons are in each PEP. Some of those rejected PEPs were even written specifically to be rejected, so there will be an answer for anyone who wonders “Why doesn’t Python do X?”, or so the next 42 times the idea comes up someone can just reply “Read PEP 789 and see if you have anything to add” instead of everyone rehashing the same arguments. There is no list of all rejected _ideas_, because a lot of ideas aren’t worth the effort to write a PEP or a formal rejection notice, and because PEP 0 would probably get pretty unwieldy if it included every half-baked idea that anyone ever mentioned. Is this one worthy of a PEP? Well, if you’re willing to put in the effort to make the best case for the idea, work through all the details, gather all the relevant threads and other links, and write it, even knowing it’ll be rejected, I’ll bet a core dev would be willing to sponsor it. And those are the only criteria there are for writing a PEP and adding it to the index. And if this idea has come up and been shot down many times over the decades, it doesn’t seem like it would be wasted effort to me. But if you’re not ready to give up on the idea yet, I wouldn’t focus on a PEP yet. I suspect that if you can’t get enough traction on -ideas, where you can directly respond to objections and refine your positive case, a frozen document is probably less likely to convince people. Plus, once it’s rejected, that’s … not quite final (I think ideas from rejected PEPs have been revived; I think the @ operator is an example?), but at least a lot more final.

On 4/12/19 1:51 pm, Jan Bakuwel wrote:
Has it been rejected as PEP or as an idea?
There has never been a PEP on it as far as I remember. Probably because it always gets shot down before it gets anywhere near that stage. One of the probable reasons for that is summed up by "preferably only one obvious way to do it". Python doesn't generally go out of its way to provide alternative ways of writing things. You say that it would be optional, so people who don't want to use it could ignore it. But you can't ignore it if you're reading or maintaining code written by someone else who uses it. Every "optional" feature has a cost to the whole community. - Greg

This is a nonstarter — meaningful indentation is a pretty baked-in ( and liked ) part of the language. And yes, it’s been brought up many times before on this list. And it already exists: for item in a_sequence: do_some_stuff #end for :-) -CHB PS: I’m pretty sure some has written an import hook that does something like this — but mostly as a joke. On Mon, Dec 2, 2019 at 3:12 PM Jan Bakuwel <jan.bakuwel@gmail.com> wrote:
-- Christopher Barker, PhD Python Language Consulting - Teaching - Scientific Software Development - Desktop GUI and Web Development - wxPython, numpy, scipy, Cython

On Mon, Dec 2, 2019 at 3:12 PM Jan Bakuwel <jan.bakuwel@gmail.com> wrote:
This is your actual problem: you have a whole page of code nested four times. That’s not going to be readable no matter what editor support you have; you need to refactor it. With smaller blocks of code where the whole thing does fit easily on the screen, you usually don’t get lost—and if you do, most editors already help you. They can draw a different colored line down the left side of each block, or have a keystroke to briefly highlight the start of the current block (I use that in emacs whenever I’m forced to edit code that someone insisted on writing with 2 or even 1 space per indent—or, worse, inconsistent indents), or collapse the current block to an outline (which would actually be less useful if the outline had to show 3 lines instead of 2). Sure, none of that is sufficient with huge blocks of code, but I don’t see how an “end if” would help. Who cares if they’re the same color when you can’t see them both anyway (which, by definition, you can’t when there’s a page or more of code between them)? All the “end if” really tells you is that some block whose start you can’t see ends here, which you can already tell from the dedent. (And, unlike C, where you need a closing brace because the dedent could be a lie, in Python it syntactically means the very thing you hope it means.)

To play the devil's advocate... (1) Using the (possible, future) PEG parser <https://github.com/gvanrossum/pegen/> this would be easy to add to the grammar, as long as it's optional. (2) It can actually help readability in some cases, especially when e.g. 'for' and 'if' alternate. (3) I have been known to hold a ruler against my screen to double-check indentation. On Mon, Dec 2, 2019 at 8:51 PM Andrew Barnert via Python-ideas < python-ideas@python.org> wrote:
-- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...>

On Dec 2, 2019, at 21:00, Guido van Rossum <guido@python.org> wrote:
3) I have been known to hold a ruler against my screen to double-check indentation.
Well, if that isn’t part of your integrated development environment, you just need to switch to emacs and give it control of a 3D printer and a robot and it can integrate holding up a ruler for you. :) But more seriously, the unobtrusive colored vertical indent-guide lines (that I think Sublime popularized, but lots of editors do it now, including at least two variations for emacs) really do solve this for me just as well, even with horrible random-indentation code. The only reason I still use the keystroke to highlight the start of the block instead is too many decades of muscle memory using emacs. That doesn’t help when there’s so much code in the inner block that it doesn’t fit on the screen, so I can’t trace the line up to the start. But does a ruler help any better? And would an “end for”?

For me it's really easy given your example without the end statements. I suppose your use case is actually about much longer code, with much more cyclomatic complexity. I recommend you run McCabe's algorithm instead to help refactor your code. https://pypi.org/project/mccabe/

Hi Guido, On 3/12/19 6:00 pm, Guido van Rossum wrote:
To play the devil's advocate...
Thanks :-)
It seems quite a few folks missed the most important argument, which is that apart from the readability argument, there's also the argument that the Python interpreter can help find issues in the code at parse time instead of at run time (way more time intensive) as writing a "end for" where an "end while" should be gets flagged immediately. cheers, Jan

I was playing the devil's advocate in jest. There is no way this will be added to Python, for a large variety of sociological and software engineering reasons. While some of the responses may to you seem like they come from inexperienced people who have not carefully read your argument, consider that to us, your proposal appears to come from yet another person who is relatively new to Python asking for their favorite feature from language X without understanding how that feature would interact with the rest of Python. On Tue, Dec 3, 2019 at 2:13 PM Jan Bakuwel <jan.bakuwel@gmail.com> wrote:
-- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...>

Hi Guido, On 4/12/19 1:06 pm, Guido van Rossum wrote:
I was not implying at all that any response was from inexperienced people. However no-one, at least not in a way clear to me, responded to the value of the suggestion to get early warnings (ie. at parse time) when an "end while" is written where an "end if" should have been written. While I like Python a lot, I do miss the support of advanced compilers that tell me at compile time where I made a typo or logic error so I find myself spending relatively more time debugging at runtime. Not a worry as Python easily makes up for the lost time for 1000+ reasons. I'm just thinking aloud how it could, in my eyes, be even better while also considering the sociological and software engineering impact on the Python community to the best of my abilities. I appreciate that I have much less experience with Python than many of the folks on the list here. So please help me understand how the suggested feature would, in any way, unfavorably interact with the rest of Python as you say. cheers, Jan

Jan Bakuwel writes:
That's inherent in an implementation that compiles "just in time" to run and "module at a time", as Python implementations generally (always?) do. After all, if you really made a syntax *error*, Python will error out at compile-time. So that presumably isn't what you're talking about. Is it that the error reporting isn't as precise? Or something else?
If it were optional, I wouldn't use it, and I work with a couple million lines of code that won't be changed. So it would be a WTF? every time I saw it. As you pointed out yourself, it's programmer time, not lines of code or machine time, that's expensive. Because of the way the Python parser works, it would also likely be implemented as be a keyword, and that would require changing a ton of code (eg, the 'end' argument to print()), which would kill the idea. (Exceptions to the rule that a keyword is globally reserved have been granted in the past, but I believe they were intended to be deprecated on introduction, and eventually turned into "full" keywords.) Steve

On Tuesday, December 3, 2019 at 7:54:03 PM UTC-5, Jan Bakuwel wrote:
I can see how you would find it useful, and I can also see why you're getting a lot of opposition. One compromise suggestion is to take Andrew's advice and add your own # end for's. Then take Serhiy's advice and add the check to a linter. After you've been coding like this for a while, start your movement to popularize "# end for" :)

Hi all, Thanks for the feedback on the list. I just got here but enjoy the discussion. Here's my summary of what I've read. - What I've suggested has been brought up many times before. In other words, there are a lot of people who think this is useful. - People focus on the silly example and suggest that the code needs refactoring but that is besides the point. There are plenty use cases where this would be very helpful, for example and especially after refactoring code to safeguard procedural logic. Explicitly defining where your "end while" is quickly tells you if it has become an "end if" after refactoring. - Many people like and prefer meaningful indentation. My proposal does not have any impact on them as they can continue to do that. People, like me, who value meaningful indentation "plus" if you like would very much appreciate this language addition. - I can't say much about the effort required to add this to the language but as far as I can tell it's pretty straight forward? Should I write a PEP? I believe I'll need a sponsor - any takers? cheers, Jan PS if I can use a hook, I'd be very happy to hear more about how I'd go about that. It would mean I wouldn't have to wait but could possibly already start using this :-) !

On Dec 3, 2019, at 14:34, Jan Bakuwel <jan.bakuwel@gmail.com> wrote:
People focus on the silly example and suggest that the code needs refactoring but that is besides the point.
You’re the one who gave that example as motivation, and who specifically highlighted the “more than a page of code” thing; it’s not something everyone else invented and read into your example. If that example is a bad argument for your proposal, the burden of coming up with a good argument for your proposal is on you. (After all, the default for any proposal is to not change anything.) If there are “plenty use cases”, provide one that isn’t silly instead of one that is. While you’re at it, you might want to show some other languages. I think part of the reaction against it comes from the languages people are familiar with. Python, Swift, Ruby, and most other languages people tout as “readable” just have a generic end or } or dedent or whatever for all blocks. So does C and all of descendants. But PHP has endfor, and pl/SQL, and sh has for/do/done… and those aren’t languages people want to use. Maybe that’s an unfair prejudice—but if so, if you can point people to better examples, it might help overcome that.

Hi Andrew, On 4/12/19 5:15 pm, Andrew Barnert wrote:
Fair enough. See below for a link to a few examples in the Ada programming language.
If that example is a bad argument for your proposal, the burden of coming up with a good argument for your proposal is on you. (After all, the default for any proposal is to not change anything.) If there are “plenty use cases”, provide one that isn’t silly instead of one that is.
Yeah, ok. I have a feeling though that even if I would provide a real-life use case that people would argue that they can read it fine without the end statements or that I should refactor the code so all blocks would easily fit on a page or that the code should not be nested deeper than X levels. It's clear that I failed to convince even a single person so it's time to drop it. Great to have this list to test the waters so to speak :-)
While you’re at it, you might want to show some other languages. I think part of the reaction against it comes from the languages people are familiar with. Python, Swift, Ruby, and most other languages people tout as “readable” just have a generic end or } or dedent or whatever for all blocks. So does C and all of descendants. But PHP has endfor, and pl/SQL, and sh has for/do/done… and those aren’t languages people want to use. Maybe that’s an unfair prejudice—but if so, if you can point people to better examples, it might help overcome that.
As mentioned, my suggestion comes from my experience with the Ada programming language. Ada even has "named loops", a really cool feature that allows you to exit an outer loop inside an inner loop by "exiting" the loop referring to it's name (https://en.wikibooks.org/wiki/Ada_Programming/Control#Loop_with_condition_at...). In my opinion, Ada is one of the most well designed programming languages aiming at reducing anomalies and thus more reliable systems. From the article on Wikipedia "For these reasons, Ada is widely used in critical systems, where any anomaly <https://en.wikipedia.org/wiki/Anomaly_in_software> might lead to very serious consequences, e.g., accidental death, injury or severe financial loss. Examples of systems where Ada is used include avionics <https://en.wikipedia.org/wiki/Avionics>, air traffic control <https://en.wikipedia.org/wiki/Air_traffic_control>, railways, banking, military and space technology." https://en.wikipedia.org/wiki/Ada_%28programming_language%29 Thanks all, for your time and engagement, it's much appreciated. regards, Jan

On Wed, Dec 4, 2019 at 7:28 PM Jan Bakuwel <jan.bakuwel@gmail.com> wrote:
It's clear that I failed to convince even a single person so it's time to drop it. Great to have this list to test the waters so to speak :-)
This is exactly why not every idea needs a PEP :) Discuss first, PEP later. ChrisA

On Wed, Dec 4, 2019, 3:31 AM Jan Bakuwel <jan.bakuwel@gmail.com> wrote:
While I am among the everybody not convinced by needing "end" constructs, I've often wanted named loops. I know approaches to this have been proposed many times, and they all have their own warts. E.g. an ad hoc pseudo code that may or may not match any previous proposal: for x in stuff as outer: for y in other_stuff as inner: ... if cond: break outer But we all manage without it.

On Wed, 4 Dec 2019 at 21:16, Anders Hovmöller <boxed@killingar.net> wrote:
I guess what is meant is this: from contextlib import suppress class Exit(BaseException): pass stuff = [10, 20, 30] other_stuff = [1, 2, 3] with suppress(Exit): for x in stuff: for y in other_stuff: print(x, y) if x + y > 21: raise Exit You can so the same with try/except: class Exit(BaseException): pass stuff = [10, 20, 30] other_stuff = [1, 2, 3] try: for x in stuff: for y in other_stuff: print(x, y) if x + y > 21: raise Exit except Exit: pass I dislike both of the above though. My suggestion would be to use a function rather than exceptions: stuff = [10, 20, 30] other_stuff = [1, 2, 3] def func(): for x in stuff: for y in other_stuff: print(x, y) if x + y > 21: return func() In this example it might seem awkward to introduce a function just for this but normally in context the function can have a more reasonable purpose and a good name and return something useful etc. -- Oscar

These are all a little bit ugly IMO. I've never written the contextlib.suppress style, but I have the others. Usually what I'll actually do is: for x in stuff: break_outer = False for y in other_stuff: do_whatever(x, y) if cond: break_outer = True break if break_outer: break I think this is also ugly noise, but it feels like less of a cognitive load than Oscar's approaches. On Wed, Dec 4, 2019 at 5:56 PM Oscar Benjamin <oscar.j.benjamin@gmail.com> wrote:
-- Keeping medicines from the bloodstreams of the sick; food from the bellies of the hungry; books from the hands of the uneducated; technology from the underdeveloped; and putting advocates of freedom in prisons. Intellectual property is to the 21st century what the slave trade was to the 16th.

On Dec 4, 2019, at 14:56, Oscar Benjamin <oscar.j.benjamin@gmail.com> wrote:
I think the majority of the time, refactoring it into a function actually makes it better, or at least neutral. The problem is that occasionally it really does make it significantly worse, and that’s when you really wish named break existed. But I think two people already said that’s about once/year for them? That sounds about right to me, too.

On Dec 4, 2019, at 12:14, Mike Miller <python-ideas@mgmiller.net> wrote:
If you want to change this from an aside to a real proposal, it’s probably worth starting a new thread (and providing a real-life use case—if we all run into it once a year, many people probably won’t remember exactly what it looked like when they last ran into it, and how much their workaround bothered them).

Actually, I found it's rejected PEP: https://www.python.org/dev/peps/pep-3136/. It looks like the first of several ideas there matches my ad hoc syntax. It *was* 2007, in distant pre-walrus memory. But I'm not sure the SC would revisit Guido's ruling. On Wed, Dec 4, 2019, 6:45 PM Andrew Barnert via Python-ideas < python-ideas@python.org> wrote:

On Dec 4, 2019, at 16:04, David Mertz <mertz@gnosis.cx> wrote:
Given that the PEP was incomplete (no implementation strategy, no argument for one of the options over the others), that its rationale had a lot of incorrect statements (like claiming that C, C++, and Ruby all have labeled break when none of them do, and C++ had recently rejected the idea), and that there’s no motivating example, maybe you could argue for a better version of the proposal to be reconsidered. On the other hand, except maybe for the last point, Guido already dismissed all of that and instead rejected it just because “code so complicated to require this feature is very rare”, and I don’t think you can really argue against that. (I mean, if you found tons of examples of stdlib and github code that could be improved by labeled break, that would actually constitute a good argument, but I don’t think it’s likely that you could find that much.)

On 5/12/19 1:03 pm, David Mertz wrote:
Whoops, didn't realise my remark let this discussion continue in a different direction :-) Just read Guido's reason for rejecting named loops, interesting. It seems we have different ideas about what "code clarity" means and that's perfectly fine of course. Beauty is in the eye of the beholder. To refer once again to Ada (sorry), that language was explicitly designed taking core software engineering principles and various issues with existing languages into account to create "the perfect language" for systems that must not fail (if we can help it). I like systems that don't fail :-). Various key elements are covered, such as readability and predictability. In other words, everything in that language is geared towards that, including named loops. But I digress. Regarding those named loops, I do get across that from time to time (not every month) but don't think that it only occurs in complicated code. I also don't see how it can be "abused". So far when I used it, it was the most elegant way to leave an inner loop. If one can have nested loops then, I think, one should be able to break or continue out of any of those loops without having to resort to yet another single use function that has no other purpose. Raising an exception is an obvious alternative but I've learned that exceptions are expensive. If that's not the case in Python, I'll have to unlearn that :-) Where it comes to the far reaching effects of such a change I'll have to respectfully bow my head and follow the lead of those who know. Guido brings up the topic of using goto (bad) and return (good) in his rejection. I've seen multiple returns in Python functions. I think that is a bad idea; a goto would be better than multiple returns as it results in more predictive behaviour and facilitates having only one clean "exit" point of the function. Compilers (or in case of Python: smart IDEs) can then help find errors in logic that otherwise would only surface at runtime. Don't get me wrong though... I've never needed a goto since I stopped using Basic a few centuries ago. It's easy to avoid. But multiple returns should, following the same logic, ideally not be supported by the language as code using those will be less clear than code that doesn't. cheers, Jan

On Dec 4, 2019, at 17:55, Jan Bakuwel <jan.bakuwel@gmail.com> wrote:
Just read Guido's reason for rejecting named loops, interesting. It seems we have different ideas about what "code clarity" means and that's perfectly fine of course. Beauty is in the eye of the beholder. To refer once again to Ada (sorry), that language was explicitly designed taking core software engineering principles and various issues with existing languages into account to create "the perfect language" for systems that must not fail (if we can help it)
Note that it was designed taking core software engineering principles of the 1970s and the distinct languages of the 1970s into account to create “the perfect Pascal”. A lot has changed in the nearly 40 years since the report was published. For just two examples: The notion of what a type system can do has been vastly extended, meaning that Haskell and Rust and Swift can prevent all kinds of errors that nobody believed could possibly be prevented in 1980. And advances in multithreading have opened a whole new class of problems that nobody could have even imagined, much less tried to solve, in 1980, so Go and Java have tools to verify lock-free behavior; Ada does not.
Regarding those named loops, I do get across that from time to time (not every month) but don't think that it only occurs in complicated code. I also don't see how it can be "abused". So far when I used it, it was the most elegant way to leave an inner loop. If one can have nested loops then, I think, one should be able to break or continue out of any of those loops without having to resort to yet another single use function that has no other purpose. Raising an exception is an obvious alternative but I've learned that exceptions are expensive. If that's not the case in Python, I'll have to unlearn that :-)
Yes, you have to unlearn it. Exceptions are not that expensive in Python (and in a lot of other modern languages)—but even if they were, you’d still have to deal with the fact that Python uses them pervasively. Every for loop ends with an exception being thrown and caught, whether you like it or not.
Guido brings up the topic of using goto (bad) and return (good) in his rejection. I've seen multiple returns in Python functions. I think that is a bad idea; a goto would be better than multiple returns as it results in more predictive behaviour and facilitates having only one clean "exit" point of the function.
I’ve never understood this idea. The dogma comes from C, where functions usually have to do a lot of explicit cleanup at the end, which means an early return complicates that cleanup, often in really messy ways that people get wrong all the time. So it makes sense for C. But most languages are not C. Even C++ programmers quickly figured out that this doesn’t even extend to their closely-related language as long as you use it properly. But other people keep trying to extend it to languages like Python where there’s not even a “if you use it properly” condition. Storing a value in an otherwise-unnecessary variable and then making sure you correctly break out of and/or skip over all of the remaining flow control to safely arrive at the end of a function is complicated. Returning early doesn’t have those problems. And if you don’t like early return, how could you possibly like labeled break? It’s a similar goto in disguise, it means every loop now has multiple clean exit points that you have to keep track of possibly buried deep down in the nesting, it means any explicit cleanup might get skipped accidentally… if none of that is a problem for labeled break, why is any of it a problem for early return?
Compilers (or in case of Python: smart IDEs) can then help find errors in logic that otherwise would only surface at runtime.
Why do early returns make that any harder? (Other than eliminating some of the sources of those logic errors in the first place, which doesn’t seem like a bad thing.) What’s an example of a logic error that a compiler could catch without early return but can’t catch with it?

Hi Andrew, On 5/12/19 3:43 pm, Andrew Barnert wrote:
Does Python have tools to do that? I hit one of those snags a few weeks ago. Today's Ada is not the 80-ies Ada either. Fact is, it's still used for mission critical systems and for good reasons. Let me put it this way: I doubt we'll see Python used in aircraft control systems, but will happily stand corrected if I got that wrong. Ada wouldn't be used today if it would be 40 years old technology.
Regarding those named loops, I do get across that from time to time (not every month) but don't think that it only occurs in complicated code. I also don't see how it can be "abused". So far when I used it, it was the most elegant way to leave an inner loop. If one can have nested loops then, I think, one should be able to break or continue out of any of those loops without having to resort to yet another single use function that has no other purpose. Raising an exception is an obvious alternative but I've learned that exceptions are expensive. If that's not the case in Python, I'll have to unlearn that :-) Yes, you have to unlearn it. Exceptions are not that expensive in Python (and in a lot of other modern languages)—but even if they were, you’d still have to deal with the fact that Python uses them pervasively. Every for loop ends with an exception being thrown and caught, whether you like it or not.
Sweet, thanks :-) Done.
I think it's harder to understand how a function works if that function has various ways it could end instead of just one. Maybe that's just me thinking that is cleaner. What is clean is, to a certain extend, in the eye of the beholder. An example of a logic error would be where a variable is used before it's being assigned, which could be the case for one of the returns but not for the other. regards, Jan

05.12.19 04:43, Andrew Barnert via Python-ideas пише:
Yes, you have to unlearn it. Exceptions are not that expensive in Python (and in a lot of other modern languages)—but even if they were, you’d still have to deal with the fact that Python uses them pervasively. Every for loop ends with an exception being thrown and caught, whether you like it or not.
Raising and catching an exception in the C code is much cheaper than in the Python code. In Python you instantiate an exception and set its traceback, context and clause, in C you can just store several threadlocal pointers (most of them NULLs). In python you execute complex bytecode to catch an exception, in C you just read and compare few pointers in common case. StopIteration is not even raised in most case internally in the C code, it is raised only when leaked to the Python code. So exceptions are still expensive in Python, even comparing with other Python code. But outside of tight loops or if you do some input/output, they are proper tool for control flow.

My little experiments in 3.7 show exception setup is about 40% more costly than just a do-nothing loop, but execution of is about 9x more expensive than doing nothing, so actually very little cost if your loop only rarely catches the exception (I assume you'll probably actually do something inside the loop, which would reduce the proportional overhead of try-setup). no try : 0.000022s : N= 1000 : stddev=0.00000 unraised : 0.000030s : N= 1000 : stddev=0.00005 raised : 0.000180s : N= 1000 : stddev=0.00000 from tools.timethis import timethis # Dabeaz's timing tool. N = 1_000 for __ in range(1_000): with timethis("no try"): for _ in range(N): pass with timethis("unraised"): for _ in range(N): try: pass except ZeroDivisionError: pass with timethis("raised"): for _ in range(N): try: raise ZeroDivisionError except ZeroDivisionError: pass On Wed, Dec 4, 2019 at 9:22 PM Serhiy Storchaka <storchaka@gmail.com> wrote:

On 04/12/2019 23:41:19, Andrew Barnert via Python-ideas wrote:
This could lead (in complicated examples) to code would be harder to maintain than if it used named loops, but it is concise it is backward-compatible it could AFAIK be checked at compile time (for more "break"s than enclosing loops) it does not require a new keyword IMO it would handle a large majority of use cases. Rob Cliffe

Hi Chris, On 3/12/19 5:07 pm, Christopher Barker wrote:
This is a nonstarter — meaningful indentation is a pretty baked-in ( and liked ) part of the language.
I know. However why not have something that suits even more people. Meaningful indentation is great (and liked here) too... but it could be even better for those valuing that while those who do not don't have to use it.
And yes, it’s been brought up many times before on this list.
Sorry. Newbie here. If being brought up many times, implementing it would be 100% backwards compatible and those relying solely on meaningful indentation can continue to do so .... sounds like a perfect candidate for a PEP to me. Glad to hear I'm not the only one :-)
Yeah. That's I'm doing now. What I'm suggesting does not exist however. The bit that's missing is that the Python interpreter would check that and "end" matches the correct begin.
Having the interpreter check more at parse time saves a significant amount of time in more complex projects - no joke :-)

On 4/12/19 11:06 am, Jan Bakuwel wrote:
If being brought up many times, .... sounds like a perfect candidate for a PEP to me.
The implication is that it has been brought up AND REJECTED multiple times. But you do have a point -- a rejected PEP would provide documentation of the reasons against for anyone bringing it up again in the future. -- Greg

Jan Bakuwel writes:
Interesting. Has it been rejected as PEP or as an idea?
In this context "PEP" and "idea" are interchangeable, except that "ideas" aren't listed in PEP 0.
Having a list of "rejected" ideas/PEPs with the reasons why it was rejected would indeed be great to have.
The list is in PEP 0. The reasons are in the PEPs themselves.

On Dec 3, 2019, at 16:54, Jan Bakuwel <jan.bakuwel@gmail.com> wrote:
We do have a list of rejected PEPs. It’s a category in the overall list of PEPs (PEP 0). And the rejection reasons are in each PEP. Some of those rejected PEPs were even written specifically to be rejected, so there will be an answer for anyone who wonders “Why doesn’t Python do X?”, or so the next 42 times the idea comes up someone can just reply “Read PEP 789 and see if you have anything to add” instead of everyone rehashing the same arguments. There is no list of all rejected _ideas_, because a lot of ideas aren’t worth the effort to write a PEP or a formal rejection notice, and because PEP 0 would probably get pretty unwieldy if it included every half-baked idea that anyone ever mentioned. Is this one worthy of a PEP? Well, if you’re willing to put in the effort to make the best case for the idea, work through all the details, gather all the relevant threads and other links, and write it, even knowing it’ll be rejected, I’ll bet a core dev would be willing to sponsor it. And those are the only criteria there are for writing a PEP and adding it to the index. And if this idea has come up and been shot down many times over the decades, it doesn’t seem like it would be wasted effort to me. But if you’re not ready to give up on the idea yet, I wouldn’t focus on a PEP yet. I suspect that if you can’t get enough traction on -ideas, where you can directly respond to objections and refine your positive case, a frozen document is probably less likely to convince people. Plus, once it’s rejected, that’s … not quite final (I think ideas from rejected PEPs have been revived; I think the @ operator is an example?), but at least a lot more final.

On 4/12/19 1:51 pm, Jan Bakuwel wrote:
Has it been rejected as PEP or as an idea?
There has never been a PEP on it as far as I remember. Probably because it always gets shot down before it gets anywhere near that stage. One of the probable reasons for that is summed up by "preferably only one obvious way to do it". Python doesn't generally go out of its way to provide alternative ways of writing things. You say that it would be optional, so people who don't want to use it could ignore it. But you can't ignore it if you're reading or maintaining code written by someone else who uses it. Every "optional" feature has a cost to the whole community. - Greg
participants (17)
-
Anders Hovmöller
-
Andrew Barnert
-
Chris Angelico
-
Christopher Barker
-
David Mertz
-
Eric Fahlgren
-
Greg Ewing
-
Guido van Rossum
-
J. Pic
-
Jan Bakuwel
-
Mike Miller
-
Neil Girdhar
-
Oscar Benjamin
-
Rob Cliffe
-
Serhiy Storchaka
-
Soni L.
-
Stephen J. Turnbull