Could we have a do while loop in Julia?

every block in Julia ends with end.

do
   # something
until condition

does not and will make the syntax more complicated.

do
  # something
  until condition
end

seems not much of an improvement over

while true
  # something
  condition && break
end
7 Likes

I already agreed to try while true further up in the discussion, so we really are arguing ā€œsemanticsā€ or is it syntax :grin: ? Anyway to me while true has always had the feel of a bug like a suspended anvil on a rope above just waiting for me to put a foot wrong. But I will give it the old college try - I might get to like it.

Thatā€™s not accurate, thereā€™s a list of keywords that end a block: catch else finally among them. (I canā€™t give you the source link as Iā€™m on a phone.) Conceivably, we could add until to that list in Julia v2.

1 Like

I actually copied the syntax from Juliaā€™s try-catch block. :slightly_smiling_face:

Sure, but all of these start another block, eventually requiring an end.

5 Likes

We should eliminate while and introduce

struct ChasmOfInfiniteNothingness end

Base.iterate(::ChasmOfInfiniteNothingness, _ = nothing) = (nothing, nothing)

Example:

for _ in ChasmOfInfiniteNothingness()
    x = rand()
    if x ā‰¤ 0.1
        @show x
        break
    end
end

mustā€¦ resistā€¦ makingā€¦ PR.

13 Likes

Itā€™d be a useful first project in writing macros to write a @dowhile macro

@dowhile condition 
    body 
end

would transform to

while(true)
    condvar = begin condition end
    if(condvar) break;
    body
end

Iā€™m too new to Julia to figure out how to do this, but I think itā€™d be pretty easy based on 2 minutes of reading about macros.

True but we already did that one: Could we have a do while loop in Julia? - #9 by rdeits

A library solution is not really suitable.

I still donā€™t understand the reasoning behind this, but experimenting in packages before proposing various additions to Base and the standard libraries is very common, so if you rule this possibility out from the start then you significantly lower the chances of a change like this being even considered.

Sure, you cannot extend the parser this way, but everything else is possible, particularly with macros. The best solution is to write something super useful in a nice way, package it up, and then at some point if enough people use it the proposal will speak for itself.

3 Likes

I guess Iā€™ve only been following this half-heartedly but itā€™s starting to look to me like people are suggesting things that are entirely equivalent to

while true
    # stuff here
    condition && break
end

but with slightly different syntax. I donā€™t understand why this is desirable, is the above really so bad? I appreciate the point that alternate syntax is sometimes desirable, but this seems like a case where the existing syntax is simple, elegant and general.

2 Likes

Code I write goes into production. Iā€™m pretty conservative about loading packages - they are loaded for functional need not syntactic sugar, it is not good practice (unless the syntactic sugar becomes essentially functional). Something like this is a pretty fundamental language change that should not really be done on the package level.

Itā€™s the kind of thing Iā€™d test out in a script for different use cases and leave it at that.

@dataDiver, each language has its own aesthetic, Julia is in my opinion heavily influenced by Common Lisp, and in Common Lisp macros are everywhere and you just have to like it. Keeping the base language small is a choice that makes for good extensibility.

I think a package that specifically contains a lot of common idiom macros is exacty whatā€™s needed here. Like some sort of UtilityMacros.jl

The alternative is to pour everything into the base language like Perl did, and I specifically find Julia exciting because it isnā€™t like Perl :wink:

2 Likes

I have to agree with @dlakelan, I think one of the whole points of Juliaā€™s design is the goal of first class status for user code relative to base Julia. Macros seems like a key part of that and this situation seems like an obvious place for a macro for those who really want a do while loop.

1 Like

It seems to me that

do

is exactly and completely identical to

while true

and that

until condition

is indistinguishable from

condition && break

How is it that one is more like a suspended anvil than the other?

I even think the current syntax is cleaner, and less special-case-y.

3 Likes

This is pretty much what Stefan said, but just to spell it out, I find that a surprising number of times I actually want the termination condition somewhere in the middle of the loop. Hereā€™s a random example from Base that I found immediately:

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

So Iā€™m not necessarily 100% against a do-while loop, but it seems like a lot of syntax to spend on a somewhat-arbitrary special case. In fact it doesnā€™t seem so crazy to me to entirely replace while with repeat ... end, equivalent to a while true loop. Then no condition position gets to be special. while cond is just really traditional.

Iā€™ll also add that, given the syntax we have today, writing code twice (to do one iteration outside the loop) is more of a bug factory than while true. Itā€™s all too easy to forget to update one of the copies of the code.

29 Likes

I support the idea that while true and break is not a great idea, as it does not follow the good programming practices nor clean coding.

That said, Julia main goal is to be fast. Thinking about C language for example, using a lot of breaks on long loops may lead to a slower IPC. Julia does a great job optimizing code, so we have less issues about performance here.

So in the end, we need to think about the main focus of the language: performance or clean coding.

1 Like

Funny you should say this. I searched my edition of the Robert C Martin Clean Code Collection, and found multiple examples for recommended code, eg in Appendix A (Client Based Locking):

IntegerIterator iterator = new IntegerIterator();

while (true) {
  int nextValue;
  synchronized (iterator) {
     if (!iterator.hasNext())
       break;
     nextValue = iterator.next();
  }
  doSometingWith(nextValue);
}

(sorry if the indentation was mangled with copy-paste).

4 Likes

As mentioned in my previous post, it seems to me that do until is identical to while true break. What am I missing?

2 Likes

Maybe we should remove all loops and replace them by macros, this way while is not privileged over @dountil and nobody can complain about their missing loop construct. Also, I think that is what the compiler does anyways :slight_smile:

macro repeat(body)
    quote
        @label start
        $body
        @goto start
        @label break
    end |> esc
end
macro while(cond, body)
    quote
        @label start
        if $cond
            $body
            @goto start
        end
        @label break
    end |> esc
end
macro dountil(body, cond)
...

This code is for illustration purposes only and does not work because it uses keywords,

I see that on some cases it can be useful (or the only option available), but it doesnā€™t make it easy to read. Just imagine a larger loop or multiple breaks.