Live data from Hacker News

GOTOphobia considered harmful in C

blog.joren.ga

271–280 of 319 posts

Re: GOTOphobia considered harmful in C

#271
I find it similar to the MISRA rules that says there should only be a single return in a function.

We make an exception for this at work for checks at the start of a function (eg. NULL, ranges, etc.) and it tends to save an indentation or two. Then generally still follow the single return rule otherwise.

Re: GOTOphobia considered harmful in C

#272

Earlier quoted context omitted.

If you code in that style you won't even notice the borrow-checker is there. Unless you have a bunch of shared global state, the the overhead of arc will seem silly on your single core uc.

That kind of style is often correlated with a lot of shared global state, even in relatively high level software like database engines. Most software avoids shared global state by delegating that implementation to the operating system, which often comes at the cost of performance.

I have worked in embedded code bases like that. While some of it is unavoidable for io, I have worked in other codebases where the compile time allocated memory was moved around in a way that would have satisfied the borrow checker except for that first mutable borrow. I haven't done rust for uc yet, so I won't claim it is a good fit, but it didn't seem like the parent poster had either, and I think there is a decent chance it could work well of the tooling is there. Which I'm not sure it is.

Re: GOTOphobia considered harmful in C

#273

Earlier quoted context omitted.

Not in the Dijkstra "Go to statement considered harmful" sense. Nor are the goto keywords found in most modern languages. These retain structure and thus are not considered harmful. But there is a good case to be made that exception handlers are gotos in the Dijkstra sense, at least when used for anything other than exceptions, like passing errors around.

If you read Dijkstras letter it is clear that early returns (ie any return which is not the last statement in a function) is subject to the same criticism as goto. > These retain structure and this are not considered harmful This might be your opinion, and it is a very reasonable opionin. But it is just not what Dijkstra is arguing. He is very clearly arguing for “single entry single exit”.

> He is very clearly arguing for “single entry single exit”.

Agreed. Return forces you into a single exit. Upon hitting return, the code can only return back to where the function was originally called. It cannot 'arbitrarily' jump to some other place in code as you could do in an unstructured programming language like, say, BASIC. Which is what Dijkstra was pushing for, being a strong proponent of structured programming.

I don't know of any modern programming language that does allow anything outside of a single exit, exception handlers and setjmp/longjmp excepted. There is a good case to be made that the latter two reintroduce the very problem Dijkstra warned of and are generally considered harmful for the same reason.

Re: GOTOphobia considered harmful in C

#275
post #132

Earlier quoted context omitted.

What language do you think Linux and Arduino should be programmed in?

If it was created today? I’d go for Rust and Python respectively

Guess what Python is written in.

https://stackoverflow.com/a/9451956

Re: GOTOphobia considered harmful in C

#276

Earlier quoted context omitted.

If you read Dijkstras letter it is clear that early returns (ie any return which is not the last statement in a function) is subject to the same criticism as goto. > These retain structure and this are not considered harmful This might be your opinion, and it is a very reasonable opionin. But it is just not what Dijkstra is arguing. He is very clearly arguing for “single entry single exit”.

> He is very clearly arguing for “single entry single exit”. Agreed. Return forces you into a single exit. Upon hitting return, the code can only return back to where the function was originally called. It cannot 'arbitrarily' jump to some other place in code as you could do in an unstructured programming language like, say, BASIC. Which is what Dijkstra was pushing for, being a strong proponent of structured program…

Dijkstra is not just arguing all exits should return to the same point, but also that you shouldn’t enter or exit in the middle of a block. Execution should consist of executing blocks zero or more times, but either fully or not at all.

Exiting in the middle of a block would be just as bad as entering in the middle, according to the argument he is making.

Re: GOTOphobia considered harmful in C

#277

Earlier quoted context omitted.

Yes, it's all compiled to jumps... The point of the discussion is that things like continue and break are easier to read and reason about because they can't just jump anywhere .

My point was to contest GP's assertion that CONTINUE and BREAK were not equivalent to GOTOs. I agree that CONTINUE and BREAK are easier to reason about because you can look at them and instantly know what they do without having to look up what label they're jumping to.

My point is that it's meaningless to make the argument that CONTINUE and BREAK can be implemented with GOTO, because every control flow structure can be. That you could use a GOTO to implement them isn't in question, what's in question is if you could do the reverse.

It's a subtyping problem, and you have the is-a relationship backwards: a cat is an animal but not every animal is a cat. GOTO is a BREAK (could always be substituted for one), but a BREAK is not a GOTO.

When you need a BREAK you could implement that in terms of GOTO, but no amount of coercion will allow you to use a BREAK as a generic GOTO.

Re: GOTOphobia considered harmful in C

#278

Earlier quoted context omitted.

CONTINUE and BREAK are quite different from GOTO in that they operate predictably given the current scope: their limitations make them incapable of creating the unstructured nightmare that Dijkstra was talking about. They're similar to a GOTO only in that they compile to a jump, but so do IF statements and FOR loops. Structured programming wasn't about eliminating jumps, it was about enforcing discipline in their use…

> CONTINUE and BREAK are quite different from GOTO in that they operate predictably given the current scope CONTINUE, BREAK, and GOTO all operate predictably because they are deterministic operations. Each continues program execution at the directed explicit (goto) or implicit (continue or break) offset. There is no non-deterministic or unpredictable behavior whatsoever.

Predictably may have been the wrong word, because that does imply non-determinism. It might be better to say that CONTINUE and BREAK are limited: given a scope, the keyword can take you to exactly one place, while GOTO could be used to take you anywhere, and you have to go hunting for the corresponding label to find that place.

Re: GOTOphobia considered harmful in C

#279

Earlier quoted context omitted.

Not too many things make me shake my head harder than folks who consider continue/break to be GOTO equivalents. For the reasons you eloquently said. Additionally, far more often than not, continue/break allow you to avoid another form of complexity, bugs, and low comprehensibility: deeply nested conditionals.

CONTINUE and BREAK are simply jumps to the beginning of or just past the end of the current loop context. They are equivalent to GOTOs to particular program offsets without the programmer needing to create labels for those offsets. They do not have any magical meaning beyond that. You could even call them syntactic sugar.

They're not syntactic sugar in any language that does not have GOTO, because the semantics of GOTO-free languages don't allow arbitrary jumps, so there is no equivalent syntactic structure that you can compile BREAK to.

The distinction matters because the whole premise of Dijkstra's argument is that if you replace the GOTO keyword with a bunch of more limited versions that cannot be used to produce spaghetti, code quality would go up. The only way for that to work is for the language to be semantically incapable of expressing GOTO.

As I said in my other reply, you seem to have the subtyping relationship wrong: GOTO is a subtype of BREAK (anywhere you find a BREAK you could replace it with GOTO), but BREAK is not a GOTO (you cannot do the reverse).

Re: GOTOphobia considered harmful in C

#280

Earlier quoted context omitted.

> He is very clearly arguing for “single entry single exit”. Agreed. Return forces you into a single exit. Upon hitting return, the code can only return back to where the function was originally called. It cannot 'arbitrarily' jump to some other place in code as you could do in an unstructured programming language like, say, BASIC. Which is what Dijkstra was pushing for, being a strong proponent of structured program…

Dijkstra is not just arguing all exits should return to the same point, but also that you shouldn’t enter or exit in the middle of a block. Execution should consist of executing blocks zero or more times, but either fully or not at all. Exiting in the middle of a block would be just as bad as entering in the middle, according to the argument he is making.

You certainly wouldn't be the first to hold that view.

However, Dijkstra accepts abortion clauses, which is what return really is (it is not an exit clause). My take is that his argument is that an unbridled go to is too primitive and that he believed go to statements should be bridled by additional structure that help describe the process, not that go to should be avoided entirely.

While I think we can agree that return is go to, it is a bridled go to. It strictly limits what a programmer can do, avoiding the mess Dijkstra claims an unbridled go to promotes. It is predictable and understandable, clearly describing the intent.

Exception handlers have no such strictness. It is not clear, without studying the program in its entirety, where your code will end up. That can be a good tradeoff when you are dealing with exceptions. The only reasonable response to encountering an exception is to ultimately crash, so at that point who cares? But, indeed, using exception handlers for control flow (e.g. passing errors around) is considered harmful.

Post reply on HN