Are "While(True)" Loops So Bad

Are while(true) loops so bad?

I wouldn't say it's bad - but equally I would normally at least look for an alternative.

In situations where it's the first thing I write, I almost always at least try to refactor it into something clearer. Sometimes it can't be helped (or the alternative is to have a bool variable which does nothing meaningful except indicate the end of the loop, less clearly than a break statement) but it's worth at least trying.

As an example of where it's clearer to use break than a flag, consider:

while (true)
{
doStuffNeededAtStartOfLoop();
int input = getSomeInput();
if (testCondition(input))
{
break;
}
actOnInput(input);
}

Now let's force it to use a flag:

boolean running = true;
while (running)
{
doStuffNeededAtStartOfLoop();
int input = getSomeInput();
if (testCondition(input))
{
running = false;
}
else
{
actOnInput(input);
}
}

I view the latter as more complicated to read: it's got an extra else block, the actOnInput is more indented, and if you're trying to work out what happens when testCondition returns true, you need to look carefully through the rest of the block to check that there isn't something after the else block which would occur whether running has been set to false or not.

The break statement communicates the intent more clearly, and lets the rest of the block get on with what it needs to do without worrying about earlier conditions.

Note that this is exactly the same sort of argument that people have about multiple return statements in a method. For example, if I can work out the result of a method within the first few lines (e.g. because some input is null, or empty, or zero) I find it clearer to return that answer directly than to have a variable to store the result, then a whole block of other code, and finally a return statement.

Is while (true) with break bad programming practice?

There is a discrepancy between the two examples. The first will execute the "do something" at least once every time even if the statement is never true. The second will only "do something" when the statement evaluates to true.

I think what you are looking for is a do-while loop. I 100% agree that while (true) is not a good idea because it makes it hard to maintain this code and the way you are escaping the loop is very goto esque which is considered bad practice.

Try:

do {
//do something
} while (!something);

Check your individual language documentation for the exact syntax. But look at this code, it basically does what is in the do, then checks the while portion to see if it should do it again.

Why while(true) is bad practice?

My project leader doesn't allow this kind of loop in my code, he's arguing that it has to be replaced by while(!exit_flag)

That's very debatable. while (!exit_flag) suggests that the loop has a natural exit condition which it will reach at some specific point by itself, e.g. something counting from 0 to 100 and then leaving the loop. However, if you are writing this loop to create a permanent daemon or event loop, then the point of this loop is to keep the program running indefinitely. Nothing says indefinitely better than while (true).

There's no real technical difference between both; it's just a matter of readability and expression of intent. Of course, you'll have to square this with the people who will read that code in the end. If their policy is while (!exit_flag), so be it.

Why while(true) is an infinite loop?

Given:

while (a)
{
// b
}

If a is true, then block b will execute. This will keep repeating until a is not true.

If a is replaced with the constant value true, then a will never be false so the loop will never quit.

While-Loop repeating when program reaches else-statement

You are looping the results of your display method. You are not looping over the input i.e. get username and password. The idea is that You get username -> check -> display (These 3 steps happen in 1 big loop). You are looping only over the last step i.e. display.

package test;

import java.io.File;
import java.io.FileWriter;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.Scanner;

public class testClass {

public static void main(String[] args) {
// Path path = Paths.get("/Users/Coding/Desktop/myFile.txt").toAbsolutePath();
// List<String> titles = Files.lines(path).collect(Collectors.toList());

String searchUsername = null;
String searchPassword =null;

boolean result = false;
while (!result) {
searchUsername = getUsername();
searchPassword = getPassword();
result = displayResults(searchUsername, searchPassword, null);

}
System.out.println("break");


}

private static String getUsername() {
Scanner scan = new Scanner(System.in);
System.out.print("Enter Username: ");
return scan.nextLine();
}

private static String getPassword() {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter Password: ");
return scanner.nextLine();
}

public static boolean displayResults(String searchUsername, String searchPassword, List<String> titles) {

// boolean userInFile = titles.stream().anyMatch(p -> p.equalsIgnoreCase(searchUsername));
// boolean passInFile = titles.stream().anyMatch(p -> p.equalsIgnoreCase(searchPassword));
return true; // false

}
}

Python - I need a continuous loop that will run forever, I know its bad practice but would using while True be appropriate?

A little experiment, looking at the bytecode:

>>> import dis
>>> dis.dis('while True: statement')
1 >> 0 LOAD_NAME 0 (statement)
2 POP_TOP
4 JUMP_ABSOLUTE 0 (to 0)

Doesn't even bother checking whether True is true. Just does an unconditional loop. So even the Python compiler recognizes this as something special and treats it as the most optimal thing.

For comparison, using 1 == 1 suggested elsewhere:

>>> dis.dis('while 1 == 1: statement')
1 0 LOAD_CONST 0 (1)
2 LOAD_CONST 0 (1)
4 COMPARE_OP 2 (==)
6 POP_JUMP_IF_FALSE 12 (to 24)
>> 8 LOAD_NAME 0 (statement)
10 POP_TOP
12 LOAD_CONST 0 (1)
14 LOAD_CONST 0 (1)
16 COMPARE_OP 2 (==)
18 POP_JUMP_IF_TRUE 4 (to 8)
20 LOAD_CONST 1 (None)
22 RETURN_VALUE
>> 24 LOAD_CONST 1 (None)
26 RETURN_VALUE

Look at all that stuff. Loading the values, comparing them, then testing the comparison result's truth value and jumping around conditionally.

All that said, True isn't the only value optimal in this regard:

>>> dis.dis('while 42: statement')
1 >> 0 LOAD_NAME 0 (statement)
2 POP_TOP
4 JUMP_ABSOLUTE 0 (to 0)
>>> dis.dis('while "foo": statement')
1 >> 0 LOAD_NAME 0 (statement)
2 POP_TOP
4 JUMP_ABSOLUTE 0 (to 0)
>>>

But I'd say it's additionally the clearest.

How do I add a delay in a JavaScript loop?

The setTimeout() function is non-blocking and will return immediately. Therefore your loop will iterate very quickly and it will initiate 3-second timeout triggers one after the other in quick succession. That is why your first alerts pops up after 3 seconds, and all the rest follow in succession without any delay.

You may want to use something like this instead:

var i = 1;                  //  set your counter to 1
function myLoop() { // create a loop function setTimeout(function() { // call a 3s setTimeout when the loop is called console.log('hello'); // your code here i++; // increment the counter if (i < 10) { // if the counter < 10, call the loop function myLoop(); // .. again which will trigger another } // .. setTimeout() }, 3000)}
myLoop(); // start the loop

When is a while(True) loop appropriate?

Sometimes, while(true) is more readable than the alternatives. Case in point:

BufferedReader in = ...;
while (true)
{
String line = in.readLine();
if (line == null)
break;
process(line);
}

Consider the alternative:

BufferedReader in = ...;
String line;
while ((line = in.readLine) != null)
process(line);


Related Topics



Leave a reply



Submit