for-else and while-else #1289

Open
StefanKarpinski opened this Issue Sep 18, 2012 · 20 comments

Projects

None yet
Owner

Allow and else clause on for and while loops that executes if the loop never executes.

@JeffBezanson JeffBezanson was assigned Oct 9, 2012
Member
quinnj commented Jun 25, 2014

Bump. Can this be 0.4?

Contributor

I guess you've decided on this behavior—just thought I'd pipe in with an opinion. I find Python's behavior really useful here, where the else clause is executed if the loop has not been terminated early by break. The assumption is that you're looking for something, and the else clause is for if you don't find it. Maybe less seemingly logical than the suggested behavior, but I've had use for it many times, at least. In Python, it's also consistent with the else clauses when catching exceptions (try/catch/else), where the else clause is executed if there was no exception. The two seem quite analogous, and the else clause for try statements is also something I think would be really useful. I guess one could still have that even with the suggested behavior here, of course.

Owner

That Python for-else behavior has always struck me as very unintuitive, honestly. Mostly it's the name, not the functionality itself. The functionality can be emulated with gotos, but it is kind of awkward.

elextr commented Jul 12, 2014

Whilst there is nothing against this, at least in my experience the thing that is needed most often is to know if the loop was breaked (broken?) or if it completed.

But I have never found a "nice" way of specifying the required combination(s) of the three conditions, that the loop never ran, shortcut (break), or completed.

Contributor

Yeah, @StefanKarpinski, I guess it's mainly a matter of recycling keywords in Python. I think the naming is less awkward/surprising for try, though, if you see it as an alternative to the catch part. But, sure, the naming is more logical in the original feature spec. I can't recall having needed that functionality, but if it existed, I surely would ;-)

Contributor
ivarne commented Jul 13, 2014

Two different suggestions for what one rarely used syntax should mean, seems like a bad sign.

Owner

Well, one would never guess at the Python meaning without already knowing it, whereas I think the meaning of executing if the main body never executes is pretty intuitive, but yes, that's still a point.

Contributor

I know that it's a keyword not yet used on Julia, but I feel that the then keyword is more intuitive when doing what @mlhetland suggested. What do you think?

Contributor

Actually, @StefanKarpinski, I hadn't noticed there were gotos in Julia; saw them in the NEWS.mdfile for 0.3.0 now. Good enough for me—just a @goto instead of a break, and a @label instead of an else (though placed differently, of course). Better than, say, lots of Boolean flags and conditionals. Speaking of macros (and loops), would it be totally insane to adapt something like the Lisp LOOP macro for Julia? (Possibly in a separate library.) Not sure how useful it'd be. Just saw it mentioned in a (much-publicized) blog post on Julia vs Lisp, and implementing it (or something like it) sounded like fun ;-)

wizzat commented Sep 24, 2014

This is a super useful feature. Has a resolution for this been decided or is everyone going to use goto?

Member

using @goto will trigger a lint warning, fyi.

Contributor
ivarne commented Sep 25, 2014
Member

er, I thought the whole point of for-loop and while-loop is to minimize the use of goto. Julia allows goto, that's fine, lint.jl doesn't have have a big-boy assumption.

Contributor
ivarne commented Sep 25, 2014

TL;DR; I think an unconditional warning about goto/label belongs in a style checker, not in a linter.

I thought the point of the higher level constructs was to be able to express most code in a clearer more readable way. We had a thorough discussion before adding goto and found it to be better for some usages. Wikipedia defines lint as "tools that flag suspicious usage in software", and I don't think @goto and @label quailifies as suspicious unconditionally. If you could warn just for cases where it would be trivial to rewrite to a while-loop (or other constructs), it would be great and within the scope of a linter!

wizzat commented Sep 25, 2014

I would say that people are much more likely to do something like this:

found = false
for x in 1:5
    if x == 3
        found=true
    end
end
if !found
    //error handling
end

than this:

for x in 1:5
    if x == 3
        @goto found
    end
end
//error handling
@label found

for/else and while/else are the natural and obvious solution, even if you rename the else clause. I saw a talk from a core python dev who wished they'd named "else" to be "nobreak". If we're so concerned about naming, perhaps nobreak is a good name. At least it's descriptive. (But for/else actually has a history in CS so it shouldn't really be so surprising to people...)

Member

@ivarne it's a grey area no? We judge "poor style" being one that can be prone to logical error. So where is the line between "prone to error" (lint ok) and "suspicious usage" (lint not ok)? Of course goto is not suspicious unconditionally, so are many current lint warnings, such as declaring an unused variable, dead branch, empty literal range [1:0]. This criterion seems inadequate. There's always judgment involved. Well currently it's mine, but it could be changed.

How about this, I could add lintpragma to silence the goto lint messages (btw, the current message is only at the INFO level, not at the higher WARN/ ERROR/ FATAL levels). Do you consider this meeting half-way?

@ivarne ivarne referenced this issue in tonyhffong/Lint.jl Sep 26, 2014
Closed

Lint goto? #33

Contributor
ivarne commented Sep 26, 2014

The discussion about lint and @goto might continue in tonyhffong/Lint.jl#33

Please continue the for - else discussion here.

@ViralBShah ViralBShah removed the feature label Feb 14, 2015
cossio commented Sep 12, 2016

I prefer Python's behavior too. It's the one I use most often.

Contributor
2Cubed commented Jan 11, 2017

I think the else name makes sense, when thought about in the proper context. "loop, continue if 'successfully exited' (break), else run [block]."

This feature is quite helpful in Python, and I would love to see it in Julia, as well. 🙂

Owner

But for/else actually has a history in CS so it shouldn't really be so surprising to people...

Is there actually precedent for this construct in any language besides Python?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment