Why not Goto?

Blitz3D Forums/Blitz3D Beginners Area/Why not Goto?

keyboard(Posted 2003) [#1]
followed the WAZ threads with interest, and I know more than I did cos of it. So, programmers, why not Goto? It is in the command syntax, but you are all against it. Before I start chopping up my code trying to get rid of the *bad* Goto command, could someone explain why it is so looked down on, and why it is even there?


Beaker(Posted 2003) [#2]
There is a thing called structured programming. Look it up.

Goto's arent as evil as some people make out. They were more evil in the past when you couldn't see the entry point for them (cos we used line numbers instead of labels). But also they don't have a defined exit point.

The main point is that you don't need to ever use Goto's, so why use them?

Gosub's are less evil because they have an exit point, but they are again, unnecessary. Use functions instead.

It is still there for the sake of completion. If I remember right in the first beta version of Blitz, it didn't have Gotos and Mark had to do some serious coding to get them in after some users kicked up a fuss.


keyboard(Posted 2003) [#3]
structured programming: A technique for organizing and coding computer programs in which a hierarchy of modules is used, each having a single entry and a single exit point


Thanks MasterBeaker I have looked it up and I think I get it more. I will examine my Goto's with a suspicious eye.


MadMax(Posted 2003) [#4]
10 x=0
20 x=x+1
30 "do something"
40 IF x<=20 : GOTO 20

Hehe, those where the days.

I remember when they started saying, one shouldn't use GOTO. I thought. "This is crazy...". Of course the BASIC I was using was very limited. Nowadays, well I wasn't even aware there was a GOTO in Blitz. :-)


sswift(Posted 2003) [#5]
This is why not goto:


.a
x=1
Goto c
.b
x=2
Goto d
.c
x=x+1
Goto b
.d
x=x-1
Print x

WaitKey()


MadMax(Posted 2003) [#6]
The reason I wouldn't use goto is that it's much more difficult to code and maintain, and however much you try to program in a structured way, you'll end up with what is known as "spaguetti" code. But then if you feel you need to use a GOTO now and then, go ahead. But the truth is that GOTO is not needed at all.


robleong(Posted 2003) [#7]
I wouldn't totally rule out the occasional use of GOTOs, if the code is clear enough to understand, and the GOTO used is not anticipated to cause problems in the future. However, in the WAZ thread, the GOTO was used to exit two loops - that could cause problems.


Gabriel(Posted 2003) [#8]
I only ever use Goto when I'm playing with something and it's quicker than the alternative.

For instance if I want to skip a huge chunk of code it's quicker to use a goto than to split it into a function or rem it out.

I would never leave a goto in anything vaguely important. You just don't need them.


Sledge(Posted 2003) [#9]
I wouldn't worry about Goto too much -- as you gain more experience you'll find yourself naturally beginning to use it less and less, until it eventually disappears from your code completely. It's just very handy to have available when you're utterly green.


Tricky(Posted 2003) [#10]
An extreme example in the old GW-BASIC, and you can really see why this program is called "Spagetti"

10 A = Int(Rnd*10)
20 B = Int(Rnd*10)
30 Print A; "+"; B; "="
40 Input C
50 If C = A + B Then Goto 80
60 IF C > A + B THen Goto 100
70 If C < A + B THen Goto 120
80 Print "That is correct!"
90 Goto 140
100 Print "No the correct answer is higher"
110 Goto 40
120 Print "No the correct answer is lower"
130 Goto 40
140 End


Take a good look at this program, it jumps in all kinds of ways, without any kind of structure, and it's hell to figure all the code all, and if you put lines to all the jumps made in this game, to get some organization for yourself you see one big bunch of spagetti, and it's so hard to maintain good order to yourself... Overuse of Goto is bound to turn your program into a big mess... In this example it's not superbad, since it's an easy one, when doing complex programming like programming a game, you will get your code into an even bigger mess, and debugging will be hell, and if you have to carry over your code to another programmer, he won't be able to make out any sense out of it... That's why Goto is considered the forbidden command... It's implented for emergency purposes, but it's usage should always be avoided if possible... As long as you only use it when you don't have another choice, you can keep track of things, as soon as you start using it for everything you'll loose control over everything, making debugging, next to impossible...

A programmer's rules seems to be, the less of gotos the better the programmer... Not completly true, but the less gotos are used, the more organized your source will be and that's worth a lot...


sswift(Posted 2003) [#11]
I still use gosubs in my main programs, but only to move code out of the main loop which I would have in the main loop anyway.

For example, when I load all the graphics, in the main program I have Gosub Load_Graphics.

Using them sparingly like this, they're really no different than using a function, except that I can access all the variables in my main program.

Now, if you're not really careful, (and I AM really careful), then this extra freedom to access any variabke in your main program can end up biting you when you accidentally reuse a variable. For example, if you always use the variable "Loop" to do a loop, and then you have a gosub in the loop, and in that gosub you do another loop... You're in trouble. :-)

Of course I only do this for the sake of convenience. It's just faster to clean up my code by moving gosubs out of main loops than by creating tons of extra global variables to pass data between all the functions.

I am trying though to find a way to move to a completely structured approach and get rid of my gosubs. Whenever I find a gosub which I can move into a function without too much converson effort I do that.

IF you want an example of why I use gosubs, then here's one.

In my game, I have a level editor built into the game, and in that level editor there is a "tag editing mode". In the editor you can select tags. So to do that I have a variable called SelectedTag.Tag. This is used by the editing functions and preserved between frames. So either it has to be a local variable in the main program, or a global variable. Local is better natually. If it was a local function variable then there would be no way to preserve it between frames. Also, this variable needs to be accessed by the Render_2D subroutine, which is another gosub. This one renders the 2D stuff over the 3D scene. And in doing so, it needs to access SelectedTag so it can print the tag's data on the screen.

Now you might say that I could return SelectedTag from the Get_Local_Input function, and then pass it as a parameter to the Render_2D_Overlay. But that seems kind of ugly. I mean does it really make sense to return a tag from a function that gets user input? Besides which, you can onyl return ONE variable from a functon. I definitely have other data like this that needs to be passed around the code a lot.

In C I suppose one might return a pointer to a structure from a function and have that contain the data. But it seems yucky to create a bunch of types each one specific to the data a particular function needs to return.

Then again, perhaps that is the way of the future. Seems pretty illogical for functions to only be able to return one peice of data. But that does make A = Foo() a lot easier to write. Then again, it's not really hard to write like A = (Kung)Foo() to return the variable Kung from the function Foo(). And A = Foo() could return a pointer to a strucutre containing for that function.

I dunno. :-) Strutured programming isn't an exact science. Personally I think what would benefit structured programming most is a better IDE. The inability to add invisible comments to a section of code clutters up code and actually makes it harder to read when you have a lot of comments. But then, who besides me actually comments their code that much? :-) It would also be nice to be able to treat code like a series of folders in explorer. That would make it MUCH easier to spot nesting errors in your code, because you could click a little + sign next to each if or else statement to collapse the code within it and then you'd see exactly what gets collpased. It would also be good to have barely visible brackets which encompass said nests of code so that again it's easier to see which code is within each nest.


Sledge(Posted 2003) [#12]

I still use gosubs in my main programs, but only to move code out of the main loop which I would have in the main loop anyway.



Ditto -- I don't see Gosub as remotely evil or worrisome. Functions excel at manipulating the values you pass them and returning a result... it's what they do; The way they're now pushed so heavily as the de facto way to cordon off a subroutine is totally puzzling to me: I remember, while attempting picking up a bit of C++, the whole fandango involving void functions and pointers JUST TO MOVE A BIT OF CODE ON THE SCREEN IN ORDER TO MAKE IT MORE ORGANISED struck me as the most awkward-for-its-own-sake approach imaginable (and, if I'm honest, I mention it now largely in the hope that someone better versed in C++ will say "Sledge you pleb, you can branch easily like this instead..." as I still can't quite belive that the language is so unaccommodating). Branching isn't just done for the sake of constructing a more optimal exe, it's done in order to increase the presentability of the source code too -- Gosub is worth its weight in gold for this and should definitely not be classed alongside Goto and dismissed with it.



EDIT: Deleted accidental Paste


GfK(Posted 2003) [#13]
Goto isn't needed at all.

BUT....

If I had the choice between using a GOTO, or being politically correct and writing four hours worth of code just to avoid using a GOTO, I'd use a GOTO. I may burn in hell for my sins, but so what. Goto's have their uses.

I've always said, it doesn't matter how you write a game, it doesn't matter what language you use, its the GAME that matters.

I've seen the sourcecode to a commercial game that didn't use ONE function. It was ALL subroutine calls. Horrible to look at, but it did the job. I won't name names, its not my place.


_PJ_(Posted 2003) [#14]
I use Gosubs, and don't toch funtcions at all. Why?
Habit mainly from the old speccy days, but also because it is easier to add more to a subroutine than updating a function and all the parameters thereof.

I guess it's good to use what works best for yourself, although there may always be more efficient/strctred ways to do it.


GfK(Posted 2003) [#15]
My first Blitz game (Hole in One) used functions (cos I come from an AMOSPro background), but it didn't use ANY datatypes.

I look at the code now and wonder how the hell I ever got it to work.


Tricky(Posted 2003) [#16]
I agree that you can sometimes better use a goto then 400 lines of code to achieve the same thing, however when I truly learned the tricks to avoid Gotos I found out that the origanisation of my program really improoved, making it much easier for me to maintain a good view on my code... In my first years in GW-BASIC it's almost impossible to avoid Gotos, but when I stepped over to Pascal I was forced to avoid them, and man, am I gratefull for this forcement, since I took so much advantage of that in all other languages I stepped in later on...

But that's my personal opinion... What do I know :P


Rottbott(Posted 2003) [#17]
There are times when a GOTO can speed things up or actually make the code simpler. But I never really jump around code with them, just use them occasionally to skip sections easily..


keyboard(Posted 2003) [#18]
Talk about throwing light on a subject, I am glad I asked that question :)

I take heart from Sledge's comment:
as you gain more experience you'll find yourself naturally beginning to use it less and less, until it eventually disappears from your code completely. It's just very handy to have available when you're utterly green.



Ice9(Posted 2003) [#19]
GOTO was important when Select Case
was not in basic. you could use a goto to
mimic it. but you can also use it to make nasty
spaghetti. Have you ever tried following code
with a bunch of goto's in it. A night mare no structure.


Curtastic(Posted 2003) [#20]
I have one goto in one of my large games, without it I would have to make some kind of kludge of doom.
because its inside a function, inside a few ifs and elses, I would end up making whiles and make variables that are only there to force the execution into the if and into the whiles.
And right there the goto is so much faster, nicer, easier to understand.
Usually you shouldnt use goto, but people who say "never" arent thinking of all of the possibilities that you could want it.


Anthony Flack(Posted 2003) [#21]

GOTO was important when Select Case
was not in basic. you could use a goto to
mimic it



Or "On x Gosub"

I use a few too. Not many. But every so often, I find they do the job nicely.


FlameDuck(Posted 2003) [#22]
I look at the code now and wonder how the hell I ever got it to work.
And work so well at that! :o>

Anyway, gotos, gosubs and functions are all evil. You should all learn to use objects and methods instead.

It's the "science" of programming. You see there are these programmers who aren't happy at all. They have underpaid jobs debugging random code, and work 50 odd hours a week. To make themselves fell more important and raise their self-image they will occasionally publish a "programming doctrine" that everyone will follow for fear that no-one will ever want to debug their code or otherwise help them out without being yelled at like a little boy.

Most sane people fortunately realize that as long as you write the program in such a fashion that it's clear what's going on and well commented, nobody important gives a rats backside which commands you use to acheive the desired effect. If it does what it's supposed to and doesn't display random glitches and crashes then it's good code, regardless of how many gotos there are. In it.


RocketGnome(Posted 2003) [#23]

Have you ever tried following code
with a bunch of goto's in it. A night mare no structure.



Yeah. Assembly. :P


Tricky(Posted 2003) [#24]
Mimics cases with gotos?

Maybe you remember this GW-BASIC variant;

On Var Goto 100,300,424,450,600


That could Mimic it, but the chance of creating spagetti still remains... Lots for commands, like Do...Loop (in Blitz Repeat... Until/Forever), Select Case, Function... Those commands really reduced the need of Gotos... And once you're used to avoid them, you don't even think about using them any more... At least, about 97% of my code, I never even considered a goto, I already knew a way around it before the word even came in my mind...


Rottbott(Posted 2003) [#25]
The only way I could get rid of all my Gotos entirely is if we had an "Exit n" command. The Exit command is handy but would be a lot more so if we could specify a 'depth' for it to get out of nested loops. Actually, is that worth putting in feature requests?


Anthony Flack(Posted 2003) [#26]
Yeah! I'm always getting stuck in nested loops like that.


Tricky(Posted 2003) [#27]
No, not worth to be put in the feature request, because as far as I know that feature already exists... (I already used it, if I recall correctly)...


9572AD(Posted 2003) [#28]
In my college programming courses (back in the long long ago), they always stressed than any well written program went completely linearly from start to finish with no tricksy jumping about. I never understood how that could work with a program that has a loop with an unspecified and variable number of iterations (a program like a GAME, for example), but as a philosophy it makes your programs much more maintanable.
GOTO obviously doesn't fit into that philosophy in any way.


Anthony Flack(Posted 2003) [#29]

(I already used it, if I recall correctly)...



Oh? How?

9572AD, I remember that being stressed too. That don't bother me none so long as my game runs tho. Plenty of bad habits in there, but it has just enough structure to hold itself up until it's all finished. About as good as it gets with me; I'd have to do some severe disciplining before I could work on a large team/large project. Which I have no intention of ever doing, anyway. So, er, yes, that philosophy does have merit I think. But so does doing things any old way, if it works for you.


_PJ_(Posted 2003) [#30]
Hmm...

Of course a completely linear program would be very good, efficient, neat &tidy, perhaps fast etc. But I think the point is that it is 'ideal-world-scenario' stuff.

I have just read the
Exit n
in the Feature Requests, and where the subject mentioned GoSubs and The Stack...

If a program uses a lot of subroutine calls, would it be particularly slower than if calling the same number of 'identical length' Functions?
would it use a significant amount of memory?


Tricky(Posted 2003) [#31]
I don't know how the Blitz compiler works on that point...

As I know for the Pascal compiler it uses segments of memory, and it reserves a certain ammount of memory for a segment... One segment could contain, the main program, a procedure, a function, and that sort of thing...

But my information on that is too global... But as for the Pascal compiler, I'd say yes (but Pascal doesn't support GoSub)...

But if Blitz uses a semiliar method is unknown to me, and Mark claims that the memory these days is so big that it doesn't really matter...

I hope, he's right...


robleong(Posted 2003) [#32]
Malice, as far as I know, subroutine calls are a tiny weeny bit faster than function calls, and generally, both take up similar amounts of memory. In ordinary practice, either implementation is similar in terms of speed and memory usage.


Tricky(Posted 2003) [#33]
I dare to doubt that, since if it was I think it could be used me, in spite of the spagetti matter (some programmers really go for speed than organization or funtionality)... But what do I know?


Tricky(Posted 2003) [#34]
I've checked out the "Exit n" matter... The "Exit" command exists, it only has no label feature like "Exit n"... That what brought me into confusion... Sorry guys, you can forgive me this little mistake...