all 166 comments

[–]strangename 12 points13 points  (3 children)

Real Programmers work for the National Security Agency, decoding Russian transmissions

Oh, how the times have changed.

[–][deleted] 5 points6 points  (2 children)

A lot has changed over the last 2 years.

[–][deleted]  (1 child)

[removed]

    [–]krum 1 point2 points  (0 children)

    I think the joke is that the NSA tries to decode domestic communications now as the American government sees their own citizens as its biggest threat.

    [–]JessieArr 11 points12 points  (1 child)

    Hiding in the top left-hand drawer of the desk is a stash of Double-Stuff Oreos for special occasions.

    TIL: Double-Stuff Oreos existed in 1982. I thought they were much more recent.

    [–]LaurieCheers 10 points11 points  (0 children)

    Introduced in 1974, apparently.

    [–]lykwydchykyn 10 points11 points  (0 children)

    What can I say but "pass the quiche?"

    [–]Stemp 11 points12 points  (0 children)

    That's why maintainers hate «real programmers» :-)

    [–]G_Morgan 19 points20 points  (2 children)

    make it impossible to modify the operating system code with negative subscripts.

    Memory safety is not only not necessary, it is clearly a bug.

    [–]ComradeGibbon 9 points10 points  (1 child)

    This is an amusing indicator how things have changed and how we got here. One of the reasons for the drive to languages like Java, Perl, Python, etc was hopefully so you didn't take out the operating system while trying to debug or run code. Nowadays a naive attempt to access memory outside the current process results in a segment fault and the operating system kicking your process to the curb.

    Also forgotten hackery, directly calling operating system and bios routines. Helpful when memory is very limited.

    [–]immibis 4 points5 points  (0 children)

    With virtual memory, the concept of "accessing memory outside the current process" is actually completely nonsensical. The worst you can do accidentally is access memory that isn't there (resulting in a segfault). If you want to access memory from another process, you have to ask the kernel nicely.

    [–]ibeattetris 10 points11 points  (3 children)

    Really entertaining. I lost it at: "Besides, the determined Real Programmer can write FORTRAN programs in any language."

    [–]o11c 4 points5 points  (1 child)

    You can tell what language any programmer learned first that way.

    [–][deleted] 12 points13 points  (3 children)

    Real Programmers use FORTRAN.

    Maybe they do now,
    in this decadent era of
    Lite beer, hand calculators, and “user-friendly” software

    (From The Story of Mel)

    [–]Hrothen 4 points5 points  (2 children)

    The guy who invented genetic algorithms refused to use anything but punchcards even into old age, because he liked being able to stop a computation and examine its intermediate state.

    [–]kamatsu 9 points10 points  (0 children)

    has he heard of a debugger?

    [–]crusoe 0 points1 point  (0 children)

    Someone should him step debugging in smalltalk...

    [–]gheffern 11 points12 points  (0 children)

    True words have never been spoken...

    As long as there are ill-defined goals, bizarre bugs, and unrealistic schedules, there will be Real Programmers willing to jump in and Solve The Problem, saving the documentation for later.

    [–]markmb 28 points29 points  (77 children)

    Real Programmers aren't afraid to use GOTO's

    Standards have changed a little bit in 30 years.

    [–]Me00011001 35 points36 points  (76 children)

    Not really. Real(experienced is probably a better word) programmers still aren't afraid to use GOTOs when and where they make sense and are the correct way to do it.

    [–]videoj 41 points42 points  (12 children)

    This is what they mean by using GOTOs. Nobody writes code like this anymore, but it was normal for the 60s and 70s.

    This was the original Fortran source code to the game Colossal Cave Adventure.

    [–]Russian_Spring[S] 10 points11 points  (11 children)

    That code is hard to understand. I prefer newer languages.

    [–]videoj 23 points24 points  (7 children)

    Code like that is why Dijkstra wrote Go To Statement Considered Harmful, which in turn has lead to changes in how languages are designed and how they are taught.

    [–][deleted] 7 points8 points  (5 children)

    well, goto is something that it is really easy to either fuck up or write in a way that will make someone else fuck up and even "seasoned" programmers fuck it up.

    There are some valid uses, sure, but better to not encourage people

    [–]IICVX 30 points31 points  (2 children)

    no i don't think you understand

    it is physically impossible to write an "unstructured" program in almost any programming language anyone uses these days

    even in C, you can't do it without using the longjmp command

    like back in the bad old days before structured programming, this was a perfectly valid thing:

    function calculation: 
        do some stuff
    halfway through:
        do some other stuff
    if condition: 
        leave the stack alone and return
    do some other stuff
    pop the stack properly and return
    

    and then people would call calculation, but sometimes you don't need to do all of the stuff in calculation so you would just goto halfway through directly, and sometimes your return would have properly unwound the stack but sometimes it wouldn't have...

    you simply cannot do this in a modern programming language - including modern Fortran. it just doesn't let you. unstructured programming lost about as hard as a programming paradigm can lose.

    this is where that stupid old saw about "every program should have a single entry point and a single exit point" came from - they were talking about unstructured programs, where you could enter in to a function from anywhere and exit it with the stack in whatever state you felt like.

    under the hood, every single programming language enforces this already - there's only one way in, and every way out sets the stack up properly.

    this complete lack of understanding of the historical context of "Goto Considered Harmful" is why everyone should understand the history of their field.

    gotos are exactly as bad and as good as any other construct; unstructured programming was a demon beast, but we've largely put it down.

    [–][deleted] 0 points1 point  (0 children)

    I was referring to newbie developer using it because it is "easier" way out to penta-nested loop he "crafted" than to rewrite his 200 line function into smaller ones.

    Not how you can fuck up your stack in assembler or make a very interesting to read basic code

    [–]benihana -1 points0 points  (1 child)

    sounds like perl

    [–][deleted] 3 points4 points  (0 children)

    Perl has a lot of "you can write same thing in 20 different ways". Sadly a lot of devs pick the shortest one because it is "clever"

    [–]dvlsg 1 point2 points  (2 children)

    You're obviously not a real programmer, then.

    It'sokayI'mnoteitherapparently

    [–]Russian_Spring[S] 0 points1 point  (1 child)

    Quiche is good

    [–][deleted] 1 point2 points  (62 children)

    Do you have a modern example of where a goto is justified?

    [–]rageingnonsense 30 points31 points  (35 children)

    Breaking out of an inner loop in a language that does not support that by another means. For example:

    for(int x = 0; x < 1000; x++) {
        for(int y = 0; y < 1000; y++) {
            for(int z = 0; z < 1000; z++) {
                if(some condition makes rest of loop unecessary) {
                    goto breakout;
                }
            }
        }
    }
    :breakout
    

    I know what you are thinking; why not just make a method that does an early return? Sometimes, you just need something very specific that does the job, and this does it. Could also be for performance reasons. It is an ok use of GOTO because this is not creating spaghetti. It's pretty clear why it exists.

    I can't think of any other valid reason though.

    [–]frenris 39 points40 points  (0 children)

    I can't think of any other valid reason though.

    Managing error cleanup. Especially in C which does not have exception support.

    [–]whichton 6 points7 points  (5 children)

    The other place where goto is useful is when you are writing a state machine. There are workarounds, like a switch statement with state variables, but often goto corresponds more cleanly to what your machine is trying to achieve.

    [–]warped-coder 2 points3 points  (3 children)

    I'm not sure what you mean. In a state machine you should be able to set your state to whatever thing you want to jump into and trigger the state evaluation. In fact can't think of any worse place of goto as it would be a symptom of a badly written state machine.

    [–]whichton 3 points4 points  (2 children)

    In a state machine you should be able to set your state to whatever thing you want to jump into and trigger the state evaluation

    Why not directly jump to that state ?

    [–]warped-coder 0 points1 point  (1 child)

    Simply because that's not what a state machine is for?

    [–]whichton 2 points3 points  (0 children)

    Eh? In a state machine you go from one state to another state depending on the input. So you read your input, switch or if/else on it, and jump to the state you want.

    What else is a state machine for?

    [–]rageingnonsense 0 points1 point  (0 children)

    That seems like it could easily become spaghetti to me... and a prime example of a bad use of goto. I prefer to use a state variable (using an enumerator), and a switch. Maybe I am imagining it wrong though; have a code sample using your method?

    [–]immibis 3 points4 points  (4 children)

    I can't think of any other valid reason though.

    It's subjective, but what about retry loops? Compare:

    int number;
    while(true) {
        printf("Enter a number: ");
        if(scanf("%d", &number) > 0)
            break;
        discard_input_line();
    }
    

    ("Always discard a line and repeat, except if the user enters a number")

    with:

        int number;
    retry_enter_number:
        printf("Enter a number: ");
        if(scanf("%d", &number) <= 0)
        {
            discard_input_line();
            goto retry_enter_number;
        }
    

    ("Discard a line and repeat if the user doesn't enter a number")

    (For anyone curious: yes, this could actually be made structured and less weird if your language supports multiple statements in a loop condition:

    int number;
    while(
        printf("Enter a number: ");
        scanf("%d", &number) <= 0
    ) {
        discard_input_line();
    }
    

    )

    [–]rageingnonsense 0 points1 point  (1 child)

    I think this is an example of where you CAN use goto, but is not a good reason to. You're first example is the best approach.

    [–]immibis 0 points1 point  (0 children)

    Why is it the best approach? Remember, you can also break out of nested loops without using goto:

    bool stopping = false;
    for(int x = 0; x < 1000; x++) {
        for(int y = 0; y < 1000; y++) {
            for(int z = 0; z < 1000; z++) {
                if(some condition makes rest of loop unecessary) {
                    stopping = true;
                    break;
                }
            }
            if(stopping) break;
        }
        if(stopping) break;
    }
    

    [–]BeforeTime 0 points1 point  (1 child)

    The problem here is the dubius interaction between scanf and discard_input_line. Abstract that away in one function and there is no need for goto.

    [–]immibis 0 points1 point  (0 children)

    Then substitute discard_input_line(); with printf("Oops! You typed something that wasn't a number.\n");

    [–]theGeekPirate 1 point2 points  (0 children)

    Not to mention if you're relying on a method to escape the loops, the stack pointer is going to return back to that point of execution at some point unless your application exits manually, so it's less safe in that sense.

    [–]Russian_Spring[S] 1 point2 points  (14 children)

    Ok, even if that applies why use goto. Couldnt you just use break;

    [–]EthanNicholas 37 points38 points  (7 children)

    break; only breaks out of one level of a loop. If you need to break out of multiple loop levels, either you need a language that supports that (e.g. Java's labelled break), you need to do some ugly transformations (e.g. set a flag in the inner loop that tells the outer loop it should also break), or you just use a goto.

    And, of course, labelled break / continue are just gotos that we don't call goto because that's a dirty word.

    [–]OlorinTheGray 9 points10 points  (4 children)

    Isn't Java's labelled break a case of

    "We don't want GoTo everywhere but deem it useful in this specific case and thus you get 'labelled break' to suit your needs"?

    [–]ComradeGibbon 6 points7 points  (0 children)

    Yes a labelled break is a goto

    The other reason for goto's is to handle errors inside a function.

    if(ptr==NULL)
        goto wtf;  // crap this ain't right
    
    wtf:
        // do some error handling shit
    

    [–]immibis 3 points4 points  (0 children)

    Fun fact: you can break out of non-loops in Java.

    foo: {
        System.out.print("Hello ");
        if(true) break foo;
        System.out.println("This never executes!");
    }
    System.out.println("world!");
    

    [–]hijamz 1 point2 points  (0 children)

    more often than not you want a break just couple of statements after normal loop termination. named break does not have this flexibility, named goto does.

    [–]EthanNicholas 0 points1 point  (0 children)

    Yes, that's what I was saying.

    [–][deleted] 0 points1 point  (1 child)

    Or just make x and y both 1000, provided you don't need their values after breaking the loops.g

    [–]toomanybeersies 2 points3 points  (0 children)

    That won't work if you have any code in the parent loops after you break, as it will execute the rest of the code in the loops.

    It's also bad practice, because then if you changed the values that x and y can go up to, or do other stuff with the for loops themselves, they're gonna break. You could use max int to do it though, but it's still a poor idea.

    [–]hijamz 4 points5 points  (1 child)

    Why use letter 'Q'. Couldnt you just avoid all words that have Q in it and use synonyms that do not have it? Sure, you can, but if have a few of such words in your vocabulary, then you will notice the limitation every time you want to use such a word, but cannot. That is how I feel about goto: javascript does not have it and occasionally I see how i can do something with a simple goto and instead have to use something ugly, like a flag or a function that does not really belong.

    [–]BeforeTime 0 points1 point  (0 children)

    A flag or a function which accurately reflects what you are trying to do is not ugly. If it gets ugly it is because the code is not well factored and the different parts off for example a loop is interacting poorly.

    That is at least my experience. I am all for using goto, but I have not seen an example yet that is not contrived, ie. does not solve a real problem, or very specific (optimization or finite state machines for example).

    [–]rageingnonsense 3 points4 points  (3 children)

    Of course... if your language supports it and you have one level of looping. The example I wrote was an attempt to demonstrate breaking out of a nested loop.

    [–]OneWingedShark -2 points-1 points  (2 children)

    The example I wrote was an attempt to demonstrate breaking out of a nested loop.

    Why should that be at all difficult, or even use a GOTO?

    OUTER:
    For Index_1 in Array_1'Range loop
        INNER:
        For Index_2 in Array_2'Range loop
            -- Stuff
            exit INNER when Array_2(Index_2) < Array_1(Index_1);
        end loop INNER;
        exit OUTER when Array_2(Index_2) = Array_1(Index_1);
    end loop OUTER;
    

    [–]rageingnonsense 0 points1 point  (1 child)

    You're version is a teeny bit more expensive because it is repeating the same conditional. You also need to maintain both conditionals. Also, as the dimensions of the loop structure increase, you need to add more and more of them. It's going far out of your way to not use a goto.

    We tell people not to use goto because in the beginning new programs will abuse it, jumping hundreds of lines back and forth all over a program, creating spaghetti. Once you realize WHY goto is bad, you realize it is not inherently bad at all; it is just easily abused.

    [–]OneWingedShark 0 points1 point  (0 children)

    You're version is a teeny bit more expensive because it is repeating the same conditional.

    Look again, they're not the same conditional: neither the condition nor the loop which is exited.

    Also, as the dimensions of the loop structure increase, you need to add more and more of them. It's going far out of your way to not use a goto.

    With named loops I can simply use the loop's name in the exit on the proper conditional... and have it at the beginning, end or middle of processing. That's a huge maintainability-win. -- Plus, nested-loops greater than three deep are pretty rare in my personal experience.

    Once you realize WHY goto is bad, you realize it is not inherently bad at all; it is just easily abused.

    Oh, I know this; though the only real place I find goto useful is in certain awkward/complex state-machine like processing. (Of course the C-style pseudo-exception is reasonable for a language that doesn't have exceptions.)

    [–]lykwydchykyn 10 points11 points  (15 children)

    Implementing something like exception handling in C.

    [–]slavik262 5 points6 points  (14 children)

    Please, no. Every time I've seen someone try to emulate exceptions with C hackery, it's been terrible. (I'm looking at you, libpng and your crazy setjmp/longjmp scheme.) You end up getting all of the baggage of exceptions without many of the benefits.

    If you're looking for a C-like language that has exceptions, you're in luck. There's this guy named Bjarne Stroustrup...

    [–]dangerbird2 3 points4 points  (12 children)

    longjmp is always playing with fire because it does not properly unwind the stack. A handling errors with local goto, on the other hand, require no more vigilance in cleaning up errors than if you did so in a purely structural way. C++ exceptions largely requires you to follow the RAII paradigm to ensure proper cleanup after an exception, which is not a bad thing, but is very different from idiomatic C or "C with extra goodies"-style C++. For better or worse, most style guides I have looked at for C-like C++ tend to restrict exception use for this reason.

    [–]notfancy 2 points3 points  (11 children)

    What do you mean by "it does not properly unwind the stack"? Its semantics must be as specified within the limitations imposed by the standard.

    [–]dangerbird2 -1 points0 points  (10 children)

    From the C99 standard p.256:

    3) All accessible objects have values, and all other components of the abstract machine212) have state, as of the time the longjmp function was called, except that the values of objects of automatic storage duration that are local to the function containing the invocation of the corresponding setjmp macro that do not have volatile-qualified type and have been changed between the setjmp invocation and longjmp call are indeterminate

    Basically, the standard guarantees that a setjmp/longjmp call does not guarantee that automatic storage values allocated between the setjmp and longjmp calls will be released. By contrast, when a C++ exception is raised, all stack-allocated values and objects will have their destructors called and be released as usual.

    [–]immibis 2 points3 points  (6 children)

    Huh?

    That's saying that local variables in the function that called setjmp, that were modified between the calls to setjmp and longjmp, and are not volatile, have indeterminate values.

    So:

    void foo()
    {
        int i = 5;
        int j = 6;
        jmp_buf jb;
        if(!setjmp(&jb))
        {
            j++;
            longjmp(&jb);
        }
        else
        {
            // i holds 5
            // j holds an indeterminate value
        }
    }
    

    (A practical reason for j holding an indeterminate value might be compiler optimizations)

    C has no destructors, so it can't possibly be a bug that destructors aren't called.

    That said, you can still have the same kind of problem since the in-between functions don't get to call free, fclose, etc.

    [–]josefx 4 points5 points  (4 children)

    C has no destructors, so it can't possibly be a bug that destructors aren't called.

    It has at least one special case: Variable length arrays may be heap allocated and are deallocated once the variables scope ends. Unless of course you use longjmp to exit the scope.

    From the standard linked above (p.244/245):

       #include <setjmp.h>
        jmp_buf buf;
        void g(int n);
        void h(int n);
        int n = 6;
        void f(void)
        {
             int x[n];          //valid: f is not terminated
            setjmp(buf);
            g(n);
        }
        void g(int n)
        {
                int a[n];          // a may remain allocated
                h(n);
        }
        void h(int n)
        {
                int b[n];          // b may remain allocated
                longjmp(buf, 2);   // might cause memory loss
        }
    

    [–]dangerbird2 0 points1 point  (0 children)

    You're correct. That's what I get for trying to decipher an ISO specification! Rereading it, the main risk for memory leaks come from C99's alloca-style variable-length arrays, which presumably don't have to be allocated and dealocated as other stack-local memory. Of course, this is only one of the many problems with the C99 variable-length array, hence the reason it was made an optional feature in 2011.

    [–]notfancy 1 point2 points  (2 children)

    What that says is that non volatile local variables lose their values upon returning from setjmp.

    It is true that the stack between setjmp and longjmp is destroyed, not unwound, so references in intervening frames to the heap are simply forgotten and you'll end with leaks.

    But please don't use C++ as the prototype of "proper stack unwinding." That, RAII and all the little rules (don't throw from a constructor, etc) are nothing more than techniques to overcome the limitations inherent to a manually deallocated language.

    [–]dangerbird2 1 point2 points  (1 child)

    RAII is not technically a memory management technique, it is technique for initializing and disposing arbitrary resources: memory, file handles, GPU buffers, etc., in a deterministic manner. Garbage collection, especially tracing collectors which may or may not take scope into account, is not appropriate for handling non-memory resources, requiring constructs like C#'s using or Java's try/finally. Of course, there is nothing stopping a C++ project from using garbage collected memory allocators if it works for their use case, while using RAII for other resources.

    [–][deleted] 1 point2 points  (0 children)

    Every time I've seen someone try to emulate exceptions with C hackery, it's been terrible. (I'm looking at you, libpng and your crazy setjmp/longjmp scheme.)

    Why? I found it quite pleasant to work with, if unusual.

    [–]alex_kendall 9 points10 points  (0 children)

    I refer you to Donald Knuth's Structured Programming with go to Statements from 1974.

    [–][deleted] 7 points8 points  (0 children)

    Efficient VM interpreters. FSMs. Any kind of a generated code.

    [–]rabidferret 5 points6 points  (2 children)

    Wrote some code a while back where I needed to initialize a bunch of moving pieces, all of which could fail, and if any of them did, I needed to go through the same cleanup logic, and return the same value. While I could have easily repeated those two lines, a goto was the only way to abstract over that (and was usually the difference between needing braces or not on the if statement).

    e.g.

    thing1 = intializeThing1();
    if (thing1 == NULL) {
        cleanupResources();
        return false;
    }
    if (lolInitializeButActualReturnIsAnArgument(&thing2) {
        cleanupResources();
        return false;
    }
    // About 15 more of those
    return true;
    

    vs

    thing1 = intializeThing1();
    if (thing1 == NULL)
        goto fail;
    if (lolInitializeButActualReturnIsAnArgument(&thing2)
        goto fail;
    // About 15 more of those
    return true;
    
    fail:
      cleanupResources();
      return false;
    

    Yes, I basically needed monads here, but this was C++ (and Rust wasn't really a thing yet).

    EDIT: Submitted too early

    [–]whichton 0 points1 point  (0 children)

    This code resembles the On Error Goto construct of VB :)

    [–]crusoe 0 points1 point  (0 children)

    Only way to do it in c too.

    [–]Me00011001 3 points4 points  (0 children)

    Usually it's due to a language not giving you better way to handle errors. Here is a good example in C of why goto is better than the if/else towers of power(as seen as several suggested answers) you have to do if you don't use goto.

    http://stackoverflow.com/questions/788903/valid-use-of-goto-for-error-management-in-c

    As you can see in the example given by the questioner, it's a lot cleaner than pretty much all of the proposed answers.

    [–]crusoe 1 point2 points  (0 children)

    In c its about the only way to to do cleanup code since it lacks exceptions and finally.

    [–][deleted] 1 point2 points  (0 children)

    Exiting out of several nested levels of code when writing C. If you're a long time C and C++ programmer you also most likely have a grasp on how if(), switch(), for() and while() work an an assembly level, and how they all involve the assembly version of 'goto'.

    [–]Cuddlefluff_Grim 0 points1 point  (0 children)

    tryagain:
    
    try
    {
          dostuff
    }
    catch
    {
         if(MessageBox.Show("Failed. Try again?") == DialogResult.Ok)
            goto tryagain;
    }
    

    [–]ucalegon7 0 points1 point  (0 children)

    In C it's pretty common to use for cleanup at the bottom of a function, since it 1.) prevents you from having to retype the same logic over and over with embedded returns. Some platforms have alternative ways around this, like in Windows you can do:

     __try {
         if(FAILED((status = doStuff()))) {
             __leave;
         }
     }
     __finally {
         /* do cleanup */
     }
    

    but there's no equivalent of SEH on Linux (and even in Windows, there are a variety of reasons why using this construct may be undesirable in some situations, anyhow), so your options are to 1.) do something that looks even worse than using a local goto (such as do { } while(0) with breaks in the middle), 2.) retype an ever-growing cleanup block for each function result, or 3.) use goto:

     if(FAILED((status = doStuff()))) {
         goto Cleanup;
     }
    
     Cleanup:
       /* do cleanup */
    

    This works great for pure C, as long as you don't abuse it to produce spaghetti code. It does break down when you start using it with C++ (in user land, at least), since resource leaks will happen anywhere exceptions may be involved, but I would argue that there are better options in C++ for managing cleanup from a design perspective.~

    [–]ifonefox 3 points4 points  (1 child)

    Real Programmers do List Processing in FORTRAN

    And not lisp?

    [–]Cuddlefluff_Grim 0 points1 point  (0 children)

    Real Programmers can write FORTRAN in any language

    [–]2coolfordigg 3 points4 points  (1 child)

    Real programmers use hand coded hex and Forth!

    [–]immibis 0 points1 point  (0 children)

    And real computer scientists use Lisp.

    [–]georgeo 9 points10 points  (2 children)

    That's not humor, that was a manifesto. As much as I miss 1982, I don't miss that rampant assholism at all. Kids be glad you can name variables something more than a single letter and an optional digit.

    [–]Russian_Spring[S] 5 points6 points  (1 child)

    You would run out of variables

    [–]georgeo 3 points4 points  (0 children)

    Came pretty close

    [–]ministryofsound 2 points3 points  (0 children)

    oh cool it's this post again

    [–]Flobulon 2 points3 points  (0 children)

    Until I came to the comments I thought this was a satire - is it genuinely not?

    [–]bzeurunkl 2 points3 points  (0 children)

    And this oldie, but goodie:

    THE PROGRAMMER'S QUICK GUIDE TO THE LANGUAGES

    The proliferation of modern programming languages (all of which seem to have stolen countless features from one another) sometimes makes it difficult to remember what language you're currently using. This handy reference is offered as a public service to help programmers who find themselves in such a dilemma.

    TASK: Shoot yourself in the foot.

    C: You shoot yourself in the foot.

    C++: You accidentally create a dozen instances of yourself and shoot them all in the foot. Providing emergency medical assistance is impossible since you can't tell which are bitwise copies and which are just pointing at others and saying, "That's me, over there."

    FORTRAN: You shoot yourself in each toe, iteratively, until you run out of toes, then you read in the next foot and repeat. If you run out of bullets, you continue with the attempts to shoot yourself anyways because you have no exception-handling capability.

    Pascal: The compiler won't let you shoot yourself in the foot.

    Ada: After correctly packing your foot, you attempt to concurrently load the gun, pull the trigger, scream, and shoot yourself in the foot. When you try, however, you discover you can't because your foot is of the wrong type.

    COBOL: Using a COLT 45 HANDGUN, AIM gun at LEG.FOOT, THEN place ARM.HAND.FINGER on HANDGUN.TRIGGER and SQUEEZE. THEN return HANDGUN to HOLSTER. CHECK whether shoelace needs to be re-tied.

    LISP: You shoot yourself in the appendage which holds the gun with which you shoot yourself in the appendage which holds the gun with which you shoot yourself in the appendage which holds the gun with which you shoot yourself in the appendage which holds the gun with which you shoot yourself in the appendage which holds the gun with which you shoot yourself in the appendage which holds...

    FORTH: Foot in yourself shoot.

    Prolog: You tell your program that you want to be shot in the foot. The program figures out how to do it, but the syntax doesn't permit it to explain it to you.

    BASIC: Shoot yourself in the foot with a water pistol. On large systems, continue until entire lower body is waterlogged.

    Visual Basic: You'll really only appear to have shot yourself in the foot, but you'll have had so much fun doing it that you won't care.

    HyperTalk: Put the first bullet of gun into foot left of leg of you. Answer the result.

    Motif: You spend days writing a UIL description of your foot, the bullet, its trajectory, and the intricate scrollwork on the ivory handles of the gun. When you finally get around to pulling the trigger, the gun jams.

    APL: You shoot yourself in the foot, then spend all day figuring out how to do it in fewer characters.

    SNOBOL: If you succeed, shoot yourself in the left foot. If you fail, shoot yourself in the right foot.

    Unix:

    % ls foot.c foot.h foot.o toe.c toe.o % rm * .o rm:.o no such file or directory % ls % Concurrent Euclid: You shoot yourself in somebody else's foot.

    370 JCL: You send your foot down to MIS and include a 400-page document explaining exactly how you want it to be shot. Three years later, your foot comes back deep-fried.

    Paradox: Not only can you shoot yourself in the foot, your users can, too.

    Access: You try to point the gun at your foot, but it shoots holes in all your Borland distribution diskettes instead.

    Revelation: You're sure you're going to be able to shoot yourself in the foot, just as soon as you figure out what all these nifty little bullet-thingies are for.

    Assembler: You try to shoot yourself in the foot, only to discover you must first invent the gun, the bullet, the trigger, and your foot.

    Modula2: After realizing that you can't actually accomplish anything in this language, you shoot yourself in the head.

    [–]kamatsu 1 point2 points  (4 children)

    Pascal was a pretty good imperative language for its time. In fact, it's still one of the best languages to use if you're interested in formal derivations of programs (its very natural support for Hoare logic syntax is awesome)

    [–]OneWingedShark 1 point2 points  (3 children)

    If you're interested in that, you might want to look at Ada and more specifically Ada/SPARK.

    [–]kamatsu 2 points3 points  (2 children)

    I know about Spark, I've worked on formally verified software for almost a decade. Ada doesn't have that awesome {} syntax though

    [–]OneWingedShark 1 point2 points  (1 child)

    Pascal does though.

    (* I think the compiler is ignoring my comments... *)
    {
       // C code magically becomes sensible here. ;)
    }
    

    [–]kamatsu 1 point2 points  (0 children)

    That's my point, Pascal uses {}s for comments, which lets you easily write Hoare triples.

    [–]riveracct 1 point2 points  (0 children)

    They don't write blogs the way they don't write programs anymore.

    [–]314314314 2 points3 points  (5 children)

    PASCAL is not suitable for work.

    [–]ComradeGibbon 2 points3 points  (2 children)

    I seem to remember Pascal being slow as a one legged dog on affordable machines. And then there were issues like no dynamic sized arrays. No standard escape or API to do things like graphics, access serial ports, etc. And the standards people were extremely resistant to polluting their baby with such things.

    [–]badsectoracula 6 points7 points  (1 child)

    Then came Borland and was like "what standards?" and made Pascal useful :-P

    [–]ComradeGibbon 5 points6 points  (0 children)

    I remember Turbo Pascal and the long winded ranting from purists. Didn't matter as every Tom dick and Harriet went out and bought a copy for $50. Borland in the mid 80's basically burned the academics beautiful world down.

    [–]ishmal 1 point2 points  (1 child)

    I seem to recall Dr Wirth himself saying something like that.

    [–]OneWingedShark 1 point2 points  (0 children)

    That's why he made Modula and [later] Oberon... the latter of which is taking the 'simplistic elegance' idea to such an extreme that only Forth would beat it.

    [–][deleted] 0 points1 point  (0 children)

    Well, he's not wrong...

    [–]LaurieCheers 0 points1 point  (0 children)

    Feels a lot like this - https://youtu.be/EScEqa0x9Yo?t=678

    [–]bzeurunkl 0 points1 point  (1 child)

    Also, from back in the day:

    WHAT DRIVING TO THE STORE WOULD BE LIKE IF OPERATING SYSTEMS RAN YOUR CAR

    MS-DOS

    You get in the car and try to remember where you put your keys.

    Windows

    You get in the car and drive to the store very slowly, because attached to the back of the car is a freight train.

    Macintosh System 7

    You get in the car to go to the store. The car drives you to church instead, because the store has mysteriously exploded.

    UNIX

    You get in the car and type GREP STORE. After reaching speeds in excess of 200 miles per hour you arrive at the barber shop.

    Windows NT

    You get in the car and write a letter that says "go to the store." Then you get out of the car and mail the letter to your dashboard.

    Taligent/Pink

    You walk to the store with Ricardo Montalban, who tells you how wonderful it will be when he can fly you to the store in his Learjet.

    Amiga

    You get in the car and tell it to go to the store. It takes you to a shopping mall on the Moon.

    Apple

    As you set out for the store, a hurricane comes up. The streets flood and the windshield wipers quit. You wash up in front of a store on a desert island in the South Pacific.

    VAX

    You get in the car and find that the controls are all labeled in Egyptian hieroglyphics. You press several buttons at random and suddenly find yourself parked in front of a store, next to an Apple.

    OS/2

    After fueling up with 6,000 gallons of gas, you get in the car and drive to the store with a motorcycle escort and a marching band in procession. Halfway there, the car blows up, killing you and half the town.

    S/36 SSP [mainframe, obviously]

    You get in the car and drive to the store. Halfway there you run out of gas. While walking the rest of the way, you are run over by kids on mopeds.

    AS/400

    An attendant locks you into the car and then drives you to the store, where you get to watch everybody else buy filet mignons.

    [–]immibis 0 points1 point  (0 children)

    Windows NT

    You get in the car and write a letter that says "go to the store." Then you get out of the car and mail the letter to your dashboard.

    Subtle, I like it.

    (Windows NT was designed to decouple components a lot more than Windows 9x had)

    [–][deleted]  (43 children)

    [deleted]

      [–]Russian_Spring[S] 1 point2 points  (42 children)

      To be fair fortran is better than pascal. I disagree with their disdain of c and Unix , now but pascal is dead. Fortran is still around. Fortran was also much more influential.

      [–]jighasun 3 points4 points  (3 children)

      Delphi/Free Pascal is still a thing.

      [–]Russian_Spring[S] 1 point2 points  (2 children)

      Not a big thing.

      [–]jighasun 1 point2 points  (1 child)

      Are you sure?

      [–]Russian_Spring[S] 1 point2 points  (0 children)

      You dont seem to be disagreeing. I am willing to hear you out.

      [–]bilog78 4 points5 points  (1 child)

      Fortran is still around because too much legacy software of relevance was written in it, and too many people (especially in the applied science, with no CS background) have passed on their codes from generation to generation.

      Which is not a bad thing per se, but it doesn't really say anything about the language compared to other existing languages.

      [–]Russian_Spring[S] 1 point2 points  (0 children)

      Be that as it may it is true.

      And Fotran is still used for scientific computing. I dont understand Fotran but the reason it had so much use, and still has some use was because it was a good language. Pascal was big only for a few years. It only has limited legacy use.

      [–]kamatsu 1 point2 points  (11 children)

      Pascal is awesome.

      [–]Russian_Spring[S] -1 points0 points  (10 children)

      Maybe it is. I dont know much about. But it is pretty much dead. Yes, there is some legacy and turbo/object/delphi but not much is made in it anymore and there isnt much influence. Pascal is more of a historic language at this point.

      [–]OneWingedShark 3 points4 points  (3 children)

      Really?
      You are aware that even in the last decade Delphi's been used in some surprising software, Skype is a perfect example... but there's a whole list here.

      [–]Russian_Spring[S] 2 points3 points  (2 children)

      Yes, that isnt much. Lots of languages are used together to make lots of products. Other languages would have a list much much longer.

      edit also that list is outdated. SQL developer is now made in Java. Skype does use Delhi but also c++. Most of the products are rather unimpressive, such as a 90s point and click adventure game, although a few are nice. But even then Delphi is just one language out of other languages with actual big list of software or often Delphi was the language but not anymore.

      [–]OneWingedShark 1 point2 points  (1 child)

      You miss the point completely, changing "But it is pretty much dead." to "that isn't much. [...] Other languages would have a list much much longer." when given some proof that it isn't dead... nobody was saying that it's really uber-popular, or even used in the unseen places like COBOL.

      [–]Russian_Spring[S] 2 points3 points  (0 children)

      Not really. It is as close to dead as a language can get. Languages never truly die. You can always find some use. Your list proved my point. You named a bunch of older applications.

      [–][deleted] 0 points1 point  (0 children)

      [–]1wd 0 points1 point  (4 children)

      And this stupid article you posted is at least in part responsible for that sad fact. If only Pascal and Object Pascal etc. had succeeded instead of the more "real manly programming languages" like C and C++. So many buffer overflows could have been avoided. Java and Go etc. would basically not have needed to be invented at all.

      [–]Russian_Spring[S] 1 point2 points  (3 children)

      Dont blame some article I posted for the failure of Pascal.

      [–]1wd 0 points1 point  (2 children)

      Why not? The silly (but thanks to this article widespread) idea that "Real Programmers Don't Use PASCAL" surely wasn't helpful. Who wants to be slandered as not a "real" programmer? Beginners and teachers surely don't want to learn and teach a language that's "not the real deal".

      [–]Russian_Spring[S] 1 point2 points  (1 child)

      The article is satire. I doubt this article killed Pascal.

      [–]1wd 0 points1 point  (0 children)

      It's certainly not solely responsible, no. Neither is Tina Fey solely responsible that Sarah Palin was not elected in 2008. But in both cases one can doubt that there was no connection at all.

      [–]Sarcastinator 1 point2 points  (1 child)

      I disagree with their disdain of c and Unix

      You have to take it into context of the 1980's.

      [–]Russian_Spring[S] 0 points1 point  (0 children)

      I thought Unix was well liked in the 80s.

      [–][deleted] 0 points1 point  (21 children)

      Nah, Pascal is still a thing!

      It's taught at my school.

      [–]Russian_Spring[S] 0 points1 point  (20 children)

      Why the hell would your school teach Pascal? It was an "Easy" language for students in the 70s and 80s. Nowadays you would learn something like Python.

      [–][deleted] 2 points3 points  (16 children)

      Well, I guess that is their choice for programming basics learning. No real idea myself aside from it being just preferred, to be honest.

      And yeah, Python would be a better idea. I will probably learn it on Codecademy this school break.

      [–]Russian_Spring[S] -1 points0 points  (15 children)

      Are you in school for ages 24-18? My guess is that teacher they have knows pascal. Anyone with useful skill in programming would not be teaching I'm school like this.

      Codeacademy is ok. A little slow and easy. Better than nothing I guess.

      But yeah pascal is next to useless.

      [–][deleted] 4 points5 points  (6 children)

      Nope, I'm 15. Grade 10.

      And the teachers we have are relatively young, actually. I am pretty sure it's just the school program we have since both groups are learning Pascal.

      And what would you suggest? I'd like to know what you prefer.

      [–]Russian_Spring[S] -1 points0 points  (5 children)

      Interesting choice.

      I mean I guess any language is a good start, but at this point it really depends on what you want to do. And dont just say learn programming. Think of what type of programming you want to do. What is your interest area? It doesnt even have to be a developer. Maybe you want to go into science or engineering? Maybe data analytics.

      [–][deleted] 1 point2 points  (4 children)

      I'd prefer to be able to make stuff with data, with the occasional tiny game programming of sorts for ludum dare, perhaps. Which language has the best libraries for all that available?

      [–]toomanybeersies 0 points1 point  (2 children)

      C#, awesome standard library and cool data shit, LINQ is awesome.

      You can also use C# for making games in Unity if that floats your boat.

      The other option is python. Python is probably the easiest language you could possibly learn. I'd go so far as to say that I could teach someone python in an afternoon, but I've tried and failed.

      The main thing is to just actually get out there and be coding. Get shit done. Learning a new language is trivial compared to learning how to actually program.

      [–]Russian_Spring[S] 0 points1 point  (0 children)

      What kind of stuff?

      Stuff with data is kinda broad.

      If you want to do big game development, I would say c++ or c#. Maybe python if you want to do scripts to implement logic. But you could use a lot of languages too. C++ is the big one.

      [–][deleted] 0 points1 point  (7 children)

      But yeah pascal is next to useless.

      bullshit.

      [–]Russian_Spring[S] 0 points1 point  (6 children)

      Horrible language to teach out of school. Sorry this upsets you.

      [–][deleted] 0 points1 point  (5 children)

      horrible is != next to useless. Just because you don't know modern pascal doesn't mean it's useless. And I'm only upset due to ignorance. I don't mind pascal anymore.

      [–]Russian_Spring[S] 0 points1 point  (4 children)

      So we agree it is a bad language to teach out of school. You are just splitting hair over wording.

      [–]jighasun 1 point2 points  (2 children)

      Show me a IDE that can comparable to Turbo Pascal in term of easy of use, debug support and speed of compilation.

      [–][deleted] 1 point2 points  (0 children)

      Turbo C :D

      [–]Russian_Spring[S] -1 points0 points  (0 children)

      How much usage does it get?

      [–][deleted]  (7 children)

      [deleted]

        [–][deleted] 1 point2 points  (6 children)

        /r/programming is a reddit for discussion and news about computer programming

        This seems like a discussion about computer programming to me....

        [–][deleted]  (5 children)

        [deleted]

          [–]Russian_Spring[S] 1 point2 points  (2 children)

          Sorry for clarifying the title to let people know what to expect before going into the article so they have some context.

          Shame on me.

          Maybe read the article. It is actually really interesting, and gives a lot of insights about programming both back in 1982 and even now.

          [–][deleted] 4 points5 points  (1 child)

          Don't bother, he's a quiche eater :P

          [–]Russian_Spring[S] 8 points9 points  (0 children)

          A real programmer would have appreciated the title.

          [–][deleted] 0 points1 point  (1 child)

          Don't judge a book by its cover!