Viewing a single comment thread. View all comments

Sloloem t1_iyalbym wrote

The idea that "Goto statement considered harmful" came from an essay by Dijkstra that was published in 1968 during the dawn of computer science.

His basic case was that GOTO was too primitive to have a single easily understood function when seen in code. It tells the machine to arbitrarily move control to a different instruction at a different line of the program but says nothing about why or what's going to be there. Also since you need to physically start reading somewhere else in the code with the context of what's in memory from the previous location in mind it can make programs extremely hard to read and verify, especially in an age before IDEs and debuggers. It allowed for too wide of a gap between the mental model of a static program and a dynamic running process.

He advocated instead for what he called "structured programming" which is really just programming as anyone born after maybe 1964 understands it. Structured programming makes extensive use of this new-fangled idea from the late 50's called "blocks", because someone had to invent the idea of:

if (true thing) {
else {

at some point.

With blocks that's just the way you write that code with the instructions immediately blocked inside the condition that allows their execution to proceed. With GOTO those lines could be 600 lines away. And without another GOTO to send you back to where you left off, you'll just keep going from wherever you ended up until the program exits or crashes.

GOTO also predates a lot of the looping structures we take for granted in modern programming and while it could be used to implement them, using the actual loops instead carries more meaning and makes your program easier to read, understand, and compile (compilers that translate human-readable source to machine-readable machine code can make certain optimizations in how it feeds instructions into the long as it understands what the loop does). So at this point while a lot of the readability issues would be countered by modern tooling, the adoption of more structured ways of writing code and more nuanced looping statements makes goto...kinda pointless.


generous_cat_wyvern t1_iyayncx wrote

>He advocated instead for what he called "structured programming" which is really just programming as anyone born after maybe 1964 understands it.

I don't know why this part made me laugh so much! But yeah, it was revolutionary at the time, but now it's considered very basic fundamentals.


Sloloem t1_iybi5pc wrote

Yeah I kindof had a moment when I realized that paper was so old it predates not only C, but also C's predecessor B...and we still talk about it. I'd worked in languages without loops before and actually had to use goto's and labels to reproduce the flow control of while and for loops when I was first learning so I just assumed the concepts had always existed in programming. It's a really interesting history how we got from doing math real fast to programming a world-wide near-real-time communications network so we can look at cat videos on the toilet. ...If you're into that sort of thing, I guess.


OldHellaGnarGnar2 t1_iyb9od3 wrote

This is the first explanation I've read about this topic that made me understand it.

The robots we have at work had their code written by an integration company we use. The first 1-2 hundred lines of each program is "where to go next", with a bunch of

>if (all these conditions match) GOTO {section that handles whatever is supposed to happen next}

It's always a huge pain whenever I'm writing new code to add or improve functionality, and trying to check that I didn't introduce any new possible states where it can't figure out where to go - because I have to jump from line 50 to 400 to 30 to 670 to 30 to 900 etc.

Having the function directly follow the "if" condition seems like it would make more sense.

Question for you: if I want to improve my coding skills (because I only took one class in school, and have just picked other stuff up as I go), would it be a good exercise to re-write all their code using the structure you've outlined? And/or if I'm trying to learn another language like python specifically, see if I can re-write it in that, so I can learn that syntax & commands at the same time?


Sloloem t1_iybovkb wrote

Yikes, I'd actually seen code kindof like that written by outsourced contractors for a financial services firm I used to work for. They created these "god" functions that ran through multi-step processes by wrapping the whole thing in a giant for loop and using If's on the iterator like if (i==1)... (i==2)... (i==3) to block each step. It really hampers extensibility.

> Question for you: if I want to improve my coding skills (because I only took one class in school, and have just picked other stuff up as I go), would it be a good exercise to re-write all their code using the structure you've outlined?

Assuming you're talking about re-writing the IF-GOTO code your robots use in more structured style, yeah absolutely. Changing the underlying implementation of some functionality while maintaining its public contract is actually the definition of "refactoring". Being able to cleanly refactor code and write code that's cleanly refactorable are actually the underlying goals of a lot of current best-practices in Object-Oriented programming so it's definitely an important skill to practice.

> And/or if I'm trying to learn another language like python specifically, see if I can re-write it in that, so I can learn that syntax & commands at the same time?

Porting code directly like that is an interesting activity but maybe something that's more of an intermediate activity once you have the fundamentals down. I thought this phrasing was kind of pompous when I first heard it but most languages have "idiomatic" ways of doing some things that is considered the correct way to write code in that language. Of course the languages are flexible enough that they would allow you port structure and style of another language's idioms to this new language, but those sorts of idiomatic patterns usually come out of some key feature of the language and have fundamental advantages in terms of code expressiveness or performance. So it's best to learn "Pythonic" ways of writing code that might be very different from how someone who'd trained as a Java or C++ developer would usually think of implementing them. Then once you feel like you can write Python, you can try re-implementing functionality that used to be written in some other language and paradigm in Python rather than trying to re-write some Java using Python. It's a slight language shift but I think it's a good way to frame it.

In a professional setting you're also unlikely to see a company trying to do a 1:1 re-write of an existing product. The switch in tech stack is usually driven by a desire to benefit from some killer feature of the new stack like NodeJS's fast async I/O or something else, and to do that you usually need to write idiomatically and respect the eccentricities of the language and the framework.


OldHellaGnarGnar2 t1_iyce8wd wrote

Thanks for the feedback! I've never heard of refactoring, but I guess that's exactly what I was trying to describe.

>In a professional setting you're also unlikely to see a company trying to do a 1:1 re-write of an existing product.

True, however my goal with trying to write it in another language wouldn't be for actual implementation; it would be to try to start learning a new language. I only really know Matlab and Fanuc TP (the robot language I was talking about). I'd like to learn a more widely used language so I can potentially open doors to more types of jobs than I'd currently be qualified for.


[deleted] t1_iycqx12 wrote



OldHellaGnarGnar2 t1_iycxv3j wrote

That makes sense. While I was thinking about how to do what we're talking about above, I hadn't yet come up with a solution to "what about when I need it to skip to the end for a mid-process cycle stop," and thought I still might need a GOTO for that, to exit the loop at those interruptions.


Sloloem t1_iyeh3if wrote

Controlling flow from inside loops is done with break and continue.

Something like this:

for (i=1;i<=10;i++) {
  if (i==5) SOMETHING
  print i;

If you use break for SOMETHING your output is: 1 2 3 4

If you use continue your output is: 1 2 3 4 6 7 8 9 10

Some languages let you control multiple levels of looping using something like break 2 to break not only this loop, but the loop it's inside. Javascript lets you do this with labels. Not all languages give you this level of control so you either figure out how to design the process without nested loops or come up with other ways around the issue like GOTO's or flag variables that direct outer loops to break when set from inner loops but those situations have no single right answer.


OldHellaGnarGnar2 t1_iyehcc0 wrote

Do these work similarly for while loops?


Sloloem t1_iyehp37 wrote

Oh yeah. Totally.


OldHellaGnarGnar2 t1_iyf5swx wrote

I'm not sure if I missed your link about breaks earlier, or if it was edited in, but I just now saw it, and it's super helpful. Our robot programs technically use "JMP LBL", not GOTO, but I basically took them as the same thing in terms of function. So it already has labels for each section if I were to restructure it to use nested loops and whatnot.

All of your comments have been super helpful. I've been wanting to learn more programming for a while, but wasn't sure what concepts or practices I'm not even aware of, and this gives me a lot to think about. I recently got the "Automate the Boring Stuff with Python" book, to use as a starting point, but am still kinda learning the syntax and python-equivalent commands of what I already know in Matlab of Fanuc TP, and haven't really gotten to stuff about code structures or paradigms, etc


Sloloem t1_iyf986x wrote

Sweet deal, glad I could help and good luck breaking in.

Actually I just scoped out some of your comment history and see you're working in CNC engineering and pop into physics and CAD subreddits a lot...I have an idea for a hand-cranked guitar pickup winder I'd like to design for 3d printing but for some reason I'm having a hell of a time getting my head around how to design the gearbox to multiply RPMs in a reasonable size. A guitar pickup involves upwards of 10,000 winds of a copper filament around the magnetic pole pieces. Motorized pickup winders tend to have speed controls from 600 to 2000 RPMs but for a hand-cranked machine 500RPM seems downright reasonable. We're talking <2oz balanced load. Is that something that might be in your wheelhouse that you could point me at some good resources or fundamentals about? Because I'd love to learn it.


Sloloem t1_iyeb96m wrote

I was speaking mostly to a mindset difference in how you approach the new language.

You'll be better at Python in the long run if you start from the description of what a program is supposed to do and treating the original code itself as a black box rather than trying to translate Matlab syntax to Python syntax because knowing the language is more than just knowing the syntax, you need all those idiomatic expressions. Python has some interesting collection structures and ways of manipulating those that I don't know if Matlab has direct equivalents for, so learning how to use them is just as much of learning Python as learning the syntax.

Honestly being curious about how programming works at all is a trait I wish more developers had so that puts you above half the people I've interviewed for jobs.


OldHellaGnarGnar2 t1_iyeh3yo wrote

Ahh, ok that makes a lot of sense. So, rather than doing a one-to-one translation, figure out how I can take advantage of python's capabilities vs whatever language I'm trying to convert code from.

Secondary question:

Is your comment related at all to programming paradigms? Like, I think all the code I know how to write would be considered "functional" (I didn't learn anything about paradigms in school), so after seeing some discussion on paradigms and watching some videos, I'm trying to understand "when would I use object-oriented" or another paradigm. So maybe if I learned to write in a different paradigm, it could be a better fit than what I'd be able to write in functional?


Sloloem t1_iyeqfi9 wrote

Yeah exactly, to both points. Learning how to do similar things under different paradigms is a great skill because it keeps you from getting too stuck on one way to approach a problem but learning all the available paradigms is mostly an academic exercise. You can learn the paradigms to identify their influences on languages but unless you're going into language design or academia they can be pretty esoteric. Not very many languages are purely single-paradigm. Most languages take influence from multiple paradigms and include features from those that designers like, creating fairly unique ways of expressing program instructions.

Example off the top of my head would be something like Scala. Scala adds features of the Functional paradigm to the Java language which is very Object-Oriented in its design. So if you're writing Scala you can write it like OO code, Functional code, or a mix of both. Scala idioms prefer Functional approaches so if you use those you tend to write less code and stuff runs better but you can also work with objects and gain some benefits of OO concepts like function encapsulation.

Python is another language that takes hints from Functional programming and OO programming, but implements its objects and classes very differently from how Java does it.


SuperBelgian t1_iye7700 wrote

There could be a reason for such a structure. Financial institutions often still have very old esoteric hardware, such as mainframes. (Even if not actively used, they still need to keep it functional to access archived data.)

Just, because you can program and compile something without errors, doesn't mean it will run correctly.
Nested functions, calling a function within a function, which calls a function, etc... is a very common way of doing things.
However, some CPUs have a limit on how deep such a stack can go, going as low as to only 4 or 8 stacks deep. (Ex: Arduino.)
Very old hardware doesn't even have such a stacking possibility that allows nested functions.


Sloloem t1_iyed84i wrote

That's all true, you're absolutely right. I was just trying to keep my anecdote from getting too lengthy by leaving out this case the code in question was written in Java in 2009 and running on IBM WebSphere on contemporary datacenter hardware so there were really better ways to have laid it out. Maybe the robots are stack limited which makes sense, but refactoring it is still a good thought experiment if nothing else.


Unable-Fox-312 t1_iycdti9 wrote

If you can get paid for it, definitely.

You should read the basic docs for your language first, though. Find out what people consider the book and study it, then take on that project in bitesize chunks with tangible goals. See if you can refactor 5% of the functionality and still have a working robot. Then 10%. If you plan to flip a switch and go from 0 to 100 on the job you're setting yourself up for a forever project and ultimately failure


OldHellaGnarGnar2 t1_iycf6rr wrote

>If you can get paid for it, definitely.

>If you plan to flip a switch and go from 0 to 100 on the job you're setting yourself up for a forever project and ultimately failure

If I were to refactor the code, I'm not sure it would ever actually be implemented. The robots have been working correctly for a few years, so I doubt management would want to "fix" what isn't broken, and potentially mess what has already been working.

If I did this, I think it would purely be an exercise for me to get better at coding. After a couple years at this job, it turns out I like writing code more than almost anything else, but that's a really small part of my current job - so my goal would be more of "get better at programming and/or learn a new language, so I can be more employable in positions that are more programming-focused"


Kriemhilt t1_iycsjrt wrote

The normal term for "the burden of working with rubbish code that is hard to understand or change" is technical debt.

One of the advantages of calling it that is that it sounds sort-of like financial debt, so you're putting it in language management might find easier to understand. You ideally want some concrete motivation though, like

>"technical debt will make it slower (and therefore more expensive) to add these features you want, but if we invest in reducing our technical debt first, those features will arrive sooner and have fewer bugs."

If they don't have any bugs to fix or features to add, this obviously doesn't help you much!


OldHellaGnarGnar2 t1_iycyqk2 wrote

Good advice!

>If they don't have any bugs to fix or features to add, this obviously doesn't help you much!

But that's the issue I think I'll have if I try to push it. Our robots generally just work as-is, and most of what we have to add is parameterized, so we're mostly filling in variables and not actually writing code. Actually writing new code for bug fixes or new functionality is pretty rare (I think I'm the only one that's learned how to do it since our division implemented robots).

About a year ago (first time I actually wrote new functionality for them), my boss and I had to convince management I was capable of adding in a new safety feature that got brought up as something we should do.


Symbian_Curator t1_iycacc6 wrote

I just want to point out, GOTO is not completely pointless, but the industry is used to repeating how GOTO is terrible without thinking much about the reasons, the reasons being as you pointed out, but also, valid uses for GOTO are so few and far between that it's just easier to teach new programmers to simply never use it.

About those valid uses:

  • In C, to mimic the destructor behaviour of C++ in function. For example, let's say that in function F you have: initialize resource A, initialize resource B, initialize resource C, do some work, clean u C, clean up B, clean up A. Then, in the code, you would try to init A, and if it works, carry on, but if not, exit the function. Try to init B, and if it works, carry on, but if not, GOTO "clean up A" part. Try to init C, and if it works, carry on, but if not, GOTO "clean up B" part. When you GOTO like this, the code "falls through" to clean up only the resources which were initialized. I was told that this technique is used widely in the code of the Linux kernel, but honestly I haven't bothered to check myself.
  • With some compiler extensions, computed GOTOs (where you can take the address of a GOTO label, put it in a lookup table, and jump based on some index) present a optimization opportunity for performance critical code, notably interpreters for other languages or bytecode of other languages. (it's similar to switch/case, just faster)

Deadmist t1_iycd9gz wrote

> In C, to mimic the destructor behaviour of C++ in function.

That doesn't mean using GOTO isn't bad, it just means that there is no better option in C.
In 'modern' languages, like C++ or Java, you can achieve the same outcome with destructors or try-with-resources, without the pitfalls of GOTO.


Symbian_Curator t1_iyce7cl wrote

I agree, but sometimes you just have to use C and then you use the tools you have. A bad tool is better than no tool at all.

My main point was that GOTO is not always pointless/useless.


Clewin t1_iyd736l wrote

Speaking of, one of the biggest uses of GOTO I saw in C was for exception handling. C++ as well, until try-catch blocks were added (and that varied by compiler until the late 1990s, early 2000s).


Liese1otte t1_iyd0xn1 wrote

Yea, this. GOTO is not neccessarily a bad thing. It's a thing. More popular codebases (mostly lower level) use GOTOs than people think. It can be handy in rare cases when you are in control and using GOTO won't actually hurt readability / predictability.

It's just that it's really easy to fuck up when using GOTO so you might as well just not at all (especially when you are not an expert on how things tend to work with it).

Same can be applied to other commonly accepted opinions, like using "eval"-type commands.


Sloloem t1_iyefdj8 wrote

Some languages also kindof have you using GOTOs and labels for exception handling...I wanna say Visual Basic? I did a project a few years ago using CrownPeak CMS which at the time I think used VB for its templating language and I vaguely recall winding up with a lot of really snotty "ON ERROR GOTO HELL" clauses. I think some legacy data applications that had a lot of functionality written in SQL procedures used that sort of error handling instead of more modern try-catch-finally or try-with-resources blocks. It's all true but I don't think I'm inaccurate in saying they're pretty niche edge cases for most programmers.


Symbian_Curator t1_iyefzmc wrote

At this point, Visual Basic itself is a niche edge case :D


Sloloem t1_iyehs4b wrote

And we're all the better for it being that way.


Mike2220 t1_iyc605t wrote

>And without another GOTO to send you back to where you left off, you'll just keep going from wherever you ended up until the program exits or crashes.

jal and jr have entered the chat


Sloloem t1_iyebsgt wrote

Man I am not gonna throw down with an assembly programmer. They scare me a little, flying so close to the sun.


Mike2220 t1_iyehm15 wrote

I needed to learn it for a few classes

It was a time


Sloloem t1_iyes9ij wrote

Heh. I graduated in 2009 and we still had some assembly in my degree program. It wasn't even being taught in a specific CPU's assembly language at that point, they had invented some assembly-like language to teach us about registers, bitmath, and jumps but it was actually interpreted by a Java CLI tool that produced the output.

I think it was just there to teach us how good we have it working at higher levels of abstraction.


Mike2220 t1_iyezgz8 wrote

Oh we had to do stuff with MIPS on one of those development boards

Took like 10 tries to actually upload the program to it even if your code worked, it sucked


Coincedence t1_iyclmnt wrote

There are certain situations where GOTO makes sense. I've had to use once or twice to do thins like restart a loop arbitraily where you have go back to a parent loop that may be 3 or 4 times removed. Its not ideal, and in nearly every case there are better alternatives, but GOTO is still valid sometimes


Chasman82 t1_iyd959l wrote

Very clear answer. It resulted in a major improvement in programming quality, since it was easier to debug and maintain. I recall that either Dijkstra or someone else illustrated the point by building some code to perform a simple task but using COME FROM instead of GOTO. The code was incredibly difficult to understand and drove the point home.


Sea_no_evil t1_iydi3g8 wrote

Yes. IOW, Goto is a primitive instruction not too far removed from the assembly language -- the native language of the chipset itself. As programming languages get more sophisticated, the need for goto goes away. The fact that most languages still have a goto instruction is really more about history than function.


cabbeer t1_iyd86ow wrote

Wow, you’re really good at explaining programming… what would go to look like in JavaScript? Or is that not possible because it’s single threaded?


Sloloem t1_iydwukt wrote

GOTO would work fine in a single threaded environment, you can't use it in javascript just because javascript doesn't have a GOTO statement. If it did it would probably look the same as it does anywhere that does have it where you pair GOTO some_label with a line of code reading :some_label to give the GOTO a target line. Not sure why they didn't include it.