Just because it isn't named in a way people find intuitive doesn't mean it isn't useful.
Just because it isn't named in a way people find intuitive doesn't mean it isn't useful.
It makes sense in the way that a language which is strongly biased to readability and consistent expectations makes sense. It is also how a language which minimizes programmer error makes sense.
For languages that refuse to remove anything, and thus suffer from unnecessary challenges, see C++.
However as far as programming is concerned, many things have been deprecated through transpilers and linters (for example "==" throws a warning in ESlint).
Cleaning up a language "makes no sense"?
Besides "could be useful" can be said for anything. Features should prove their usefulness (and in this case Guido regrets even adding it), we don't just keep them around in the off chance that they might be. That's hoarding.
It's one thing to make a change like this along with a bunch of other breaking changes, but there is no way this justifies breakage by itself.
No, I want a deprecation warning, and an eventual removal when for 4.0 lands.
>In what world does that sound like a good idea?
In a world where we don't pile crap upon crap forever, like with POSIX, X-Windows, or C++.
Everything has a cost. In maintenance, in documentation, in support, in limiting the design space or constraining further development for other reasons (performance, for example).
Nothing is truly free. Everything has to be balanced regarding costs and benefits.
"Programming languages should be designed not by piling feature on top of feature, but by removing the weaknesses and restrictions that make additional features appear necessary."
try:
import uvloop
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy)
except ImportError:
pass
Does the handler for if the try succeeds need to be in an else, separated from the success logic? try:
import uvloop
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy)
except ImportError:
pass
else:
print("well that didn't work") $ python3
>>> try:
1/0
except ZeroDivisionError:
print("exception")
else:
print("surprise")
exception
>>> try:
1/1
except ZeroDivisionError:
print("exception")
else:
print("normal")
1.0
normal
The choice of the name else is unfortunate because it's activated under the same circumstances of a then branch of an "if". Maybe its name should really be "then". That would also look like a .then of a JavaScript Promise, which would make sense nowadays and was obviously impossible to foresee back in 1991. However the name "else" makes sense if it refers to "except": it's what happens when no "except" fire. I still don't understand why it should be "else" for a "for" that succeeded: it should be a "then" there. $ python3
>>> for i in [1,2,3]:
print(i)
else:
print("completed")
1
2
3
completed
That should be a "then", but admittedly a very useless one.I agree that for the intended use case "else" is a better choice. It's like the else of the if that failed to find 2 in this code:
>>> for i in [1,2,3]:
if i == 2:
break
else:
print("we didn't find 2")
Still "else" doesn't hint much at what's going on, especially if the body of the loop is long. Maybe "nobreak" would make it immediately understandable to everybody? However in the best Python tradition I would make it very explicit, remove the feature from the language and use boolean flags. They are less compact but easier to understand than a feature that (probably) very few people know about. >>> we_found_2 = False # this is a valid assertion now
>>> for i in [1,2,3]:
if i == 2:
we_found_2 = True
break
if not we_found_2:
print("we didn't find 2")
That's also the only way to do it if there are multiple break in the loop on different conditions.print("well that's done")
Goto is considered harmful, but it's important to recognize the context of that decision rather than parroting the idea. It's not an obvious idea and if the discussion had happened today with modern languages[0] instead it's not at all obvious the same conclusions would be reached.
This write-up does a pretty fair job of translating the original paper to something more modern without a lot of bias. http://david.tribble.com/text/goto.html
[0]: Modern languages of course learned from this paper, so that's not a fair comparison. In fact golang contains a goto, but it behaves well according to Dijkstra's concerns and occasionally results in more readable code. I would be shocked if Dijkstra took any issue with go's implementation.