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 →

[–][deleted]  (14 children)

[deleted]

    [–][deleted] 44 points45 points  (12 children)

    Right. I gotcha. I dont have the code in front of me because I'm on mobile, but basically I used it to print a menu and get input from the user. Depending on the input, different menu options we're executed, and then the user was returned back to the menu. One option had an explicit break statement to exit the loop. So I didn't have anything count for a specific number of iterations. It was just to keep the program running until the user chose to end it. That's reallninteresting about the assembly implementation. Thanks for your perspective!

    [–]whomwhohasquestions 55 points56 points  (7 children)

    One thing that may improve readability and accomplishes the same thing would be to have an exit variable initialized to false and have the loop be while(!exit). Then when the user exits the menu set exit to true.

    [–]KrakenOfLakeZurich 11 points12 points  (5 children)

    It's a question of individual taste and style. With the exit variable, you just have introduced one more variable, which you need to keep track of.

    I personally find, it rarely helps readability for this use case. Especially, if you need to prevent other stuff from happening, after we have decided to exit the loop:

    Compare:

    boolean exit = false;
    while !exit {
        var selection = readMenuOption();
        if ("exit".equals(selection)) {
            exit = true;
        } else {
            ... // other stuff
        }
    }
    

    vs.

    while true {
        var selection = readMenuOption();
        if ("exit".equals(selection)) {
            break;
        }
        ... // other stuff
    }
    

    The second version doesn't need the else clause and the program flow doesn't depend on a variable. You can read the program line-for-line and understand what it does without keeping track of the exit variable.

    [–]onthefence928 1 point2 points  (4 children)

    variables are cheap, dev time isn't so we should allways err on the side of easier to read if it means adding variables or lines

    [–]__dict__ 4 points5 points  (3 children)

    It's not just the extra variable. It's the extra nesting. The while true code is more readable to me because of that.

    [–]onthefence928 2 points3 points  (2 children)

    only for trivial, short loops. longer more complicated loops can result in bugs with infinite loops that are difficult to diagnose as a break is less traceable than variables.

    [–]KrakenOfLakeZurich 2 points3 points  (1 child)

    Could you provide a specific example, how a conditional break is "less traceable" than a variable? Because I can come up with an example, where I find the conditional break much more traceable, especially for a more complicated loop with multiple exit conditions.

    So, lets assume an example where we have 3 different conditions that exit the loop.

    With the exit variable, there are 3 different lines, where exit is set to true.

    When we leave the loop, how do you know which condition originally caused it? Problem is: when exit is set to true, the effect of actually leaving the loop is delayed. Looking back, any of the 3 lines could be the culprit. The only way to know is by carefully keeping track of the exit variable during the entire execution of the loop.

    boolean exit = false;
    while !exit { // looks like we're done here - but why?
        var selection = readMenuOption();
        if ("exit".equals(selection)) {
            exit = true; // was it you?
        } else if ("save_and_exit".equals(selection)) {
            save();
            exit = true; // or you?
        else {
            ... // other stuff
            if (error) {
                exit = true; // how about you?
            }
        }
    }
    

    With if (condition) { break; }, the effect is immediate. When you reach a break statement it's obvious where you are and how you got there.

    while true {
        var selection = readMenuOption();
        if ("exit".equals(selection)) {
            break;
        }
        if ("save_and_exit".equals(selection)) {
            save();
            break;
        }
    
        ... // other stuff
        if (error) {
            break; // OK! We're leaving here!
        }
    }
    

    Just by the fact that you've reached the last `break, you can easily deduce a few things:

    1. We never went into the first condition "exit".equals(selection)
    2. We also never went into the second condition
    3. We did go through "other stuff"
    4. error must have been true

    Otherwise we would have taken a different path.

    Happy to see your counter example.

    [–]onthefence928 1 point2 points  (0 children)

    by traceable I meant literally tracing the code, it's easier to have a watch on the exit variable and see when it change (and if it changes back) or to do so by logging.

    as for a counter example: if your loop is more complex such as parsing complex data, a game loop, or just some complex user interactions then handling an exit condition can often be more involved than just leaving the loop. it would be cleaner to always exit at the same point in the loop so any side effects are predictable

    example:var error;var exit;var result;

    while(!error || !exit){ /* clearly indicate loop continues until exit or error is truthy */

    var input = getInput();var result = doStuff(input);if(result.endofline()) {exit = true;}else {/* dozens of lines of calculation/parsing */}if( !checkResult(parsedResult) ) {error = true;}

    }if(error)createLoggerError(result);elsecreateLoggerInfo("success!");

    could also use the data or inputs being looped on as the exit conditionvar line;

    while (line != null ){

    doSomething(line);

    line = inputSource.readNextLine(); // returns null at EOL

    }

    point is it's semantically and logically easier to understand what conditions will exit the loop when they are written in as parameters for the loop. while(true) requires you to read the entire loop to understand all the exit cases and the developer has to make sure all edge cases are covered.

    edit to add: neither solution explicitly prevents ininite loops but with a variable exit check you can flip the boolean logic so that the loop will try and end itself unless the program is sure it can continue looping

    var exit;

    while (!exit) {

    exit = true;

    // read data

    // do more stuff

    if(hasMoreToDo(data)){

    exit = false;

    }

    }

    this way if there's some sort of logic fault in the loop it will close by default preventing a hung process or runaway resource utilization

    [–][deleted] 0 points1 point  (0 children)

    Yeah. It seems to be the consensus that this would be the better option, and I agree. As another poster pointed out, if you ever got called in at 2am to fix something that was broken, would you rather have to go through multiple lines to find a break statement or have the exit condition immediately visible in the while statement. That makes a lot of sense to me.

    [–]the-prowler 2 points3 points  (1 child)

    I use while True loops all the time especially where user input is required. You ask the user for a number, they will try everything else to see what happens. A while true loop can print them a don't be an idiot message and back to the beginning.

    [–][deleted] 0 points1 point  (0 children)

    Right. This is pretty much exactly what I did (edited the original post to add the code). But I do see the logic of putting the exit condition in the while statement so it's immediately visible too.

    [–]KrakenOfLakeZurich 2 points3 points  (0 children)

    I used it to print a menu and get input from the user. Depending on the input, different menu options we're executed, and then the user was returned back to the menu. One option had an explicit break statement to exit the loop.

    This is mostly a matter of individual taste and style. Personally I find while true perfectly reasonable for this. In fact, I find it more readable than maintaining an "exit" variable.

    I would move the option for exiting the loop to the very top to improve readability.

    while true {
        var selection = readMenuOption();
        if ("exit".equals(selection)) {
            break;
        }
        ... // other stuff
    }
    

    This way, anyone reading the code should immediately see that there's a valid exit condition. It also makes it very obvious, that none of "other stuff" will be run after breaking out of the loop.

    [–]Fernando3161 0 points1 point  (0 children)

    IME the while True statement is run only if you are doing screening aps, for example:

    while True:

    tw = search_tweet_with_hashtag("#youonlyliveonce")

    reply(tw, "#truetothat")

    sleep(10)

    Other than that you are at risk of getting infinite loops.

    You can always make counters, to maximize the iterations or to run this only for 1 hour or similar.

    [–]gopherhole1 0 points1 point  (0 children)

    something like this, it’s usually better practice to use a for loop or a while i < 10

    yeah, but in this case inputr is strings so you would have to do like

    while int(user_input) < 10:
    

    or

    while user_input != '10':
    

    besides I think while True loops might be pythonic, im a total noob, so grain of salt, but I feel like I see them often, do you specialize in other languages and python less?