LoginLogin
Nintendo shutting down 3DS + Wii U online services, see our post

Anti-Goto Sentiment Considered Harmful

Root / Site Discussion / [.]

🔒
YolkaiCreated:
well i must admit that your turn to my statement brought a laugh out of me but i do seem to realize that its not about having a brain, its about progressing at your own pace. if dev 234 wanted to make his game with a goto loop, it was his choice. i do notice you mentioned a gosub for animation? i do find that kind of outrageous and for that i share your point of view. i manage my sprite animations with a def for 4 directions and a chunk of code before the button imputs. i dont use spanim, at least not yet, but i never used goto for sprite animations.
My point is that it's so easy to learn loops that you shouldn't consciously stay with label loops.

Let's be real here, nobody is maintaining anyone else's SB code. No need to make code readable or maintainable.

No need to make code readable or maintainable.
Yeah, it's not like the person who wrote the code will ever have to revisit it after a while, ever. please do yourselves a favor and make the code readable & use comments for your own sake

It is important to write clean code. But i find that there are some who become obsessed with it. To the point where anyone using a keyword for example GOTO is a complete noob and their code is horrible becuase of using this. In truth, i like GOTO’s because they are extremely simple. They are perfect for your prototype code which requires a simple design so that you can get the bigger picture of how your code works. Most importantly, i believe that every person has their own way of programming and no one should force their way on others. Let the beginners experience programming and learn things for themselves. That is how they will learn best.

I am sorry, but using GOTO in your code when you don’t have to, IS a very loud and large klaxon ringing out that you are indeed a noob. That you need to go back and learn the basics. That you don’t know what you are doing, and that your code is automatically suspect (even if it works). I warned everyone earlier in this thread I would could make a big giant document about why GOTO is bad. Well this thread has gone on long enough, so hold on to your butts, it is a long one. Here we go. If the site wants to copy and paste this into one of those nifty pages, feel free. If I have the ability to do so myself, please let me know what links to click to do so. GOTO isn’t inherently evil in and of itself. It is nicely named and does what it says on the box. Such clarity can be nice to someone just starting out. That being said there are only a few situations where you would want to actually use it, or consider using GOTO to be OK.
  • You are coding in Assembly Language. At that point you simply don’t have the luxury of higher level constructs.
  • You are coding on an old retro system or language that does not support needed looping constructs. For example: BASIC on the Commodore 64.
  • A higher level language is compiling down to an intermediate form that is not meant to be human readable or editable. For example code generated by LEX/YACC.
  • You are in a low level language like C and need to escape from a nested loop several levels deep. (You may need to defend use in a code review for this one.)
Times when GOTO use is not acceptable.
  • Everything else, use a function or loop instead.
  • Item 1
Times when GOTO use is abhorent.
  • GOTO use is defended as a lifestyle choice
  • You are too lazy to learn available looping/function constructs in the language.
  • You maliciously teach it to new programmers as though it was a good thing to use.
The whole title of this thread is wrong headed, and I think we are all owed an apology because of it. I don’t know why it wasn’t closed months ago. If you don’t get the reference, the thread is titled after the talk “GOTO Statement Considered Harmful” by Edsger W. Dijkstra. I actually looked it up when this thread started, and I found it rather dissapointing. I expected a fiery roast of GOTO, and instead if it is only a page long and basically says you shouldn’t really use GOTO it creates code that is hard to follow. You can read it yourself at: http://www.u.arizona.edu/~rubinson/copyright_violations/Go_To_Considered_Harmful.html. After that what followed was sort of an academic snail mail version of a flame war (this is per-internet). Frank Rubin replies with ““GOTO considered harmful” considered harmful” (looks at thread title). Finally Dijkstra replies with “On a Somewhat Dissappointing Correspondence”. Rubin doesn’t seem to know how to use break or continue in a loop (maybe it wasn’t there at the time), and Dijkstra is as could be guessed disappointed by the whole back and forth. Yes, GOTO can incite flame wars in a generally unpleasant manner, and people can take one side or the other with religious fervor (myself included). Yes, you can go to stupid lengths to avoid putting GOTO in your code, and sometimes you can make cleaner code with it than by avoiding it. Ultimately however, everyone knows that Dijkstra was right, it is self-evident. Stop trying to rationalize it, GOTO is bad, and somewhere in your heart of hearts, I think you know it too. This site is generally targeted at new programmers, and teaching them GOTO instead of looping and function call syntax is a terrible thing to do to another human being. The site should officially advocate against using GOTO if only to head off some flame wars with an answer from above. If you are posting code on the site using GOTO and someone points it out, you should listen and fix it. Try to set a good example. Give those just starting out some good code to look at. There isn’t even that much syntax to learn. WHILE/WEND, REPEAT/UNTIL, FOR/NEXT, and DEF in function and subroutine styles. That’s it. There is no good reason to not use them, but there are plenty of good reasons not to use GOTO. Here is a quick question for you. Q: How do you use GOTO in Java, JavaScript, or Python? A: You don’t, because you don’t need it, and it isn’t in the language. BASIC was made back in the 60’s. The command PRINT is called PRINT because it used to actually print out text to a printer. There was no display. There was no file system. Things were very primitive. It was made about the same time as FORTRAN and COBOL. Not everything in the language is something that you should still be using. SmileBoom should have taken out GOTO and GOSUB when they took out line numbers. So, here is a little translation table for anyone still using GOTO. If your code looks like this:
I = 0
@LABEL_START:
IF I >= 10 THEN GOTO @LABEL_EXIT
PRINT I
I = I + 1
GOTO @LABEL_START
@LABEL_EXIT:
You should use a FOR loop. (That sure looks more readable to me.)
I = 0
FOR I = 0 TO 9
 PRINT I
NEXT I
If your code looks like this:
I = 0
J = 10
@LABEL_START:
IF I == J THEN GOTO @LABEL_EXIT
PRINT I
I = I + 1
GOTO @LABEL_START
@LABEL_EXIT:
Try a WHILE loop.
I = 0
J = 10
WHILE I != J
 PRINT I
 I = I + 1
WEND
If your code looks like this.
I = 0
@LABEL_START:
PRINT I
I = I + 1
IF I < 10 THEN GOTO @LABEL_START
Try a REPEAT loop.
I = 0
REPEAT
 PRINT I
 I = I + 1
UNTIL I >= 10
If you code looks like this
A = 1
B = 2
GOSUB @ADD_TWO
PRINT C
END

@ADD_TWO:
C = A + B
RETURN
Try a function
PRINT ADD_TWO(1, 2)
END

DEF ADD_TWO(A, B)
 RETURN A + B
END
And if your code looks like this.
THE_NAME$ = “BOBBY”
GOSUB @PRINT_NAME
END

@PRINT_NAME
PRINT THE_NAME$
RETURN
Try a subroutine. Note the lack of parenthesis on the parameters and no return value.
PRINT_NAME “BOBBY”
END

DEF PRINT_NAME THE_NAME$
 PRINT THE_NAME$
END
I find it hard to see any of the GOTO statement examples as easier to read or write. But there is more to it than that. After all, I use % on the end of my numeric variables, and that is uglier AND harder to write. Problems with GOTO: Tons of Line Labels are needed when you use GOTO/GOSUB. A for loop requires no line labels. You might need one or two when using GOTO. Making line labels requires that they are all distinct. You can easily run out of useful line label names and having them peppered through the code makes things harder to read. If you want to reuse code in a different file, you now need to make sure that the line labels are still unique. This is extra overhead you don’t get with looping and function call syntax. Everything is at the global scope if you are using GOTO/GOSUB. Inside of a function/subroutine, you can make variables with the same name as variables at the global level. If you want to have ten different functions that have a variable called “I” that is used as a looping index you can do it. When you reference a variable it looks first at the current scope, and if it finds it uses it. Otherwise it looks through parent scopes until it either finds one or hits the global scope. Likewise the parameters passed in don’t have to be the same name as they were at the global scope. They can be whatever you want to name them and it won’t affect code outside of the function/subroutine. So, how does scoping help? Because, now you can re-use code. If you want to take the function out of one file and put it in another you can do it without affecting anything else (assuming you aren’t accessing globals). If you wanted to try this with code that uses GOTO/GOSUB, you will have far more problems. First you have to also copy over any variables that are used as input or output. If they are already present and used by something else you are going to need to rename things in your code. You may need to rename line labels too. Since everything would be at the global scope one mistake could mean that one GOSUB call is messing up a variable used by another GOSUB call. That would be a miserable problem to find and fix. Functions can be recursive, you have to fake it with a stack if you are using GOSUB. Yes recursion is a bit of an advanced topic for new programmers, but it is still worth noting. With recursion, a function can call itself, and use the results. Each call gets its own stack frame that holds the variables for that specific call of the function. So calling a function from itself won’t break the state of the parent call. A simple example is probably factorial (yes you could easily do this in a loop, it is a simple example). If you tried doing that with GOSUB, you would run into problems unless you make your own stack manually. If you didn’t make your own stack manually, one call would stomp over top of its own variables.
DEF FACTORIAL(X)
 IF X <= 1 THEN
  RETURN 1
 ELSE
  RETURN X * FACTORIAL(X – 1)
 ENDIF
END
There are a whole host of algorithms that lend themselves nicely to recursion, and not being able to do it easily with GOTO/GOSUB is a problem, and a lot more work. GOTO/GOSUB calls can branch to literally anywhere in the code. This is really the be number one problem. If you are in a FOR, WHILE, or REPEAT loop you have well defined areas where the program can jump to. You can only jump to the top of the loop or exit the loop entirely. Even with things like CONTINUE and BREAK (which I am fine with by the way) are limited to those two points. Likewise for functions and subroutines. They have well defined entry and exit points. However, if you are using GOTO/GOSUB, you can jump to any line of code in the whole program. This property lends to the dreaded creation of “Spaghetti Code” where it is difficult to trace where code came from, and where it is going. This is an uncertainty you just don’t have with a loop, because it encourages cleaner coding. Spaghetti code leads to write-once code that can be near impossible to maintain. In a real programming environment you spend 80% of your coding time on code maintenance. Do yourself a favor and don’t make your job harder. Spaghetti code can easily crush a new programmer just getting started. You shouldn’t teach GOTO because you are making life hard for them, they will quickly burn out and can give up entirely. This isn't matter of personal style, it is a matter of maintainability and readability. GOTO doesn't scale well with code length. To make my point, below is a maze generation program from the book “Basic Computer Games” compiled by David Ahl back when computers were still new (https://www.atariarchives.org/basicgames/showpage.php?page=3). It makes extensive use of GOTO. Here are some questions about the code: Q: What algorithm is it using to generate the maze? Q: Does GOTO make the code easier to read or harder to read and understand? Q: If you wanted to modify the program how comfortable would you be trying to modify it? Or would you rather start over from scratch?
10 PRINT TAB(28);"AMAZING PROGRAM"
20 PRINT TAB(15);"CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY"
30 PRINT:PRINT:PRINT:PRINT
100 INPUT "WHAT ARE YOUR WIDTH AND LENGTH";H,V
102 IF H<>1 AND V<>1 THEN 110
104 PRINT "MEANINGLESS DIMENSIONS.  TRY AGAIN.":GOTO 100
110 DIM W(H,V),V(H,V)
120 PRINT
130 PRINT
140 PRINT
150 PRINT
160 Q=0:Z=0:X=INT(RND(1)*H+1)
165 FOR I=1 TO H
170 IF I=X THEN 173
171 PRINT ".--";:GOTO 180
173 PRINT ".  ";
180 NEXT I
190 PRINT "."
195 C=1:W(X,1)=C:C=C+1
200 R=X:S=1:GOTO 260
210 IF R<>H THEN 240
215 IF S<>V THEN 230
220 R=1:S=1:GOTO 250
230 R=1:S=S+1:GOTO 250
240 R=R+1
250 IF W(R,S)=0 THEN 210
260 IF R-1=0 THEN 530
265 IF W(R-1,S)<>0 THEN 530
270 IF S-1=0 THEN 390
280 IF W(R,S-1)<>0 THEN 390
290 IF R=H THEN 330
300 IF W(R+1,S)<>0 THEN 330
310 X=INT(RND(1)*3+1)
320 ON X GOTO 790,820,860
330 IF S<>V THEN 340
334 IF Z=1 THEN 370
338 Q=1:GOTO 350
340 IF W(R,S+1)<>0 THEN 370
350 X=INT(RND(1)*3+1)
360 ON X GOTO 790,820,910
370 X=INT(RND(1)*2+1)
380 ON X GOTO 790,820
390 IF R=H THEN 470
400 IF W(R+1,S)<>0 THEN 470
405 IF S<>V THEN 420
410 IF Z=1 THEN 450
415 Q=1:GOTO 430
420 IF W(R,S+1)<>0 THEN 450
430 X=INT(RND(1)*3+1)
440 ON X GOTO 790,860,910
450 X=INT(RND(1)*2+1)
460 ON X GOTO 790,860
470 IF S<>V THEN 490
480 IF Z=1 THEN 520
485 Q=1:GOTO 500
490 IF W(R,S+1)<>0 THEN 520
500 X=INT(RND(1)*2+1)
510 ON X GOTO 790,910
520 GOTO 790
530 IF S-1=0 THEN 670
540 IF W(R,S-1)<>0 THEN 670
545 IF R=H THEN 610
547 IF W(R+1,S)<>0 THEN 610
550 IF S<>V THEN 560
552 IF Z=1 THEN 590
554 Q=1:GOTO 570
560 IF W(R,S+1)<>0 THEN 590
570 X=INT(RND(1)*3+1)
580 ON X GOTO 820,860,910
590 X=INT(RND(1)*2+1)
600 ON X GOTO 820,860
610 IF S<>V THEN 630
620 IF Z=1 THEN 660
625 Q=1:GOTO 640
630 IF W(R,S+1)<>0 THEN 660
640 X=INT(RND(1)*2+1)
650 ON X GOTO 820,910
660 GOTO 820
670 IF R=H THEN 740
680 IF W(R+1,S)<>0 THEN 740
685 IF S<>V THEN 700
690 IF Z=1 THEN 730
695 Q=1:GOTO 830
700 IF W(R,S+1)<>0 THEN 730
710 X=INT(RND(1)*2+1)
720 ON X GOTO 860,910
730 GOTO 860
740 IF S<>V THEN 760
750 IF Z=1 THEN 780
755 Q=1:GOTO 770
760 IF W(R,S+1)<>0 THEN 780
770 GOTO 910
780 GOTO 1000
790 W(R-1,S)=C
800 C=C+1:V(R-1,S)=2:R=R-1
810 IF C=H*V+1 THEN 1010
815 Q=0:GOTO 260
820 W(R,S-1)=C
830 C=C+1
840 V(R,S-1)=1:S=S-1:IF C=H*V+1 THEN 1010
850 Q=0:GOTO 260
860 W(R+1,S)=C
870 C=C+1:IF V(R,S)=0 THEN 880
875 V(R,S)=3:GOTO 890
880 V(R,S)=2
890 R=R+1
900 IF C=H*V+1 THEN 1010
905 GOTO 530
910 IF Q=1 THEN 960
920 W(R,S+1)=C:C=C+1:IF V(R,S)=0 THEN 940
930 V(R,S)=3:GOTO 950
940 V(R,S)=1
950 S=S+1:IF C=H*V+1 THEN 1010
955 GOTO 260
960 Z=1
970 IF V(R,S)=0 THEN 980
975 V(R,S)=3:Q=0:GOTO 1000
980 V(R,S)=1:Q=0:R=1:S=1:GOTO 250
1000 GOTO 210
1010 FOR J=1 TO V
1011 PRINT "I";
1012 FOR I=1 TO H
1013 IF V(I,J)<2 THEN 1030
1020 PRINT "   ";
1021 GOTO 1040
1030 PRINT "  I";
1040 NEXT I
1041 PRINT
1043 FOR I=1 TO H
1045 IF V(I,J)=0 THEN 1060
1050 IF V(I,J)=2 THEN 1060
1051 PRINT ":  ";
1052 GOTO 1070
1060 PRINT ":--";
1070 NEXT I
1071 PRINT "."
1072 NEXT J
1073 END
And here is my implementation of a maze generation program in SmileBasic. It is has a game loop added and is longer, but I still say it is much easier to read, modify, and learn from than the first one. Would you rather modify my code, or the one with GOTOs in it? Or do you have trouble with both? (yes, I know everyone hates the %’s on variable names, I just like specifying my data types when possible). If you skip the game loop, they are actually about the same length (that would be the line PRINT_MAZE starts on). (I manually typed this up, there may be a few bugs because of that.)
OPTION STRICT

VAR LEVEL%
FOR LEVEL% = 1 TO 3
 VAR WIDTH% = 49
 VAR HEIGHT% = 27
 DIM MAZE%[0, 0]

 MAZE% = GENERATE_MAZE(WIDTH%, HEIGHT%)
 
 VAR START_X%, START_Y%
 VAR EXIT_X%, EXIT_Y%

 START_Y% = 1
 REPEAT
  START_X% = RND(WIDTH%)
 UNTIL MAZE%[START_X%, START_Y%] == 0

 EXIT_Y% = HEIGHT% - 2
 REPEAT
  EXIT_X% = RND(WIDTH%)
 UNTIL MAZE%[EXIT_X%, EXIT_Y%] == 0

 PRINT_MAZE% MAZE%, WIDTH%, HEIGHT%, START_X%, START_Y%, EXIT_X%, EXIT_Y%

 VAR BTN%

 REPEAT
  BTN% = BUTTON()
  IF BTN% AND #UP THEN
   IF START_Y% >= 1 AND MAZE%[START_X%, START_Y% - 1] == 0 THEN
    MOVE_GUY START_X%, START_Y%, START_X%, START_Y% - 1
    START_Y% = START_Y% - 1
   ELSE
    BEEP 23
   ENDIF
  ELSEIF BTN% AND #DOWN THEN
   IF START_Y% < HEIGHT% - 1 AND MAZE%[START_X%, START_Y% + 1] == 0 THEN
    MOVE_GUY START_X%, START_Y%, START_X%, START_Y% + 1
    START_Y% = START_Y% + 1
   ELSE
    BEEP 23
   ENDIF
  ELSEIF BTN% AND #LEFT THEN
   IF START_X% >= 1 AND MAZE%[START_X% - 1, START_Y%] == 0 THEN
    MOVE_GUY START_X%, START_Y%, START_X% - 1, START_Y%
    START_X% = START_X% - 1
   ELSE
    BEEP 23
   ENDIF 
  ELSEIF BTN% AND #RIGHT THEN
   IF START_X% < WIDTH% - 1 AND MAZE%[START_X% + 1, START_Y%] == 0 THEN
    MOVE_GUY START_X%, START_Y%, START_X% + 1, START_Y%
    START_X% = START_X% + 1
   ELSE
    BEEP 23
   ENDIF
  ENDIF
 UNTIL START_X% == EXIT_X% AND START_Y == EXIT_Y%
NEXT LEVEL%
CLS
PRINT "YOU WIN"
END

DEF MOVE_GUY OLD_X%, OLD_Y%, NEW_X%, NEW_Y%
 COLOR #TWHITE, #TBLACK
 LOCATE OLD_X%, OLD_Y% + 1
 PRINT " ";
 COLOR #TCYAN, #TBLACK
 LOCATE NEW_X%, NEW_Y% + 1
 PRINT "O";
 COLOR #TWHITE, #TBLACK
END

DEF PRINT_MAZE MAZE%, WIDTH%, HEIGHT%, START_X%, START_Y%, EXIT_X%, EXIT_Y%
 VAR X%
 VAR Y%
 
 LOCATE 0, 0
 COLOR #TWHITE, #TBLACK
 PRINT "LEVEL: " + STR$(LEVEL%)
 ‘PRINT THE MAZE OUT

 FOR Y% = 0 TO HEIGHT% - 1
  FOR X% = 0 TO WIDTH% - 1
   IF MAZE%[X%, Y%] == 0 THEN
    IF X% == START_X% AND Y% == START_Y% THEN
     COLOR #TCYAN
     PRINT "O";
    ELSEIF X% == EXIT_X% AND Y% == EXIT_Y% THEN
     COLOR #TYELLOW
     PRINT "X";
    ELSE
     PRINT " ";
    ENDIF
   ELSE
    COLOR #TRED
    PRINT "M";
   ENDIF
  NEXT X%
  PRINT
 NEXT Y%
 COLOR #TWHITE, #TBLACK
END

DEF GENERATE_MAZE(WIDTH%, HEIGHT%)
 VAR H%
 VAR W%
 VAR CELL_W%
 VAR CELL_H%
 VAR STACK_X%[0]
 VAR STACK_Y%[0]
 DIM VISIT%[4]
 VAR X%, Y%
 VAR START_X%, START_Y%
 VAR DIR%
 VAR I%, J%
 VAR UNVISITED%
 CELL_W% = CEIL((WIDTH% - 1) / 2)
 CELL_H% = CEIL((HEIGHT% - 1) / 2)
 W% = (CELL_W% * 2) + 1
 H% = (CELL_H% * 2) + 1
 DIM MAZE%[W%, H%]
 FILL MAZE%, 1

 Y% = 0
 X% = RND(CELL_W%)
 START_X% = X% * 2 + 1
 START_Y% = Y% * 2 + 1
 UNVISITED% = CELL_W% * CELL_H%
 MAZE%[X% * 2 + 1, Y% * 2 + 1] = 0
 UNVISITED% = UNVISITED% - 1

 WHILE UNVISITED% > 0
  DIR% = RND(4)
  VISIT%[0] = IS_VISITED(MAZE%, X%, Y% - 1, CELL_W%, CELL_H%)
  VISIT%[1] = IS_VISITED(MAZE%, X% - 1, Y%, CELL_W%, CELL_H%)
  VISIT%[2] = IS_VISITED(MAZE%, X% + 1, Y%, CELL_W%, CELL_H%)
  VISIT%[3] = IS_VISITED(MAZE%, X%, Y% + 1, CELL_W%, CELL_H%)

  IF VISIT%[0] + VISIT%[1] + VISIT%[2] + VISIT%[3] == 0 THEN
   ‘ALL NEIGHBORS VISITED BACK TRACK
   IF LEN(STACK_X%) > 0 THEN
    X% = POP(STACK_X%)
    Y% = POP(STACK_Y%)
   ELSE
    BREAK
   ENDIF
  ELSE
   ‘PICK UNVISITED NEIGHBOR
   WHILE VISIT%[DIR%] == 0
    DIR% = (DIR% + 1) MOD 4
   WEND
   
   PUSH STACK_X%, X%
   PUSH STACK_Y%, Y%

   ‘REMOVE WALL
   IF DIR% == 0 THEN
    ‘NORTH
    MAZE%[X% * 2 + 1, Y% * 2] = 0
    Y% = Y% - 1
   ELSEIF DIR% == 1 THEN
    ‘WEST
    MAZE%[X% * 2, Y% * 2 + 1] = 0
    X% = X% - 1
   ELSEIF DIR% == 2 THEN
    ‘EAST
    MAZE%[X% * 2 + 2, Y% * 2 + 1] = 0
    X% = X% + 1
   ELSE
    ‘SOUTH
    MAZE%[X% * 2 + 1, Y% * 2 + 2] = 0
    Y% = Y% + 1
   ENDIF

   MAZE[X% * 2 + 1, Y% * 2 + 1] = 0
   UNVISITED% = UNVISITED% - 1
  ENDIF
 WEND

 RETURN MAZE%

END

DEF IS_VISITED(MAZE%, X%, Y%, WIDTH%, HEIGHT%)
 VAR Z%
 IF X% >= 0 AND X% < WIDTH%  AND Y% >= 0 AND Y% < HEIGHT% THEN
  RETURN MAZE%[X% * 2 + 1, Y% * 2 + 1]
 ELSE
  RETURN 0
 ENDIF
END
Long ago, I was actually going to port the first version to SmileBasic and got fed up untangling the spaghetti code. So instead I looked up maze generation on Wikipedia and made my own. So in my case, I would have rather started over than try to make sense of the old code. Unmaintainable code may run but it isn’t very valuable. I still don’t know what algorithm the first one was using. I assume it is something different than what I chose. Here is the pseudo code I worked from. Maze generation algorithm from Wikipedia Recursive backtracker The depth-first search algorithm of maze generation is frequently implemented using backtracking:
  • 1. Make the initial cell the current cell and mark it as visited
  • 2. While there are unvisited cells
    • 1. If the current cell has any neighbours which have not been visited
        • 1. Choose randomly one of the unvisited neighbours
        • 2. Push the current cell to the stack
        • 3. Remove the wall between the current cell and the chosen cell
        • 4. Make the chosen cell the current cell and mark it as visited
      • 2. Else if stack is not empty
        • 1. Pop a cell from the stack
        • 2. Make it the current cell
Hopefully you can see the resemblance. Advocating against GOTO isn’t an obsession, it is hygiene, you need to keep your code clean. Like I said earlier in the thread, using GOTO is like using the free weights wrong at the gym. You can hurt yourself rather easily if you don’t have proper form. This can lead to medical problems like a bad back or a hernia. If a weight lifter comes up to you at the gym says your form is bad and offers to help you fix it, you should be thankful they pointed it out and let them help you. Even if it is intrusive, embarrassing or unpleasant. Likewise if you post code with GOTO in it, and someone points out your bad form, you should listen and fix it. It isn’t pleasant to point this out, it is actually fairly miserable. If I do it, it is because I am trying to help a fellow human, not because I enjoy it. I will help you if you let me. FUNCTIONS AND LOOPS WERE ADDED TO THE LANGUAGE TO MAKE YOUR LIFE EASIER. LET THE COMPILER/INTERPRETER MAKE YOUR LIFE EASIER! Is anyone actually going to read this whole thing? Probably not, but I thank you if you did. Hopefully I was able to convince people of the error of their ways this time. I still think the site should officially advocate against GOTO, but this thread seems to prove the opposite. If you want to continue using GOTO, I can’t stop you, but I can mentally put you in the same bucket as Young Earth Creationists or Flat Earthers. Obviously incorrect and unwilling to learn. Have fun dying your hair a neon pastel pink or blue. (P.S. Yes, the Earth is largely spherical, and is way older than 6,000 years. If someone is telling you otherwise they are wrong and trying to hurt you somehow.)

I am sorry, but using GOTO in your code when you don’t have to, IS a very loud and large klaxon ringing out that you are indeed a noob. That you need to go back and learn the basics. That you don’t know what you are doing, and that your code is automatically suspect (even if it works). I warned everyone earlier in this thread I would could make a big giant document about why GOTO is bad. Well this thread has gone on long enough, so hold on to your butts, it is a long one. Here we go. If the site wants to copy and paste this into one of those nifty pages, feel free. If I have the ability to do so myself, please let me know what links to click to do so. GOTO isn’t inherently evil in and of itself. It is nicely named and does what it says on the box. Such clarity can be nice to someone just starting out. That being said there are only a few situations where you would want to actually use it, or consider using GOTO to be OK.
  • You are coding in Assembly Language. At that point you simply don’t have the luxury of higher level constructs.
  • You are coding on an old retro system or language that does not support needed looping constructs. For example: BASIC on the Commodore 64.
  • A higher level language is compiling down to an intermediate form that is not meant to be human readable or editable. For example code generated by LEX/YACC.
  • You are in a low level language like C and need to escape from a nested loop several levels deep. (You may need to defend use in a code review for this one.)
Times when GOTO use is not acceptable.
  • Everything else, use a function or loop instead.
  • Item 1
Times when GOTO use is abhorent.
  • GOTO use is defended as a lifestyle choice
  • You are too lazy to learn available looping/function constructs in the language.
  • You maliciously teach it to new programmers as though it was a good thing to use.
Holy heck that was long. Don't worry, I cut most of it out in the quote. Anyway, just one thing you forgot in the acceptable section: You are a beginner and know only GOTO loops. Sure, beginners should learn the loops that were meant to be loops, but that doesn't mean tell them they shouldn't use GOTO. They don't know what to use instead. Also, don't tell them to use while/repeat loops instead and nothing else. They probably won't know how to use those. Direct them to a thingumajig (that was in my dictionary for some reason) that tells them how to use while/repeat/for loops. So let them find out for themselves instead of telling them their code is crappy. Sure, you're trying to use constructive critisizm, but critisizm will discourage them and they won't think they're good at programming. Tell them they are doing good, but that they can improve. Or, don't tell them not to use a code.

Let’s just agree on yes, it’s inevitable that beginners will find their way to GOTO (probably through one of the YouTube tutorials they search for). If the beginner is willing to learn deeper into SB then they will find FOR and WHILE, if not they’re’nt going to find those features then they probably wouldn’t’ve made it far into the concepts of programming and probably lost interest in it as a whole and that’s ok. The whole “GOTO is an evil virus of satan” deal shouldn’t be brought up to beginners because it is up to them to search for a better and less tedious way of doing things, and they don’t find it, simply tell them there’s a better method and they should go find it.

Let’s just agree on yes, it’s inevitable that beginners will find their way to GOTO (probably through one of the YouTube tutorials they search for). If the beginner is willing to learn deeper into SB then they will find FOR and WHILE, if not they’re’nt going to find those features then they probably wouldn’t’ve made it far into the concepts of programming and probably lost interest in it as a whole and that’s ok. The whole “GOTO is an evil virus of satan” deal shouldn’t be brought up to beginners because it is up to them to search for a better and less tedious way of doing things, and they don’t find it, simply tell them there’s a better method and they should go find it.
Yes.

I only kept this open on the off chance that someone like Squarefingers intended to submit an opinion, but it appears that this was not the case. I don't think there is any value in keeping the thread open longer; nothing of value has come of it in the 3 months that it has been.