Live data from Hacker News

GOTOphobia considered harmful in C

blog.joren.ga

291–300 of 319 posts

Re: GOTOphobia considered harmful in C

#291

Earlier quoted context omitted.

or maybe its that things like a kernel reasonably need to use goto? or at least at the time it was written, there werent alternatives that were performant enough.

Either is more charitable, and both are probably closer to the truth. FYI: 4,879 code results in illumos/illumos-gate for goto 2,587 code results in freebsd/freebsd-src for goto It's not like any comparable project is immune? Perhaps `goto` says more about how old the code is?

I don't see how the number of goto's is relevant. You're still having alot of goto's in each function in the codebase with SESE and only using one goto location, solely for cleanup and exit.

Re: GOTOphobia considered harmful in C

#292
post #259

Earlier quoted context omitted.

Where in the world beginners use state machines instead of switch statement or if ladder? this is genuine question, because I do believe that people do not use enough state machines to model their systems.

Usually as a simple menu system, see e.g. https://github.com/sokrateshayraniyim/Your-Own-Library/blob/...

is still switch

Re: GOTOphobia considered harmful in C

#293
post #289
post #220

Earlier quoted context omitted.

Could be worse. https://github.com/Keith-S-Thompson/fizzbuzz-c/blob/master/f... #include #include int main(void) { jmp_buf jb[7]; volatile int j = 0; setjmp(jb[0]); volatile int i = 1; if (j == 0) setjmp(jb[1]); if (j == 1 && i > 100) longjmp(jb[6], 0); if (j == 1 && i % 15 == 0) longjmp(jb[4], 0); if (j == 1 && i % 3 == 0) longjmp(jb[2], 0); if (j == 1 && i % 5 == 0) longjmp(jb[3], 0); if (j == 1) printf("%d\n", i);…

I am sobbing in pain at that atrocity.

I live to serve.

Re: GOTOphobia considered harmful in C

#294

Earlier quoted context omitted.

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…

> GOTO is a BREAK (could always be substituted for one), but a BREAK is not a GOTO.

You wrote this backwards, but you seem to understand the relationship and that GOTO is more general. That is, every BREAK is a GOTO (because you can always substitute a GOTO), but every GOTO is not a BREAK (i.e., you can't substitute a BREAK for some GOTOs because BREAK cannot jump to an arbitrary label).

Re: GOTOphobia considered harmful in C

#295

Earlier quoted context omitted.

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 qu…

See my other reply. GOTO is the generic type because it can be used to jump anywhere. BREAK/CONTINUE are sub-types because they are limited in where they can jump. BREAK/CONTINUE can be always implemented using GOTO, but not the other way around.

I agree that BREAK/CONTINUE are not syntactic sugar in languages that don't have GOTO.

Re: GOTOphobia considered harmful in C

#296

Earlier quoted context omitted.

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…

> GOTO is a BREAK (could always be substituted for one), but a BREAK is not a GOTO. You wrote this backwards, but you seem to understand the relationship and that GOTO is more general. That is, every BREAK is a GOTO (because you can always substitute a GOTO), but every GOTO is not a BREAK (i.e., you can't substitute a BREAK for some GOTOs because BREAK cannot jump to an arbitrary label).

No, I wrote it in exactly the order I wanted to. Because of the substitution property that you acknowledge, GOTO is a subtype of BREAK. BREAK is not a subtype of GOTO because it cannot always be substituted for GOTO. Thus, "GOTO is a BREAK, but a BREAK is not a GOTO."

A GOTO is just one possible implementation of BREAK, just as a cat is one possible implementation of an animal.

The practical impact of this is that it is incorrect to ascribe to BREAK the same weaknesses as GOTO, because BREAK is not a GOTO.

Re: GOTOphobia considered harmful in C

#297

Earlier quoted context omitted.

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 qu…

See my other reply. GOTO is the generic type because it can be used to jump anywhere. BREAK/CONTINUE are sub-types because they are limited in where they can jump. BREAK/CONTINUE can be always implemented using GOTO, but not the other way around. I agree that BREAK/CONTINUE are not syntactic sugar in languages that don't have GOTO.

No, you're still mixing up the subtype relationship.

Type X is a subtype of type Y if and only if an instance of X can always be used where an instance of Y is required.

GOTO can always be used to replace a BREAK. Therefore GOTO is a subtype of BREAK.

BREAK cannot always be used to replace a GOTO. Therefore BREAK is not a subtype of GOTO.

The inheritance relationship here is not single, it's multiple: a GOTO is a BREAK, but it is also a CONTINUE and a whole lot of other things. It's like a monster class that inherits from every interface under the sun and can do just about anything.

Dijkstra was basically advocating for refactoring our languages to extract those capabilities into smaller, more focused keywords (as well as dropping most of the functionality). Rather than having one keyword implement both the BREAK and CONTINUE interfaces, we break them out into separate keywords.

Re: GOTOphobia considered harmful in C

#298

Earlier quoted context omitted.

See my other reply. GOTO is the generic type because it can be used to jump anywhere. BREAK/CONTINUE are sub-types because they are limited in where they can jump. BREAK/CONTINUE can be always implemented using GOTO, but not the other way around. I agree that BREAK/CONTINUE are not syntactic sugar in languages that don't have GOTO.

No, you're still mixing up the subtype relationship. Type X is a subtype of type Y if and only if an instance of X can always be used where an instance of Y is required. GOTO can always be used to replace a BREAK. Therefore GOTO is a subtype of BREAK. BREAK cannot always be used to replace a GOTO. Therefore BREAK is not a subtype of GOTO. The inheritance relationship here is not single, it's multiple: a GOTO is a BRE…

We apparently disagree on whether the general, flexible construct is the subtype or whether the specific, constrained construct is the subtype. You seem to be thinking from a object-oriented programming class hierarchy perspective, while I am thinking from a set theory perspective (i.e, the set of operations that can be done with GOTO is a superset of those that can be done with CONTINUE or BREAK).

At this point, I don't care which you call the subtype. You can claim that as a win if you want, but having spent so much time on this stupid thread I think we've both lost.

Re: GOTOphobia considered harmful in C

#299

Earlier quoted context omitted.

No, you're still mixing up the subtype relationship. Type X is a subtype of type Y if and only if an instance of X can always be used where an instance of Y is required. GOTO can always be used to replace a BREAK. Therefore GOTO is a subtype of BREAK. BREAK cannot always be used to replace a GOTO. Therefore BREAK is not a subtype of GOTO. The inheritance relationship here is not single, it's multiple: a GOTO is a BRE…

We apparently disagree on whether the general, flexible construct is the subtype or whether the specific, constrained construct is the subtype. You seem to be thinking from a object-oriented programming class hierarchy perspective, while I am thinking from a set theory perspective (i.e, the set of operations that can be done with GOTO is a superset of those that can be done with CONTINUE or BREAK). At this point, I d…

[deleted]

Re: GOTOphobia considered harmful in C

#300

Earlier quoted context omitted.

> comment lines before subroutines would help. That code looks normal to me. I have a ton of BASIC books and magazines. You're talking about a time period before full screen text editors were a thing. It's almost impossible to explain to anyone that didn't have to work with TI-99 BASIC, C64 BASIC, GW-BASIC/BASICA, etc. what it was like. Once you got to QBASIC/QuickBASIC it was done. Life was easy. A few years before…

Wasting RAM on REM’s was just rookie stuff. I remember chasing bytes with short variable names, abbreviated print statements, reducing spaces as much as possible etc. I had like 28k to play with and I was 14 years old!

I remember in Commodore basic, finding that a period by itself ('.') was parsed as zero, but was actually slightly faster than using zero, and saved a byte every time it was used. In other words, you could write:

    10 for i = . to 6.28 step 0.1:next
and it would be slightly faster and smaller than

    10 for i = 0 to 6.28 step 0.1:next
Made for some ugly inner loops, but you gotta do what you gotta do. For that matter, we certainly would have removed some of those extra spaces as well. Bytes mattered and whitespace slowed you down.
Post reply on HN