News for hackers. Stuff that matters.
Re:GOTOphobia Considered Harmful (In C) by mort96 on Sunday February 26, 2023 @06:09PM (#34950692)
To give people some kind of an idea of what it was created in response to: Imagine writing an entire program in one single main function. The only thing you're allowed to do for flow control is goto. You can do 'goto somelabel;' for an unconditional goto, or you can do 'if (somecondition) goto somelabel;' for a conditional goto. Here's some examples of how it would look if if translated to something C-like:

Loops would look like:

    int i = 0;
    loop_start:
    print i;
    i = i + 1;
    if (i < 10) goto loop_start;
Fizzbuzz would look something like:

    int i = 0;
    loop_start:
    if (i % 5 != 0) goto not_fizzbuzz;
    print "fizzbuzz";
    goto done;
    not_fizzbuzz:
    if (i % 3 != 0) goto not_fizz;
    print "fizz";
    goto done;
    not_fizz:
    if (i % 5 != 0) goto not_buzz;
    print "buzz";
    goto done;
    not_buzz:
    print i;
    done:
    i += 1;
    if (i < 100) goto loop_start;
Often, this wasn't just constrained to a single function; the whole program would be constructed like this, with gotos which jump back and forth across pages and pages of code. Languages wouldn't even have a call stack with subroutines (which is why "procedural" languages -- languages with procedures -- were important enough to be given a special name).

At least that's my understanding of it. I haven't lived through this, and my only experience with this kind of stuff is writing assembly, where we always make use of a call stack, so even that is in practice a procedural language. If I have gotten anything wrong, please correct me.

Re:GOTOphobia Considered Harmful (In C) by fsckboy on Sunday February 26, 2023 @07:38PM (#34951513)
tangentially, can somebody point me to what are considered the best fizzbuzz solutions? I'm both an experienced and cs-educated coder, and I know what I would consider to be a good solution, but I have no idea what the rest of "you" are looking for. (my favored solution would be a small number of state machines running in parallel to sieve-of-eratosthenes the correct answers thus avoid innumerable divisions, but maybe that's just me and I'm old fashioned?)
Re:GOTOphobia Considered Harmful (In C) by anonymoushn on Sunday February 26, 2023 @11:43PM (#34953059)
Surely your compiler won't actually emit an integer modulus if you tell it to mod by a constant?
Re:GOTOphobia Considered Harmful (In C) by _kst_ on Monday February 27, 2023 @01:00AM (#34953520)
I don't claim to have the best, or even good, fizzbuzz implementations, but if you're looking for a lot of fizzbuzz implementations:

https://github.com/Keith-S-Thompson/fizzbuzz-c

https://github.com/Keith-S-Thompson/fizzbuzz-polyglot

Re:GOTOphobia Considered Harmful (In C) by zozbot234 on Sunday February 26, 2023 @08:10PM (#34951748)
The loop you posted is a do-while loop; the while loop has a somewhat less intuitive translation to GOTO:

  loop_test: IF (NOT loop_condition) GOTO after_loop
    loop_body
    GOTO loop_test
  after_loop: etc...
Re:GOTOphobia Considered Harmful (In C) by dheera on Monday February 27, 2023 @12:12AM (#34953239)
Not too far from assembly ...
Re:GOTOphobia Considered Harmful (In C) by mort96 on Monday February 27, 2023 @04:51AM (#34954664)
Almost, except in assembly, we always have a call stack. So even assembly is a procedural language, even though it doesn't otherwise have structured control flow.
Re:GOTOphobia Considered Harmful (In C) by _kst_ on Monday February 27, 2023 @12:56AM (#34953506)
Could be worse.

https://github.com/Keith-S-Thompson/fizzbuzz-c/blob/master/f...

    #include <stdio.h>
    #include <setjmp.h>
    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);
        if (j == 1) longjmp(jb[5], 0);
        if (j == 0) setjmp(jb[2]);
        if (j == 1) puts("Fizz");
        if (j == 1) longjmp(jb[5], 0);
        if (j == 0) setjmp(jb[3]);
        if (j == 1) puts("Buzz");
        if (j == 1) longjmp(jb[5], 0);
        if (j == 0) setjmp(jb[4]);
        if (j == 1) puts("FizzBuzz");
        if (j == 0) setjmp(jb[5]);
        i ++;
        if (j == 1) longjmp(jb[1], 0);
        if (j == 0) setjmp(jb[6]);
        j ++;
        if (j  < 2) longjmp(jb[0], 0);
    }
Re:GOTOphobia Considered Harmful (In C) by ziml77 on Monday February 27, 2023 @01:41PM (#34960250)
I am sobbing in pain at that atrocity.
Re:GOTOphobia Considered Harmful (In C) by _kst_ on Monday February 27, 2023 @03:50PM (#34961684)
I live to serve.
Re:GOTOphobia Considered Harmful (In C) by int_19h on Monday February 27, 2023 @04:56AM (#34954683)
Procedural or not was more of a spectrum. If you look at early BASICs, for example, they had GOSUB, and it could recurse, so there was a return-address stack. But GOSUB did not have any provisions to pass arguments or return values - it was just a GOTO that remembered where it came from; you had to use globals to pass data around. So if you wanted a data stack (i.e. locals), you had to rig your own with arrays.

OTOH early FORTRAN had procedures with arguments and results, but no recursion.

Structural or not was also not necessarily all-in. FORTRAN and BASIC both had for-loops before they had structured conditionals.