Gotoless programming
-
Agreed. I really don't understand the goto hate, although I've never worked in an environment where it was an issue. There are times when goto makes sense even in modern programming techniques.
I can understand it. There are indeed times when
goto
makes sense. The problem is that it is taught to people who do not have the experience to understand when those times are, so use it when a "proper" alternative would be more work. Blame the teachers! I do... :laugh:Ideological Purity is no substitute for being able to stick your thumb down a pipe to stop the water
-
Inspired by the goto comments in the lounge today... Msny years ago a co-worker showed me his first program after we had banned the use of goto statements at our company. His program had a main loop like: If var = 1 gosub 100 If var = 2 gosub 200 and so on.. and inside each subroutine before leaving, it would set var to whatever it needed to be next. An abstracted goto ! This is back in the days before OO and events. This was procedural type code and in this case.. a goto would have been clearly easier to understand.
andrewgissing wrote:
An abstracted goto !
A switch statement in disguise :)
-
Inspired by the goto comments in the lounge today... Msny years ago a co-worker showed me his first program after we had banned the use of goto statements at our company. His program had a main loop like: If var = 1 gosub 100 If var = 2 gosub 200 and so on.. and inside each subroutine before leaving, it would set var to whatever it needed to be next. An abstracted goto ! This is back in the days before OO and events. This was procedural type code and in this case.. a goto would have been clearly easier to understand.
I use the Poser CGI package. http://en.wikipedia.org/w/index.php[^] It includes the Python programming language so the user can program some things. Python's lack of a goto is sometimes a nuisance. http://en.wikipedia.org/wiki/Python_%28programming_language%29[^]
-
Inspired by the goto comments in the lounge today... Msny years ago a co-worker showed me his first program after we had banned the use of goto statements at our company. His program had a main loop like: If var = 1 gosub 100 If var = 2 gosub 200 and so on.. and inside each subroutine before leaving, it would set var to whatever it needed to be next. An abstracted goto ! This is back in the days before OO and events. This was procedural type code and in this case.. a goto would have been clearly easier to understand.
I would also group the break keyword with goto:
public static void renameSchedule(string currentName, string newName) { foreach (schedule sched in Schedules.lst) { if (sched.scheduleName.Trim().ToUpper() == currentName.Trim().ToUpper()) { sched.scheduleName = newName; break; } } }
After all it is jumping out of the looping logic - I use this a lot... I was taught never to use a goto at university, probably because it would mess up all those nicely drawn diagrams we were creating before we wrote any code, then in the final year when we were doing advanced(cough cough) COBOL programming we were told that there was one instance where we could use it...
“That which can be asserted without evidence, can be dismissed without evidence.”
― Christopher Hitchens
-
That's why I always get scared when such rules are preached religiously and then applied at all cost. I often write code for old 8 bit computers or microcontrollers and calling functions for everything will result in a slow processor working more on the stack than the actual task. Using goto or branching instructions in assembly then will make more of the two most valuable resources, CPU and memory. Thinking and making most of the resources at your disposal is more important than blindly following rules.
I'm invincible, I can't be vinced
Hmm, looks remarkably like a very basic finite state machine to me 8)
-
andrewgissing wrote:
An abstracted goto !
A switch statement in disguise :)
Exactly.
var state = 0;
while(state != 5)
{
switch (state)
{
case 0:
// ...
state = 1;
break;
// ...
}
}Interestingly enough C# turns a
switch
into a set ofgoto
s that use the hashcode of the test value as the jump offset (or something similar). Essentially a hardcoded dictionary - which is why it's so much quicker than repeated 'if's.He who asks a question is a fool for five minutes. He who does not ask a question remains a fool forever. [Chineese Proverb] Jonathan C Dickinson (C# Software Engineer)
-
I would also group the break keyword with goto:
public static void renameSchedule(string currentName, string newName) { foreach (schedule sched in Schedules.lst) { if (sched.scheduleName.Trim().ToUpper() == currentName.Trim().ToUpper()) { sched.scheduleName = newName; break; } } }
After all it is jumping out of the looping logic - I use this a lot... I was taught never to use a goto at university, probably because it would mess up all those nicely drawn diagrams we were creating before we wrote any code, then in the final year when we were doing advanced(cough cough) COBOL programming we were told that there was one instance where we could use it...
“That which can be asserted without evidence, can be dismissed without evidence.”
― Christopher Hitchens
It's true that
break
(andcontinue
) are very similar togoto
. However, it's also very restricted in scope, and it cannot jump backwards. It cannot jump into the midst of a loop either. That makes it less likely to accidentally break code. I'm not saying it's good, but it's not quite as bad asgoto
can be. -
Exactly.
var state = 0;
while(state != 5)
{
switch (state)
{
case 0:
// ...
state = 1;
break;
// ...
}
}Interestingly enough C# turns a
switch
into a set ofgoto
s that use the hashcode of the test value as the jump offset (or something similar). Essentially a hardcoded dictionary - which is why it's so much quicker than repeated 'if's.He who asks a question is a fool for five minutes. He who does not ask a question remains a fool forever. [Chineese Proverb] Jonathan C Dickinson (C# Software Engineer)
Jonathan C Dickinson wrote:
Interestingly enough C# turns a
switch
into a set ofgoto
s that use the hashcode of the test value as the jump offset (or something similar). Essentially a hardcoded dictionary - which is why it's so much quicker than repeated 'if's.That only happens when dealing with string cases (above some point 3 or 5 IIRC). All others use a jump table.
-
Inspired by the goto comments in the lounge today... Msny years ago a co-worker showed me his first program after we had banned the use of goto statements at our company. His program had a main loop like: If var = 1 gosub 100 If var = 2 gosub 200 and so on.. and inside each subroutine before leaving, it would set var to whatever it needed to be next. An abstracted goto ! This is back in the days before OO and events. This was procedural type code and in this case.. a goto would have been clearly easier to understand.
The good old goto debate. A goto is a bit like telling the computer that I don't want you to proceed to the next line of code, instead make some other line the next thing to execute. And we do that all the time: exit for, exit do, if some condition goto next line otherwise goto some other line. While some condition go into first line of loop block otherwise goto past the end of the loop block. And then, it all eventually becomes machine code / opcodes, and all of these become some kind of jump instruction, which is basically a goto. So for all you people out there that think that your code has no gotos, I can assure you the CPU is doing jump instructions left, right and centre as YOUR code runs in the CPU. Now please don't tell me that your code is somehow bypassing the CPU. The reason this myth exists is that those early versions of BASIC had line numbers for each statement. And you would code "GOTO 760". Problem was when you inserted lines and made 760 line 761 or whatever but didn't go and update everything pointing to 760. And so this caused problems and bugs. Let's move on. We have alphabetic statement labels (used all the time in assembly language by the way), so you can now "Goto SomeLabelThatHasAMeaningfulNameThatWontBeRenumbered" and the problem is gone. Use goto freely, it's OK. I do it. It gets me out of deep nested rules and condition logic where I have established something I needed to establish. Yes there are always other ways to achieve the same result, but no - they are not always better or more elegant. And now it is time for me to go to bed.
-
The good old goto debate. A goto is a bit like telling the computer that I don't want you to proceed to the next line of code, instead make some other line the next thing to execute. And we do that all the time: exit for, exit do, if some condition goto next line otherwise goto some other line. While some condition go into first line of loop block otherwise goto past the end of the loop block. And then, it all eventually becomes machine code / opcodes, and all of these become some kind of jump instruction, which is basically a goto. So for all you people out there that think that your code has no gotos, I can assure you the CPU is doing jump instructions left, right and centre as YOUR code runs in the CPU. Now please don't tell me that your code is somehow bypassing the CPU. The reason this myth exists is that those early versions of BASIC had line numbers for each statement. And you would code "GOTO 760". Problem was when you inserted lines and made 760 line 761 or whatever but didn't go and update everything pointing to 760. And so this caused problems and bugs. Let's move on. We have alphabetic statement labels (used all the time in assembly language by the way), so you can now "Goto SomeLabelThatHasAMeaningfulNameThatWontBeRenumbered" and the problem is gone. Use goto freely, it's OK. I do it. It gets me out of deep nested rules and condition logic where I have established something I needed to establish. Yes there are always other ways to achieve the same result, but no - they are not always better or more elegant. And now it is time for me to go to bed.
Umm, as you said goto caused problems if you used it and didn't really know how it worked. The thing is most (if not all) programs are compiled and this causes the assembler to move all the loops, functions anything else to the old loveable JMP or Jump statement (which is a go to this location). (Complains about "Softies not know how work things", burn hand on soldering iron!)
-
Inspired by the goto comments in the lounge today... Msny years ago a co-worker showed me his first program after we had banned the use of goto statements at our company. His program had a main loop like: If var = 1 gosub 100 If var = 2 gosub 200 and so on.. and inside each subroutine before leaving, it would set var to whatever it needed to be next. An abstracted goto ! This is back in the days before OO and events. This was procedural type code and in this case.. a goto would have been clearly easier to understand.
I've seen justifiable GOTOs in C code. Usually, the scenario involves nested control structures (IFs or loops) and the possibility of a trash-it-all error deep in the nest. C++ offers less of an excuse for GOTOs, because of the ease of use of the exception mechanism.
That having been said, if a programmer feels he can defend his use of a GOTO, and his program is otherwise legible and maintainable, it's usually not worth starting an RWAR over it. That is, unless you enjoy RWARs for their own sake!
(This message is programming you in ways you cannot detect. Be afraid.)
-
Inspired by the goto comments in the lounge today... Msny years ago a co-worker showed me his first program after we had banned the use of goto statements at our company. His program had a main loop like: If var = 1 gosub 100 If var = 2 gosub 200 and so on.. and inside each subroutine before leaving, it would set var to whatever it needed to be next. An abstracted goto ! This is back in the days before OO and events. This was procedural type code and in this case.. a goto would have been clearly easier to understand.
-
Agreed. I really don't understand the goto hate, although I've never worked in an environment where it was an issue. There are times when goto makes sense even in modern programming techniques.
I guess its just that abusing it can make source code hard to follow.
-
The good old goto debate. A goto is a bit like telling the computer that I don't want you to proceed to the next line of code, instead make some other line the next thing to execute. And we do that all the time: exit for, exit do, if some condition goto next line otherwise goto some other line. While some condition go into first line of loop block otherwise goto past the end of the loop block. And then, it all eventually becomes machine code / opcodes, and all of these become some kind of jump instruction, which is basically a goto. So for all you people out there that think that your code has no gotos, I can assure you the CPU is doing jump instructions left, right and centre as YOUR code runs in the CPU. Now please don't tell me that your code is somehow bypassing the CPU. The reason this myth exists is that those early versions of BASIC had line numbers for each statement. And you would code "GOTO 760". Problem was when you inserted lines and made 760 line 761 or whatever but didn't go and update everything pointing to 760. And so this caused problems and bugs. Let's move on. We have alphabetic statement labels (used all the time in assembly language by the way), so you can now "Goto SomeLabelThatHasAMeaningfulNameThatWontBeRenumbered" and the problem is gone. Use goto freely, it's OK. I do it. It gets me out of deep nested rules and condition logic where I have established something I needed to establish. Yes there are always other ways to achieve the same result, but no - they are not always better or more elegant. And now it is time for me to go to bed.
The reason not to use goto is not a technical one, but a code cleanliness one. A goto is an unstructured jump and makes it much harder for a human brain to comprehend the structure of the procedure. Loops with breaks and continues, conditionals, switch blocks and so on may translate to jump instructions in assembler or IL, but they're structured and therefore easier to understand. The only time I would say it might be okay is the 'double break' (i.e. breaking out of a 2D or deeper loop set). When your logic is this complex it's usually better to take the looping code out into a sub-procedure or -function and use
return
instead, because chances are that procedure is too long already. (You can always ask the compiler to inline it if you think the function stack is critical.) In modern languages, proper error condition handling (i.e. exceptions) have taken away most of the situations in which you'd want to do this. So I agree up to a point: fundamentalist 'never' dictums (dicta?) are not particularly helpful. But it is very rarely the most elegant approach to use a goto. -
Exactly.
var state = 0;
while(state != 5)
{
switch (state)
{
case 0:
// ...
state = 1;
break;
// ...
}
}Interestingly enough C# turns a
switch
into a set ofgoto
s that use the hashcode of the test value as the jump offset (or something similar). Essentially a hardcoded dictionary - which is why it's so much quicker than repeated 'if's.He who asks a question is a fool for five minutes. He who does not ask a question remains a fool forever. [Chineese Proverb] Jonathan C Dickinson (C# Software Engineer)
-
Exactly.
var state = 0;
while(state != 5)
{
switch (state)
{
case 0:
// ...
state = 1;
break;
// ...
}
}Interestingly enough C# turns a
switch
into a set ofgoto
s that use the hashcode of the test value as the jump offset (or something similar). Essentially a hardcoded dictionary - which is why it's so much quicker than repeated 'if's.He who asks a question is a fool for five minutes. He who does not ask a question remains a fool forever. [Chineese Proverb] Jonathan C Dickinson (C# Software Engineer)
-
andrewgissing wrote:
An abstracted goto !
A switch statement in disguise :)
-
/trollattempt? See: Leppie's comment.
He who asks a question is a fool for five minutes. He who does not ask a question remains a fool forever. [Chineese Proverb] Jonathan C Dickinson (C# Software Engineer)
-
Hmm, looks remarkably like a very basic finite state machine to me 8)
I agree on the state machine. Each state has one subroutine for it. Each subroutine could transition to one or more states. Simple, concise. How (and why) would a goto improve this? Other thoughts In assembly, ever high level loop is implemented with gotos/branches. Java does not have or need a goto because they allow labeled break and continue statements. I don't think C# copied that feature (unfortunately).
-
Inspired by the goto comments in the lounge today... Msny years ago a co-worker showed me his first program after we had banned the use of goto statements at our company. His program had a main loop like: If var = 1 gosub 100 If var = 2 gosub 200 and so on.. and inside each subroutine before leaving, it would set var to whatever it needed to be next. An abstracted goto ! This is back in the days before OO and events. This was procedural type code and in this case.. a goto would have been clearly easier to understand.
The gosub call was the mechanism for calling faux functions / subroutines. Unlike the goto, the last address was pushed on the stack so the subroutine could return to the location it was called from. They were a big improvement over goto.