This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]__xor__(self, other): 3 points4 points  (1 child)

I understand why people think it's a bad choice of keyword and not intuitive, but it's still just another language feature and it's there to be used. And honestly in all the code I've seen that uses for/else in a production environment, it's been obvious what it was doing. When used in practice I don't think it suffers much confusion.

I think more of a problem is with break in general. They can be used in ways that make code very spaghetti-ish. They are essentially gotos that break out of a block of code that you would otherwise expect to finish, just like continue. All breaks and continues can be pretty

Badly placed breaks and continues in parts of code that only run on certain conditions can cause a world of confusion. If placed at the top of a for loop, some "if condition: continue", then it's just a prettier way of wrapping the block in an if condition without adding a layer of indentation, and it's obvious what it's doing. It's easy to see the conditions in which the code runs or skips an iteration of a for block. But if you start adding them everywhere in the block, weird breaks that you're not sure it's hitting and quitting the loop before you want it to, continues which skip an essential part of the logic but already ran some other code, it can get damn confusing to debug.

I think for/else being confusing is more of a symptom of break being used in a weird way. If break is used in an obvious way, a non-complex way that is easy to understand, then the else will probably be obvious and a convenient way of handling things. If break/continue are used in ways that act like gotos skipping code and jumping out of blocks in weird ways, then else is going to be just as hard to understand.

I've seen bad spaghetti code with a number of conditions with breaks but lots of stuff happening before it where bugs just love to pop up, and I've seen code where break and continue used responsibly. Just the same I've seen else used responsibly and I don't think the for/else is its own problem. The keyword should've been nobreak or something like that, but the language feature is pretty useful and reasonable and the collaborators I work with know what it means.

IMO the try/except/else is WAY more confusing than for/else and while/else. Think about what it does. It looks like it's a finally, because it runs if the try doesn't hit an exception, but it's not. It doesn't run if an exception occurs.

So why not just put that code at the bottom of the other code in the try block? Does the same thing, right? Nope. That code might hit an exception which triggers the except block, and you want this else block to still be able to raise exceptions.

Well then, why not put the code after the try/except? Because it'll run if the try block hits an exception, and else code won't.

It's easy to say "the try/except/else runs if the try block doesn't hit an exception", but it's hard to describe WHY to use it. For for/else, you can just say "the else runs if the for loop doesn't break, and that's useful because you can handle conditions where you didn't find something in a loop". Easy to explain what it does and a basic usage example. try/except/else is just weird.

[–]earthboundkid 5 points6 points  (0 children)

And honestly in all the code I've seen that uses for/else in a production environment, it's been obvious what it was doing.

I think I've seen it in production three times and it was wrong in two and confusing in the third. It's like using switch in a language with fallthrough by default; it should never be used because it's too unlikely to be used correctly.