Could we have a do while loop in Julia?

Yes of course, but sometimes the person making the PR is also stretched too thin and is happy to wait :blush:

Folks, I don’t think there’s much point in continuing this discussion. We’re not adding a do while loop—the existing loop constructs are perfectly sufficient.

16 Likes

This is interesting. When a code block like this is directly translated into an intermediary dialect or machine code, it results into two tests: one for the while instruction and another for the break condition. Most compiled languages have optimisations that deal away with the test for the while true, but in interpreted languages this should not be the case.

Could anyone clarify Julia’s behaviour in this situation? Does it generate one or two tests?

Thanks.

I am not sure I understand, but in

while true
    if ...
        break
    end
end

the true is of course optimized away and not checked as a conditional, ever.

Julia is a compiled language and uses the same optimizer as a lot of other compiled languages. There would not be a performance difference. This thread is only about what is nice for us meat bags to write.

10 Likes

One of the mentioned reasons is to avoid accidental infinite loops, not knowing where the breakpoints might be, etc.

Maybe this discussion indicates something could be done on the IDE side to indicate exit points from a loop or function. A while true loop with no break statements could be marked; when cursor is inside the loop the break statements could be underlined, etc.

1 Like

Sorry for reviving it, but against the “search” of break statements it might be helpful to have some special break statement that swaps break and condition (as was mentioned for other languages before)

while true
  #---code---
  break if x<5
  #---more code---
end

though I see that a very basic version of that is actually trivial to implement as a macro:

macro breakif(cond)
  return quote
    $(esc(cond)) && break
  end
end

Then code becomes somewhat cleaner aswell since you can search at the left end of the line:

while true
  n1 = read(f, Int32)
  totbytes -= 4
  @breakif n1 == 0
  skip(f, n1)
  totbytes -= n1
end

Of course the value of this approach depends on personal style and preference.

Another question: What about adding a new keyword loop that gets translated into while true such that people just can omit the true condition. That might help some people against their feeling of (unintended) infinite loops :smiley: (Myself included :angel:) since it states clearly that the true wasn’t just the initial setting and forgotton but indeed intended. (I don’t want to imply that anyone here forgets such stuff, but rather admit that I forget it from time to time)
Full version then would be:

loop
  n1 = read(f, Int32)
  totbytes -= 4
  @breakif n1 == 0
  skip(f, n1)
  totbytes -= n1
end

Looks very clean and fully intended to me.
EDIT: Tbh when I try to fit my mind into the “all breaking conditions inside the loop”-style, then the while true just feels cluttered somehow. Thus that might aswell be an argument to introduce a loop keyword.

Btw why Julia doesn’t translate

while cond
  #---code---
end

into

loop
  @breakif cond
  #---code---
end

in the first place? That way there really wouldn’t be any preferred style of loop! :smiley: utopian thoughts end

I find

n1 == 1 && break

much more transparent, idiomatic to Julia, and equally conscise.

I am not sure what you mean here: since while true without a break just gives an infinite loop which is never the intended construct in a real-life program, the intention is always unambiguous.

If you are a new user to Julia and miss some control flow constructs from another language, I would suggest that you should just give it some time and you will get used to it. Julia’s basic control flow is fine as it is.

1 Like
julia> see_below = true
true

julia> while see_below
           println("hi mom!")
           rand() > 0.8 && break
       end
hi mom!
hi mom!
hi mom!

julia>

:see_no_evil:

1 Like

I like the do stuff while condition loop from Python a lot myself, but I think it clashes with Julia’s end keyword in a weird way.

Unless we enforced some whitespace rules, users might start to write code that would look like

do
    <stuff>
while
    <conditions>
end

and

  1. that just looks weird to me;
  2. that blocked-version of would incentivize people a bit to write all of their conditions in one really complicated block, which I don’t think is great practice. I don’t want to have to juggle 7 conditionals, but if I have to, I’d at least like them to be nested.

Maybe we could try some syntactic sugar, just to make the intent more obvious. Like,

first
    ...
then while <condition>
    ...
end

since we aren’t using then to my knowledge yet.

A bit off-topic, but I sometimes wish I could leave out the loop variable in for loops, such as

for 1:5
    println("Hello!")
end

or

[rand(4, 5) for 1:10]

Now, I need some dummy variable:

[rand(4, 5) for _ in 1:10]

Regarding the transparency, I get your point for your case. But in a case like that one:
image
from string search, it becomes more difficult or at least highly dependant upon syntax highlighting. I overlooked the first return as it is somewhat in mid of line. I’m not at all arguing for do..while loops but rather for some cleaner indication of breaking or return points within the loops. That’s why I like the idea of better highlighting of such statements in the editor.
Same code but different highlighting:

    while true
        i = findnext(isequal(t1),s,i)
        if i === nothing return 0 end
        ii = nextind(s, i)
        a = Iterators.Stateful(trest)
        matched = all(splat(==), zip(SubString(s, ii), a))
        (isempty(a) && matched) && return i
        i = ii
    end

There I can see the return points easier because these are almost the only ones that are highlight at all.
Especially for long lines or large loop bodies it can become quite hard to see all escape conditions. Thus some visual support would be appreciated. this can both be done by additional editor features aswell as having some macro that somewhat moves the escape keyword to the front of the line.

foreach(x->println("Hello!"), 1:5)
map(x->rand(4,5), 1:10)

felt way more useful when I began writing this. Well, at the end it just shifts the unnecessary variable to the definition of a constant functor…

See: A for loop where the counter isn't used

1 Like

I always found Ruby’s 5.times { ... } syntax cute. We could do something like times(5) do ... end, but the word times leaves something to be desired.

Thanks, but… meh :wink:

I read the issue now. Too bad, I think it would be a big improvement, especially in comprehensions. Also, it seemed more like a generalization than genuinely new syntax. A bit like how you can have function (args...) without a name. An anonymous loop, if you will.

Oh well.

In the code/screenshot you link on Github, AFAIK it is highlighted the same as in Atom:

so perhaps you can open an issue there to make return and some other keywords bold (if that is feasible, I don’t know the details).