breaking out of if statements?

All things techie, be they discussions on troubleshooting, video encoding, programming, or algorithm design.

Moderator: Nuxius

breaking out of if statements?

Postby TerraFrost » Thu Jan 19, 2006 12:44 am

I'm sure everyone knows how to break out of a loop.

Code: Select all
for ($i=0;$i<100;$i++)
{
   echo "$i<br />\n";
   if ($i == 10)
   {
      break;
   }
}

or...
Code: Select all
for ($i=0;$i<10;$i++)
{
   echo $i;
   continue;
   echo "<br />\n";
}

as examples.

But what about an if statement? eg.

Code: Select all
if (true)
{
   echo '1';
   break;
   echo '2';
}

PHP doesn't support it. In fact, I don't think Java, JavaScript, or anything else, for that matter, would. This makes me wonder... why? Languages are begining not to support goto because it's considered harmful. Is breaking out of if statements seen as being similar to a goto? If so, then what about breaking out of for loops? Why isn't that seen as being similar to a goto, either?

If anyone has any thoughts, I'd be interested in hearing 'em. Or, if someone wants to test breaking out of an if statement in another programming language, I'd like to hear the results! :)
TerraFrost
Legendary Guard
 
Posts: 12357
Joined: Wed Dec 04, 2002 6:37 am

Postby Gigafrost » Thu Jan 19, 2006 3:40 pm

Here at work we use short circuiting all the time (early returns, breaks and continues in loops.)

In general, the reason they're good is that you can (usually) avoid code with huge if_else blocks (IE, you have to scroll really far away from the if statement to see what happens when the condition fails, or to even see that there is an else in te first palce) and reduce nesting too deeply. The overall goal would be to make the code easier to read. Imagine:

Code: Select all
for(int i = 0; i < [somenum]; i++) {
  if ([condition 1]) {
    [do some stuff]
    if ([condition 2]) {
      [do some more stuff]
      if ([condition 3]) {
        [do some stuff 3]
      }
   } else {
      [else stuff]
   }
  } else {
    [else stuff 2]
  }
}


Same logic using short circuiting:

Code: Select all
for(int i = 0; i < [somenum]; i++) {

  if (![condition 1]) {
    [else stuff 2]
    continue;
  }

  [do some stuff]

  if (![condition 2]) {
    [else stuff]
    continue;
  }

  [do some more stuff]

  if ([condition 3]) {
    [do some stuff 3]
  }
}


Notice that ifs are no longer nested and that I was also able to put spaces between the logic, grouping them together in a way that makes it a bit more readable. This is a coding style that I've learned about since I started working. I think it makes the code a lot easier to read and understand.

Breaks could be useful if you're only looking for a specific entry. Otherwise, you could be constructing complicated while loops or nesting IFs deeper, maybe even adding variables or arbitrarily changing loop variables all to do the same thing you could do with a simple break. Although I guess I can't recall having seen it come up a lot.

So, given those uses of the current short circuiting commands, I'd guess that the reason break isn't used to jump out of an IF statement is because either

1) Like in your example, you'd only be skipping code that would never be executed, so then there'd really be no point, or...

2) It'd be useful if you were nesting IFs deeply, but the other short circuiting ideas are there to try and reduce that sort of stuff in the first place.

So, I can see some use for a break; in an if, but I suppose I can see why people wouldn't particularly want it in...
User avatar
Gigafrost
Frost Weapon
Frost Weapon
 
Posts: 4900
Joined: Wed Dec 04, 2002 5:09 pm
Location: Here

Postby TerraFrost » Fri Jan 20, 2006 11:10 pm

Gigafrost wrote:Here at work we use short circuiting all the time (early returns, breaks and continues in loops.)

I was under the impression that short circuting worked more like this:

Code: Select all
if (function_exists('preg_match') && preg_match('#...#',...)) {
...
}

In this example, preg_match will only be called if it exists. If it doesn't, then no errors will be returned, when normally, they would be.

So, given those uses of the current short circuiting commands, I'd guess that the reason break isn't used to jump out of an IF statement is because either

1) Like in your example, you'd only be skipping code that would never be executed, so then there'd really be no point, or...

2) It'd be useful if you were nesting IFs deeply, but the other short circuiting ideas are there to try and reduce that sort of stuff in the first place.

So, I can see some use for a break; in an if, but I suppose I can see why people wouldn't particularly want it in...

The idea of doing a break within an if actually came to me while writting a SOCKS5 client. Basically, you connect, and for each packet you send, reject if the full length of the packet wasn't written, and reject if certain things aren't the way they ought to be, as per the official spec. ie.

Code: Select all
if ($fsock = fsockopen($address,$port,$errno,$errstr,1))
{
   $request = "\5\1\0";
   if (fputs($fsock,$request) != strlen($request))
   {
      fclose($fsock);
      update_status();
   }

   $response = fgets($fsock, 3);
   if (strlen($response) != 2 && substr($response,0,2) != "\5\0")
   {
      fclose($fsock);
      update_status();
   }

   $request = "\5\1\0\1".$dest_addr.$dest_port;
   if (fputs($fsock,$request) != strlen($request))
   {
      fclose($fsock);
      update_status();
   }

   // the response length can be up to 22 bytes long
   $response = fgets($fsock,23);
   if (substr($response,0,2) != "\5\0")
   {
      fclose($fsock);
      update_status();
   }
}

As is, update_status quits the script. Something that I thought would have been nice to do, though, is to have them all sorta fall through with a break when an error takes place. That doesn't seem all that hard to read to me.

Now, I suppose I could have had all the requests be in an array and could have itereated through the array with a for loop, but then testing the length and the contents wouldn't be so easy. I mean, I can sorta envision something, off hand, but once implemented, I don't think it'd be as easy to read as the above. Atleast imho.

Thinking about it, though, a potential problem I see with breaks for if statements is... which if statement is to be broken?

Say you have something like...

Code: Select all
if (...)
{
   ...
   if (...)
      break;
}

Do you break out of the innermost if or the outermost? I suppose a rule could be made where the if that the current if is within is the one that is broken out of or where breaks are ignored until the next statement ceases to be a break, but that could get a little confussing. To elaborate on the last idea... say you had two consecutive breaks. The first one could break out of the innermost loop and the next one could break out of the next innermost loop. The process would repeat - the breaks would continue to be read and processed - until you get to a point where there are no more breaks.
TerraFrost
Legendary Guard
 
Posts: 12357
Joined: Wed Dec 04, 2002 6:37 am

Postby Gigafrost » Mon Jan 23, 2006 11:29 pm

It's possible that it's not a very wide spread use of the word. At this point I suppose it's also possible that I simply don't remember the term we use (but I don't remember.) But, the concept is still the same; skip over a knowable amount of code... GOTOs that don't result in spaghetti code...

Another smaller problem with using "break" in an if is that you wouldn't be able to use it non-trivially in a loop. Although it really is a small problem because you could just use a different keyword...
User avatar
Gigafrost
Frost Weapon
Frost Weapon
 
Posts: 4900
Joined: Wed Dec 04, 2002 5:09 pm
Location: Here


Return to Communications Center

Who is online

Users browsing this forum: No registered users and 0 guests

cron