DEV Community

Bill Schneider
Bill Schneider

Posted on

Readability with break statements

There is a widespread belief that break and continue statements are a bad programming practice. See this StackOverflow thread for an discussion. They can make code less readable if they make the intent less clear. In some cases, though, I believe they are actually better than the alternatives and can improve readability.

Here's a recent example from working with AWS in Python.

ssm = boto3.client("ssm")
response = ssm.send_command(...)
command_id = response["Command"]["CommandId"]
while True:
  invocation = ssm.get_command_invocation(... command_id ...)
  if invocation['Status'] not in ['Pending', 'InProgress']
    break
  time.sleep(5)

This code sends a command to AWS SSM, and gets the status of the invocation in a loop, exiting when completed. It will also pause before retrying.

Note that the only way to terminate this loop is the break statement.

I thought of a few alternatives to avoid a break but actually like them less.

One option is to bootstrap an initial request outside the loop, so you can include the status directly on the while condition:

invocation = ssm.get_command_invocation(... command_id ...)
while invocation['Status'] not in ['Pending', 'InProgress']:
  time.sleep(5)
  invocation = ssm.get_command_invocation(... command_id ...)

I don't like this as much because of the duplication.

Another way to address this is by using a flag to indicate completion:

done = False
while not done:
  invocation = ssm.get_command_invocation(... command_id ...)
  done = invocation['Status'] not in ['Pending', 'InProgress']
  time.sleep(5)

No duplication here, but the flag variable is extra clutter, and is not really that much more readable than the break version, because it's not obvious from the while statement itself what condition will cause the loop to terminate. Also, even if the loop completes on the first iteration, you still have to sleep before exiting the loop -- unless you add a break, in which case the flag is useless.

Compared to the other options, the original version with the while True / break feels like the least bad, even if that conclusion is unintuitive.

Top comments (2)

Collapse
 
bdelespierre profile image
Benjamin Delespierre • Edited

Which one would you pick?

# happy path
for value in list:
    if value in ignored:
        continue

    # do something...
Enter fullscreen mode Exit fullscreen mode
# unecessary indent & double negative
for value in list:
    if value not in ignored
        # do something
Enter fullscreen mode Exit fullscreen mode
Collapse
 
rhymes profile image
rhymes

Agreed. In this case avoiding "break" makes for less readable code.

I think the author of the SO answer is mostly saying to make them explicit, like you cloud do with "defensive" returns in a function.
return