143 Replies - 8339 Views - Last Post: 13 October 2012 - 01:05 PM

Re: Is it important to know about GOTOs?

If the ability to emulate any other control structure doesn't convince you that it is more powerful and more flexible than any of them, then I don't know what will.

cfoley has pretty much covered this, but the ability to do something with goto that I can't do in other ways, and that I want to do, or the ability to express something I want to do in a more graceful and, um, expressive manner.
You know, like, how would adding a goto improve a language like Java?

I've taken Compilers, man, I know that everything in a high-level language can be expressed in low-level machine instructions because I've done it. I know that all of your control structures are basically jumps at heart, or can be expressed with jumps. I just don't see why I'd want to write assembler in Java. So to convince me you'd have to show me that there's something I can't do now, which I want to do, and could do with a goto, or else to show me that there's something I can do now, which I would prefer to do with a goto.

All of your control structures look like they work fine, but I prefer to use the stock components because getting those structures right each time I want to write a loop takes away from my attention to getting the higher-level details right - just as having to refer directly to the memory address of a piece of data instead of a name which refers to that address would take away from my attention to what that data actually means. So I don't prefer to do it that way.

In the end, I think you're right when you point out that yours is a losing argument, because if you really do come up with a control flow that I want to have, and you express it in terms of a goto, I and any other modern programmer will immediately name it and bake it into a language. So you'd have to show not only a better form, but also that this can't be expressed in terms of a simple, expressive, and restricted command with a semantically helpful name.
That's a hard job, but it's what you'd have to do to reply effectively to Dijkstra. This is why nobody's managed to reply to Dijkstra effectively in a couple of decades of trying.

Re: Is it important to know about GOTOs?

If the ability to emulate any other control structure doesn't convince you that it is more powerful and more flexible than any of them, then I don't know what will.

Why should it? All you've proved is that control structures replace GOTO in are more readable in cleaner way. The request was to see something "gotos excel at". If all they excel at is awkward emulation then you've completely failed to make a case for them.

G0rman, on 12 October 2012 - 12:54 AM, said:

I'll do it without gotos and loops if it makes you feel better
Heck, I'll throw in "no sub()" as a a free bonus!

LOL. I suspect you'll use recursion, which is looping using the stack. Curiosity, though... Do this without loops.

Re: Is it important to know about GOTOs?

Secondly, the things that gotos excel at - namely power and flexibility - are exactly what you are trying to avoid.

Sigh. Okay, this is going nowhere.

If you haven't got an example of this power and flexibility - ...

This was your response to a post where OP explained why he wouldn't be giving you one as it's not worth his effort.

Which was his response to a post where you said:

Quote

...

They're incredibly powerful and incredibly easy to use. And they make a lot of things really easy.

...

You then follow his response where he shows said examples, that he already proclaimed was going to be a waste of time. Your respond with exactly what he expected you to say:

Quote

...

I've taken Compilers, man, I know that everything in a high-level language can be expressed in low-level machine instructions because I've done it. I know that all of your control structures are basically jumps at heart, or can be expressed with jumps. ...

So which is it, you agree they're powerful, or you need an example of their power?

I thought his explanation was extremely discriptive. GOTOs can be used to do all sorts of things that modern languages have constructs to do for you. That's the power and flexibility... it, on its own, can perform all those tasks.

So what's the problem? OP won't fall into your dogma that goto's are evil. He's admitted said power can be destructive... he's just unwilling (and so am I) to say thusly they are inherently the worst thing and should never be used. Only because we created 12 new tools to replace the abilities of this 1 tool.

Re: Is it important to know about GOTOs?

They're incredibly powerful and incredibly easy to use. And they make a lot of things really easy.

...

So which is it, you agree they're powerful, or you need an example of their power?

I agree that they're extremely powerful. And if you read the rest of that post, I said that the problem is that their superpower is the ability to totally hose your code. Now I'd like an example of some way in which they can turn their power to good. As I say, the way to convince someone that this construct is a useful one would be to give them an example of how this adds something which I can't do in other ways or allows me to do something I can already do, but more gracefully.

In Java, for example, I have no actual need for the "enhanced for" loop. I can do a while (has next) over an iterator or a standard for (int i = 0...) across the indices of an enumerated collection (a list, for example). The enhanced for earns its place in the language by making iteration over a collection a more graceful and expressive construct: instead of counting numbers or checking a flag, which are operations about the container, I'm doing something for each item. Now it's an operation about the items themselves - this is, I think, a better expression of my purpose.
It turns out that this also gives the compiler some room to optimize, and it gives the language some room to specialize. So I can imagine ways to make this construct iterate over infinite sets, or sets whose bounds are not known at run time, and give meaningful answers, which is hard to do when I'm using the original for loop. And of course, it's simply impossible with a hand-rolled goto construct.
So the development of a language is a progress towards better ways of expressing our purpose, and better ways of understanding those expressions with our machines. If you insist on using low-level constructions, you make that more difficult or you make it impossible. That's fine, if that's what you want to do, but if you want to convince me that there's a benefit to it, you have to show me a benefit. Not just "I can do that, but worse and with more chance of error", but "I can do that, and I can do it better, and I can also do this thing that you can't do".

The goto has to earn its place in the language, like any construct. And so far, I don't see that happening.

Quote

I thought his explanation was extremely discreptive. GOTOs can be used to do all sorts of things that modern languages have constructs to do for you. That's the power and flexibility... it, on its own, can perform all those tasks.

So what's the problem? OP won't fall into your dogma that goto's are evil. He's admitted said power can be destructive... they're just unwilling (and so am I) to say thusly they are inherently the worst thing and should never be used. Only because we created 12 new tools to replace the abilities of this 1 tool.

Re: Is it important to know about GOTOs?

Here's the thing... OP agreed with you that it's powerful, and the power can be destructive.

OP hasn't said we should start adding it to languages that don't have it. Only that modern languages have limited/restricted versions of it (see my previous post where I talk more about this).

He then is basically say he doesn't agree that the dogma of "goto is always evil and should NEVER be used" is bullshit dogma. And that learning what they are, how they work, and the design patterns of them can be helpful to understanding how these more contemporary constructs work (loops, if/thens, case, break, etc). As well as allowing one to maintain old code.

As you said, you learned compilers and assembly in college. Where jumps/gotos are taught. So thusly YES it's reasonable to learn them.

So in the end, the two of you agree on every fact... and only fail at the conclusion where you say thusly goto is inherently evil. And OP says, no it's conditionally evil.

What's the fucking problem? Are the two of you so insecure about your opinions that you can't see through your own facts?

Re: Is it important to know about GOTOs?

So in the end, the two of you agree on every fact... and only fail at the conclusion where you say thusly goto is inherently evil. And OP says, no it's conditionally evil.

And since the only people beating that dead straw man are you and the OP, I think we can let this one rest. GOTO is not evil. This is not a moral issue, "evil" doesn't come into it.

"GOTO considered harmful" is the issue, and yes, it is. That's been known for a long time, since Dijkstra, and nobody has yet presented any reason to believe that unrestricted branching is a desirable feature in a language that has reasonable flow control instructions.

GOTO should not be included in high level languages, because its presence creates room for errors that would not otherwise be possible, and it adds nothing to the language that cannot be done in other ways.

We agree on all of this.

Should GOTO be taught? Well, if there's a reason to teach it, sure. For compilers, for assembly programming, it's pretty necesary, so yes, you should teach it. If you're doing system programming in C, yes, there will probably be cases where you need it. But if you're learning application programming in contemporary languages, you don't even have a GOTO, so there's nothing to teach. So it's up to the teacher, I'd say.

Quote

What's the fucking problem? Are the two of you so insecure about your opinions that you can't see through your own facts?

I don't get the sense that baavgai suffers from excessive insecurity, but I'm not going to speak for him. In my case, I'm pretty well convinced that GOTO is in fact harmful (not in my or in anyone's opinion, but in fact) and that this is so well established that it's odd that we're still talking about it. I'm also happy to have this opinion changed if anyone can take the trouble to show me a way in which it is incorrect.
If nobody wants to present any arguments or facts to support the claim that GOTO is other than harmful (note: "evil" is still not at issue) in a high level language, then I think the issue is pretty much settled by acclamation, and it's all over but the shouting. Which you seem to be taking care of nicely.

Re: Is it important to know about GOTOs?

Posted 12 October 2012 - 08:41 AM

Okay. Um, thanks for joining in. I'm glad we still agree on everything. I think. I'm not sure what you're on about there, honestly, but it's always nice to end a pleasant argument with a pointless tirade. It wouldn't be the internet without you!

Re: Is it important to know about GOTOs?

If the ability to emulate any other control structure doesn't convince you that it is more powerful and more flexible than any of them, then I don't know what will.

Expanding on Baavgai's response to this, a couple posts back I showed that more flexibility is not necessarily a good thing. The main thing we would like to see if you want to make a case for GOTO is examples where GOTO does something that isn't better handled with structures. You have shown that GOTO can do the same things as structures. We already knew this. We also know that goto's have a lot more leniency than structures. The problem is that using this extra leniency is almost always a horrible idea. If you don't understand the problems involved with using GOTO's then lets compare some examples side by side.

With functions, we don't need to track how the environment is stored or save locations to return to. The functions are easier to read, debug, and alter. Every example you have given only demonstrates why one should avoid GOTO in favor of structures. With GOTO comes a lot of extra work ensuring that you are correctly controling the flow and environment. This just means that you are likely to have more errors in your program that structures would prevent. Why not just use the structures and ensure the integrity of the control flow and environment? This is a huge advantage structures have over GOTOs, so you need to show us something GOTO offers that overcomes this advantage.

Re: Is it important to know about GOTOs?

Posted 12 October 2012 - 10:05 AM

baavgai, on 12 October 2012 - 08:56 PM, said:

Why should it? All you've proved is that control structures replace GOTO in are more readable in cleaner way. The request was to see something "gotos excel at". If all they excel at is awkward emulation then you've completely failed to make a case for them.

jon.kiparsky, on 12 October 2012 - 02:11 PM, said:

If you haven't got an example of this power and flexibility - and I'm honestly interested in seeing it - I think there's not much point in continuing with this.

I believe I perfectly answered his request - to show that gotos are powerful and flexible.

I don't think excel is a synonym for neither powerful nor flexible. If you believe that, then I guess I already answered your request, right?

baavgai, on 12 October 2012 - 08:56 PM, said:

G0rman, on 12 October 2012 - 12:54 AM, said:

I'll do it without gotos and loops if it makes you feel better
Heck, I'll throw in "no sub()" as a a free bonus!

LOL. I suspect you'll use recursion, which is looping using the stack.

Yup, that's right I'll just use recursion. I guess you are realizing that no single element on it's own is indispensable. So the fact that any single element is replaceable is not a reason not to use said element.

I don't really agree with "recursion is just looping using the stack", recursion and looping are very different things. I'm sure you know better, it's just that description is a bit off, it could mislead people.

What's the fucking problem? Are the two of you so insecure about your opinions that you can't see through your own facts?

I don't think it's a case of that. Everyone enjoys this kind of theoretical discussion, and it's nice to see a lot of thought going in to posts. It was great to see some code snippets that people wrote, and there has been some enlightening posts.

I doubt anyone will be brooding over "this guy on the internet didn't 100% agree with me about gotos"

A lot of what you said was very helpful lordofduct, but I wish you would have focused more on the topic rather than starting a meta-dialogue. You seemed to have some interesting things to say, so don't focus on who is trying to "win" the thread

mojo666, on 13 October 2012 - 12:10 AM, said:

Why on earth is this considered better than

I doubt anyone thinks it is better.

But gun to my head, if I had to give an answer, I'm sure I could think of something about having a high level of control over the way a program executes. There's probably some specialists out there who find that the way their language deals with functions is unsatisfactory for whatever reason. Heck, even mid 80s people thought tail calling with gotos was more efficient than sub(), and it wasn't until compilers were smart enough to optimize the call that they swapped over to just using sub().

mojo666, on 13 October 2012 - 12:10 AM, said:

Why on earth is this considered better than

With functions, we don't need to track how the environment is stored or save locations to return to. The functions are easier to read, debug, and alter. Every example you have given only demonstrates why one should avoid GOTO in favor of structures. With GOTO comes a lot of extra work ensuring that you are correctly controling the flow and environment. This just means that you are likely to have more errors in your program that structures would prevent. Why not just use the structures and ensure the integrity of the control flow and environment? This is a huge advantage structures have over GOTOs, so you need to show us something GOTO offers that overcomes this advantage.
[/quote]
As above, sometimes you might need it.

In C you have to allocate your own memory after all. I don't see a lot of people telling me that C is the work of the devil because pointers and malloc are "harder to read, debug and alter". If you need to consider a problem at a very low abstraction level, then you may need goto. If you want to consider it at a higher abstraction level, you will use more complex control statements. If you are an architect, you probably won't even care about a for loop.

Low level instructions are always going to be useful in that kind of situation. Though I understand the logic of "if you have a low resource environment then use a low level language", it would also be nice to use a higher level language and manually control the execution.

As before, I'm not saying you should forgo all other high level statements and only code with gotos. I was asked for examples of goto's power and flexibility, so I gave examples to that effect. I was not asked for examples of goto's "readability, debugability and alterability" - though I don't think I'd have much problem altering or debugging that code. And certainly no problem reading it (YMMV, I did write the code after all. Did you have any problem?).

I think I've said it 3 times before, but no one has given me an answer as to why jumps within a block or scope are bad. Do you really think it is so hard to read/debug/alter those ~10 line examples. A good example is our university coding standard, which states "A function should not be longer than 30-50 lines." That's enough to fit screen without scrolling. Do you think you would have problems with such a small piece of code (once again, assuming the aforementioned limitation of no jumps outside of the scope, only within the block)

EDIT: By the way, this whole "refactor my code with X restriction" is really fun, we should do this more often!

Re: Is it important to know about GOTOs?

Posted 12 October 2012 - 10:07 AM

baavgai, on 11 October 2012 - 05:19 PM, said:

BBeck, on 11 October 2012 - 04:25 PM, said:

But not all of that is entirely a question of style. My primary point was that having multiple exit points from a block of code can make it far more difficult to both understand and debug. It costs maybe a couple extra machine instructions to avoid the multiple exit points

Nope, still style. I understand some of the complaint against the multiple exit points but, you know, it's not like you don't know where you're going.

You're exactly right that your code is about 5 lines long and very easy to understand quickly. Your code is actually a very bad example to use as a "bad example" because of that. Where the issue of multiple exit points comes in is when someone hands you a program that needs debugging and there's a function or method that gets called 87 just fine, but then blows up on "roughly" the 87th pass through it because it returns an invalid return value. Then you open up the code to find that said function or method is 30 pages of code with 47 exit points that all have different code determining what they return. Which of the 47 exit points was the one that returned the bad value? All you can do is step through the code with the debugger to try and figure out which of the 47 exit points is not working correctly. You probably have to figure out which exit point it is before you can even begin debugging.

But if you have a hard fast rule that says there will always be one exit point and one exit point only, and that exit point will be at the end. If you write all your code that way and a function or method returns a bad value, you know exactly which exit point of the rouge function/method caused the problem. You can set a break point on it in confidence and then keep moving that break point back further and further until you find the problem.

I'm maybe not the best at giving examples of this, but I'm sure you can find better examples in academic texts. Certainly, this is something that I was taught in school.

Quote

I'm dead seriously when I say I found your code hard to follow. The caps thing is murder, but the while loop where you could use a for loop added confusion and visual noise. Mine was far more clear to me.

Fair enough; some of it's going to be what you're accustomed to and personal preferences. The while loop is maybe not "quite" as clear as the for loop, but it eliminates the multiple exit problem. And I think it's still pretty clear. I believe "eliminating multiple exit points" is part of the reason that while and do-while loops are in the language. It's a bit of visual noise, true, but the extra noise is much less noticeable in a large code block. For something this simple, 'for' is probably quite a bit more clear, but it requires multiple exit points. In a larger block of code I think while and for would likely start looking more equal and I would say the same thing about putting the opening curly brace on it's own line although that's admittedly a matter of style preference. But the curly braces on their own lines tends to make the code harder to read for very small blocks, but I think it makes the code easier to read and debug once you get to more average sized blocks of code.

As far as using Pascal case with it's capitalization of first letters: The first letter of every sentence in English is capitalized. Looking at it from that perspective, it's a bit un-natural to make the first letter in a phrase lower case while making the rest uppercase. I know it's a standard in both Java and C# to make the first letter lower case. I would not give anyone a hard time for doing it that way because it's considered the 'most correct' way to do it in those languages. I'm not sure why they chose to do it that way. I presume it comes from the days before IDEs color coded reserved words and what not. There was probably a problem with reserved words being capitalized already and when the code was black and white, rather than being color coded, it probably made the code easier to read to make that first letter lowercase to show that it was a name the programmer had chosen rather than a reserved word.

But with color coding in Visual Studio today, I've never had a problem distinguishing between my own names and those built into the language or framework. I've been using Pascal case since I took Pascal class in school and I've never found a good reason to change. However, I'm well aware that that's my preference rather than "best practices" (unless you are programming in Pascal where it is part of the "best practices"). So, I'm not going to try and convert anyone over to Pascal case who's programming in Java or C#. And I'm open to hearing why I should switch other than "well everyone else is doing it that way".

Quote

I do agree that clarity is absolutely worth of few more operations. This is one of the reasons OO exists. However, I don't believe your vision of clarity and mine of are the same.

That's fair.

Quote

I wasn't going to point this out but, um, you missed resetting your inner counter; the code executes one inner loop and then never does so again. You know, if you can't get the thing right...

Good catch! :-) I believe that would add one more machine instruction to the outer loop and slow it down a couple of cpu cycles even further. But like you said, when it makes sense "clarity is absolutely worth a few more operations".

A function shouldn't be more than a page. Well, a screen, really. If it is, you need another function. A function is a form of documentation. Code with tons of comments around code blocks floating in giant blocks finds clarity when a simple, named, function is used instead.

One exit point really wouldn't help on your 30 page monster because, well, it would still be a 30 page monster.

BBeck, on 12 October 2012 - 01:07 PM, said:

Java and C# to make the first letter lower case.

Quite.

The reasoning here is that classes start upper case. In Java, methods starts lower, but C# prefers those upper as well. The big thing here is something like Image image;. If your classes are upper case, and you just need single instance of a class, you have immediate clarity with this convention. When your convention, I'm fumbling for what to say and being murky on class names and variable names.

Oddly, I did Pascal in high school and college and never picked up this odd formatting. I believe Pascal preferred var caps because their types were lower case, hence a reverse of the Java/C# convention. However, they tend to only use that for complex types, with primitive vars often lower being. Man, that takes me back.

I generally attempt to adapt to my environment and use the preferred conventions of a given language as much as I can. If nothing else, it gets you into that language's zone.

A function shouldn't be more than a page. Well, a screen, really. If it is, you need another function. A function is a form of documentation. Code with tons of comments around code blocks floating in giant blocks finds clarity when a simple, named, function is used instead.

One exit point really wouldn't help on your 30 page monster because, well, it would still be a 30 page monster.

BBeck, on 12 October 2012 - 01:07 PM, said:

Java and C# to make the first letter lower case.

Quite.

The reasoning here is that classes start upper case. In Java, methods starts lower, but C# prefers those upper as well.

LOL Well, you're absolutely right that that's a " hideous giant god function of holy terror". I absolutely agree that you should strive to keep all procedures/functions/methods to one or two pages of code and that if they aren't you need to go back and break it up into sub-functions. I was thinking about that when I wrote what I wrote. But I was also thinking that things like this tend to be mostly a problem when you have a beginner who doesn't know better. In that case, they're probably failing on best practices in something like 20 different areas.

Obviously in your code, it's 2 exit points, about 5 lines of code, and abundantly easy to read and understand. But I think it's taught as a best practice because the person who's likely to crank out a 30 page method is the same person that's likely to write 47 exit points. And maybe it's taught as, "follow these 10 best practices and you won't ever have to worry about it".

I don't know. Pascal was my first formal computer class. Before that I started programming in Basic when I was 12, writing spaghetti code with GOTO's jumping all over the place like a grasshopper on a frying pan. That was inline (non-object oriented) programming. So, maybe it's less of a concern today, I don't know.

But I went from being a pasta programmer to writing considerably easier to read code that was far easier to debug largely from some of the "best practices" I picked up from Pascal and Assembler classes (Assembler taught me the value of commenting your code more than anything else).

I pretty regularly get comments on how easy my code is to work with when other people go through it. (Although, most people probably aren't going to tell you that they think your code stinks to your face. lol)

This (fourth post from the bottom and the last post with code) thread is probably a pretty good example of what my code looks like when I'm putting forth my "Sunday Best". It's maybe not the best code ever written. There's probably a better way to do it. But I think following the practices that I do makes it a lot easier for someone unfamiliar with the code to come in and get up and running with it quickly. And I think it makes it a "whole" lot easier to debug. (I'm not saying your code is any less readable or well written. I was just trolling about multiple exit points and your code was at least an example where multiple exit points were used.)

Anyway, I'm sticking with single exit points unless it can be shown that it improves the over-all performance of the app. But I would certainly forgive someone for doing it if the code were easy to read and easy to debug. And I might even admit it's better when multiple exit points improves performance on the basis that every little bit counts.

It makes sense what you're saying about making the first letter lowercase. Sometimes it's hard to let go of old habits. :-) Adapting to the new environment is probably wise. But I'm still pretty partial to my Pascal case. :-)

Re: Is it important to know about GOTOs?

Posted 12 October 2012 - 12:22 PM

One of the things I'm learning from my immersion in functional programming is the value of keeping functions even more minimal than you think is necessary. I don't really mind multiple returns from a function in Java, but in scheme or in Scala it would feel really weird, because you're keeping your functions down to one or two lines.