Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

for-else and while-else #1289

Open
StefanKarpinski opened this Issue · 17 comments

10 participants

Stefan Karpinski Jacob Quinn Magnus Lie Hetland elextr Ivar Nesje Paulo Roberto de Oliveira Castro Mark Roberts tonyhffong Jeff Bezanson Viral B. Shah
Stefan Karpinski

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

Jeff Bezanson JeffBezanson was assigned
Jacob Quinn
Collaborator

Bump. Can this be 0.4?

Magnus Lie Hetland

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.

Stefan Karpinski

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

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.

Magnus Lie Hetland

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 ;-)

Ivar Nesje
Collaborator

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

Stefan Karpinski

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.

Paulo Roberto de Oliveira Castro

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?

Magnus Lie Hetland

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 ;-)

Mark Roberts

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

tonyhffong

using @goto will trigger a lint warning, fyi.

Ivar Nesje
Collaborator
tonyhffong

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.

Ivar Nesje
Collaborator

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!

Mark Roberts

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...)

tonyhffong

@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?

Ivar Nesje ivarne referenced this issue in tonyhffong/Lint.jl
Closed

Lint goto? #33

Ivar Nesje
Collaborator

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

Please continue the for - else discussion here.

Viral B. Shah ViralBShah removed the feature label
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.