QB64 Phoenix Edition
Use LOOPs to avoid excessive RETURNs - Printable Version

+- QB64 Phoenix Edition (https://staging.qb64phoenix.com)
+-- Forum: Chatting and Socializing (https://staging.qb64phoenix.com/forumdisplay.php?fid=11)
+--- Forum: General Discussion (https://staging.qb64phoenix.com/forumdisplay.php?fid=2)
+--- Thread: Use LOOPs to avoid excessive RETURNs (/showthread.php?tid=879)



Use LOOPs to avoid excessive RETURNs - Pete - 09-12-2022

Just another in my huge line of tech tips to share with the growing Phoenix community. If you enjoy this coding tip, please feel free to use the code by donating to my GOFORKME page.

Okay, so have you ever used a GOSUB routine that goes on forever, but under several conditions needs to be exited early? If so, maybe you just added several RETURN statements after said conditions. That can get messy in a hurry, and it might be hard to debug when you are searching RETURN and trying to figure out where those RETURNs return to. So for all you tired of being pasta coders out there, here is my 5-cent solution. (Lucy would be so proud....)

Instead of...

Code: (Select All)
GOSUB pete
END

Pete:
bigger_1 = 1 + 1
IF STEVE = funny_looking THEN RETURN
IF ROSES THEN VIOLETS = blue ELSE RETURN
' Blah... Blah... Blah...
PRINT "My GOFORKME page is going viral!"
IF youvehadenough THEN RETURN
LOCATE somewhere, better
RETURN

We could code it this way...

Code: (Select All)
GOSUB Pete
END

Pete:
DO
    bigger_1 = 1 + 1
    IF STEVE = funny_looking THEN EXIT DO
    IF ROSES THEN VIOLETS = blue ELSE EXIT DO
    ' Blah... Blah... Blah...
    PRINT "My GOFORKME page is going viral!"
    IF youvehadenough THEN EXIT DO
    LOCATE somewhere, better
    EXIT DO
LOOP
RETURN


Tune in NEXT time for my second tech tip: DO AND WHILE can be my pal, but NEXT will never hurt me.

Pete Big Grin


RE: Use LOOPs to avoid excessive RETURNs - mnrvovrfc - 09-12-2022

This tip is good. I would add a comment on the line with "DO" that it will execute once on purpose. Either that, or "DO" or "LOOP" having "UNTIL 1" or "WHILE 0" after it and without the obligatory "EXIT DO" as the last statement controlled by the so-called loop.

While QB64 lacked "_CONTINUE" I learned a valuable tip on the Wiki page for "DO... LOOP" to emulate it. I had written a "preprocessor" having a few invented keywords, put in functionality like "_CONTINUE" that was translated into "IF condition THEN GOTO CONTINUE001" but it didn't work very well because it made a few assumptions. I abandoned my "preprocessor" after I discovered the tip on Wiki.


RE: Use LOOPs to avoid excessive RETURNs - Pete - 09-12-2022

(09-12-2022, 05:06 PM)mnrvovrfc Wrote: This tip is good. I would add a comment on the line with "DO" that it will execute once on purpose. Either that, or "DO" or "LOOP" having "UNTIL 1" or "WHILE 0" after it and without the obligatory "EXIT DO" as the last statement controlled by the so-called loop.

While QB64 lacked "_CONTINUE" I learned a valuable tip on the Wiki page for "DO... LOOP" to emulate it. I had written a "preprocessor" having a few invented keywords, put in functionality like "_CONTINUE" that was translated into "IF condition THEN GOTO CONTINUE001" but it didn't work very well because it made a few assumptions. I abandoned my "preprocessor" after I discovered the tip on Wiki.

Yes, I actually do that. My method of defining these types of container loops is pretty simple...

DO ' Falx loop.
' foo
EXIT DO
LOOP

As you also discovered, this technique and block IF/THEN statements are effective ways to avoid GOTO statements. I find only a few rare occasions in my coding structure where GOTO is the better solution, and thankfully I can usually get away with a single instance in the entire program.

Thanks for the reply,

Pete


RE: Use LOOPs to avoid excessive RETURNs - CharlieJV - 09-12-2022

Just the way I'm wired:

When I see "EXIT DO", I immediately think there must be more that needs to be done in the subroutine, and I wind up reading further into the subroutine to see what else needs to be done.  To then find out there is nothing else to be done.  And I'm left wondering: "why the heck did you make me read all the way to the end of the subroutine.?"

When I see "RETURN", I know the subroutine is done.  I need not read the rest of the code for the subroutine, and I can get back to looking at the code that brought me to the subroutine.

Regardless, very neat tip.  I do like to see how others organise their code.  Variety is the spice of life.

Keep 'em coming!


RE: Use LOOPs to avoid excessive RETURNs - Pete - 09-12-2022

(09-12-2022, 05:39 PM)CharlieJV Wrote: Just the way I'm wired:

When I see "EXIT DO", I immediately think there must be more that needs to be done in the subroutine, and I wind up reading further into the subroutine to see what else needs to be done.  To then find out there is nothing else to be done.  And I'm left wondering: "why the heck did you make me read all the way to the end of the subroutine.?"

When I see "RETURN", I know the subroutine is done.  I need not read the rest of the code for the subroutine, and I can get back to looking at the code that brought me to the subroutine.

Regardless, very neat tip.  I do like to see how others organise their code.  Variety is the spice of life.

Keep 'em coming!

@CharlieJV

Okay, here is another good reason to use the DO/LOOP method. Portability. Let's say we have a GOSUB routine we want to transition into a SUB or FUNCTION. With the DO/LOOP method, you just port it over. You only need to replace the GOSUB statement with a SUB or FUNCTION call, rename the label to the SUB or FUNCTION name, and of course, substitute END SUB or END FUNCTION instead of RETURN. Contrast that to the example I posted that used three inner RETURN statements. Each of those would have to be changed to EXIT SUB or EXIT FUNCTION, along with the other transition changes. More work, but with the DO/LOOP method, you only need to swap out one RETURN statement.

Pete

I'm always thinking, but that's because God put too many hot women on the planet.


RE: Use LOOPs to avoid excessive RETURNs - SMcNeill - 09-12-2022

Code: (Select All)
GOSUB pete
END

Pete:
bigger_1 = 1 + 1
IF (Steve <> funny_looking) OR  ROSES THEN
    VIOLETS = blue
    ' Blah... Blah... Blah...
    PRINT "My GOFORKME page is going viral!"
    IF NOT youvehadenough THEN  LOCATE somewhere, better
END IF
RETURN

And the above is how Steve does the exact same thing without being goofy like Pete. Wink


RE: Use LOOPs to avoid excessive RETURNs - Pete - 09-12-2022

Steve, I could not get your example to work. I was unable to find even one single condition in which: STEVE <> funny_looking

Pete Big Grin


RE: Use LOOPs to avoid excessive RETURNs - SMcNeill - 09-12-2022

That's cause you've only seen me with my clown nose on after giggling your wife... Big Grin


RE: Use LOOPs to avoid excessive RETURNs - Pete - 09-12-2022

Okay, spoofing aside, let's compare some pros and cons.

Pros - Pete's method:
Speed: Early exiting is faster.
Simplicity: Easier to write and read the condition statements.
Errors: No need to contemplate how to handle more complicated conditional statements where one statement might corrupt an upcoming statement. (ELSEIF and SELECT CASE also help when this is a factor).

Cons - Steve's method:
Steve came up with it. Big Grin

Well I do applaud anyone who can think through the logic of multiple conditional statements. That's a valuable skill set to have. I used to be more like that, but I would add so much to my routines overtime, I found myself too caught up with debugging how any new introduced condition would affect the existing routine.

Pete