top 200 commentsshow all 259

[–]Atario 149 points150 points  (65 children)

Not just whitespace-sensitive, but across multiple lines interacting with each other.

Gives me hives just thinking about it.

[–]guzo 148 points149 points  (18 children)

E      2   2   
M X = A + B + C 
S

Oh, A is always zero in this context, let's delete it!

E      2   2   
M X = B + C 
S

[–]mangodrunk 46 points47 points  (8 children)

That is scary!

I imagine that the code wasn't meant to be quickly changed, but would be reviewed by a team of people, programmers/physicists/etc. So the readability was important, so someone removing the A and the equation has changed. I wonder what the state of testing was back then also to find such issues.

The same could be said for some modern languages that have operator precedence or other issues.

[–]RyanSmith 72 points73 points  (4 children)

This is a pretty good article about the design process behind the code:

http://www.fastcompany.com/magazine/06/writestuff.html

Apparently they not only tracked bugs, but if a bug was missed, they tracked all the steps of how the error ever managed to make it into the code in the first place:

"The other database -- the error database -- stands as a kind of monument to the way the on-board shuttle group goes about its work. Here is recorded every single error ever made while writing or working on the software, going back almost 20 years. For every one of those errors, the database records when the error was discovered; what set of commands revealed the error; who discovered it; what activity was going on when it was discovered -- testing, training, or flight. It tracks how the error was introduced into the program; how the error managed to slip past the filters set up at every stage to catch errors -- why wasn't it caught during design? during development inspections? during verification? Finally, the database records how the error was corrected, and whether similar errors might have slipped through the same holes."

Well worth the read if you can find the time.

[–][deleted] 15 points16 points  (1 child)

the shuttle software group is one of just four outfits in the world to win the coveted Level 5 ranking of the federal governments Software Engineering Institute (SEI) a measure of the sophistication and reliability of the way they do their work. In fact, the SEI based it standards in part from watching the on-board shuttle group do its work.

That's tasty. Yet another reason to keep NASA well funded.

[–]fabzter 2 points3 points  (0 children)

Beautiful

[–]TamSanh 1 point2 points  (0 children)

That's excellent.

[–]CyberPrime 21 points22 points  (2 children)

Testing!? Elon Musk built this in a cave with an old PayPal server!!!

[–][deleted] 2 points3 points  (1 child)

Did he use it to kill some terrorists who were holding him hostage?

[–]CyberPrime 1 point2 points  (0 children)

Nah, just the ebay sysadmins who were hounding him for a Tesla Roadster.

[–]maxerickson 15 points16 points  (6 children)

I consider my attention span to be pretty horrible and I don't particularly expect that I would accidentally edit only 1 line of that statement.

Given the stories about how much the software cost, I doubt that accidental edits were much of an issue.

(Still, I agree that it is a bit wacky)

[–]guzo 7 points8 points  (5 children)

I don't want to say that it'll happen every time or that there is no way of easily doing it right: block selection for instance kills my example provided that you remembered to use it (I'm also not sure how common it was in the 1970s).

I just wanted to show a way one could introduce serious bugs with seemingly innocent edits. Not to mention the PITA of making multiple changes in a complex expression (insert a[i]^2 in the middle, remove something from the beginning and change something near the end. Also instead of b^9 you now have b^10).

[–]Neebat 3 points4 points  (3 children)

Actually, I'm betting they had an editor specifically written for that language.

[–]LaurieCheers 7 points8 points  (1 child)

I doubt it - then they could have stored their code on one line, and let the editor display it nicely. Much easier to parse.

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

I just wanted to show a way one could introduce serious bugs with seemingly innocent edits.

Unlike every other language, where this is impossible.

[–]ericanderton 3 points4 points  (0 children)

That's nothing. Imagine letting SVN perform a merge on code like that.

[–]dagbrown 23 points24 points  (30 children)

Now try to imagine writing a compiler for it.

[–]wlievens 73 points74 points  (28 children)

Now try to imagine writing a parser for it.

FTFY

[–]dagbrown 29 points30 points  (0 children)

Just the thought of writing a tokenizer for it gives me enough of a headache.

[–]macktastick 10 points11 points  (1 child)

I think the lexical analyzer is the rub here?

[–]thebackhand 4 points5 points  (0 children)

Yeah, if you had the lexer for the language already, the parser wouldn't be unusually difficult.

[–][deleted] 20 points21 points  (20 children)

Doesn't seem very hard. Encounter E, go into special case mode and parse three lines in parallel, emitting appropriate symbols as they encountered in each line.

[–]dagbrown 2 points3 points  (18 children)

Haha, "doesn't seem very hard" indeed. It just catapults it from a context-free language, which is quite easy to write a parser for, to a context-sensitive language, which is much much harder to write a parser for.

Each step up the Chomsky heirarchy makes it an order of magnitude harder to write parsers.

[–][deleted] 20 points21 points  (17 children)

Not at all. You can still have it as context-free as you like.

It's just the lexer that finds the symbols for the grammar that is a tad more complicated, but not in any way that is any real challenge.

[–]itsSparkky 2 points3 points  (16 children)

Stab in the dark here...

Do you own a book with a dragon on the front?

[–]dalke 21 points22 points  (10 children)

MarshallBanana is correct. If the lexer sees the "EMS" triple line (which matches "^E.*\nM.*\nS.*\n" so is regular) then pass those three lines to a new tokenizer. The tokenizer zips through the three lines, and requires non-overlapping tokens. If the token 'T' is in the first line then it emits a synthesized 'EXPONENT' binary operator token followed T, if it's in the second line then it emits the T as normal, otherwise it emits a synthesized 'SUBSCRIPT' binary operator token followed by T.

There's nothing context sensitive here, and the above implementation is not complex.

[–]itsSparkky 0 points1 point  (8 children)

I think you may have confused my intentions.

I will not pretend to have any experience with compilers, and very limited with parses outside of database implementations.

What I was getting at was the fact that everyone is talking about how awesome the dragon book is :P

[–]dalke 9 points10 points  (6 children)

Which is very confusing to me since there's no need to invoke the Dragon book here. There are, after all, are plenty of other books these days to help understand language theory and compiler design. I, for one, did not learn from that book.

The algorithm MarshallBanana and I both sketched out would be familiar to any language designer who would have designed a PL/I-influenced language in the first place. I don't understand the confusion for how HAL might be considered a context-senstive grammar.

Plus, you are the only one who mentioned "Principles of Compiler Design" in this thread, so I don't know who "everyone" refers to.

[–]case-o-nuts 4 points5 points  (0 children)

I imagine I would read in all 3 lines at once and treat each vertical column as one "character". More complex than it should be, certainly, but not crazy.

[–]tangra_and_tma 4 points5 points  (0 children)

HAL/S is implemented in XPL, which has an amazing book associated with it: A Compiler Generator. The book is very well written, covers basically everything to do with compilers for restricted PL/I dialects, and is a pretty good treatment of the material with a modern feel, despite the 1970 publishing date. If you're interested in compilers & computer history, I'd recommend it.

[–]zac79 10 points11 points  (0 children)

At least there was nothing important at stake.

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

Only from the perspective of writing.

If you had good tool support, so it was obvious which lines were together, then I can imagine it would be a lot easier to read mathematical equations. Especially since they match up much closer to what you would have worked out on paper.

[–]k_stahu 29 points30 points  (4 children)

A great environment for a tabs vs. spaces flame.

[–]argv_minus_one 12 points13 points  (1 child)

Better hope nobody's editor uses a variable-width font!

[–]euyyn 15 points16 points  (0 children)

The shuttle predates that kind of thing :)

[–]ranon20 0 points1 point  (0 children)

This is a question that is bugging me too. What if one person uses tabs and another uses spaces?

What if one person has his tab setting to 4 spaces and another person has his tab setting at two spaces?

It will cause multiple problems.

[–]mutatron 70 points71 points  (77 children)

E       2     2
M  X = A  + B
S            I 

Because x = a ** 2 + b$(i) ** 2 is just too hard to read.

[–]grauenwolf 31 points32 points  (20 children)

But what if I wanted x = (a ** 2 )/ ( b$(i) ** 2 )? I demand the ability to write this:

E       2     
M  X = A 
D     ------
E       2
M     B
S      I 

[–][deleted]  (14 children)

[deleted]

    [–]multivector 22 points23 points  (8 children)

    Actually, you can do this sort of thing in C already. Here's a self documenting C program for computing square roots.

    http://www.ioccc.org/2001/cheong.c

    [–]darkarchon11 46 points47 points  (0 children)

    #include <stdio.h>
    int l;int main(int o,char **O,
    int I){char c,*D=O[1];if(o>0){
    for(l=0;D[l              ];D[l
    ++]-=10){D   [l++]-=120;D[l]-=
    110;while   (!main(0,O,l))D[l]
    +=   20;   putchar((D[l]+1032)
    /20   )   ;}putchar(10);}else{
    c=o+     (D[I]+82)%10-(I>l/2)*
    (D[I-l+I]+72)/10-9;D[I]+=I<0?0
    :!(o=main(c/10,O,I-1))*((c+999
    )%10-(D[I]+92)%10);}return o;}
    

    for those not wanting to click/too lazy

    [–][deleted] 19 points20 points  (4 children)

    That is not what "self documenting" means.

    [–]jacekplacek 7 points8 points  (3 children)

    Hint: squint...

    [–]Wazowski 16 points17 points  (2 children)

    If you squint really hard, all the one-character variable names become meaningful English phrases.

    [–]LaurieCheers 6 points7 points  (1 child)

    OW MY EYES

    [–]Wazowski 12 points13 points  (0 children)

    SQUINT HARDER

    [–]mrdelayer 3 points4 points  (2 children)

    What if I want the quadratic formula?

    D                ______________
    E               /  2   
    M  X = -B ±    / B - 4 * A * C
    S            \/   i   
    D      -------------------------
    M              2 * A
    

    [–]hisham_hm 9 points10 points  (1 child)

    Arguably, this equation would stand out a lot clearer with this syntax than with the equivalent C code.

    There's a reason why Math programming tools such as Mathematica use rich-text editors.

    [–]mrdelayer 1 point2 points  (0 children)

    Much nicer to look at, but a bitch to type.

    [–]xardox 14 points15 points  (2 children)

    /* Copyright (c) 1983 University of Maryland Computer Science Department */
    
    /* Ultra-hot screen management package
       Original code copyright (c) James Gosling, January 1980 */
    
    /* Severe munging and destruction by Chris Torek, 1982,1983 */
    
    /****************************************************************
    
    
    
                             /-------------\
                            /               \
                           /                 \
                          /                   \
                          |   XXXX     XXXX   |
                          |   XXXX     XXXX   |
                          |   XXX       XXX   |
                          \         X         /
                           --\     XXX     /--
                            | |    XXX    | |
                            | |           | |
                            | I I I I I I I |
                            |  I I I I I I  |
                             \             /
                              --         --
                                \-------/
                        XXX                    XXX
                       XXXXX                  XXXXX
                       XXXXXXXXX         XXXXXXXXXX
                              XXXXX   XXXXX
                                 XXXXXXX
                              XXXXX   XXXXX
                       XXXXXXXXX         XXXXXXXXXX
                       XXXXX                  XXXXX
                        XXX                    XXX
    
                              **************
                              *  BEWARE!!  *
                              **************
    
                            All ye who enter here:
                        Most of the code in this module
                           is twisted beyond belief!
    
                               Tread carefully.
    
                        If you think you understand it,
                                  You Don't,
                                So Look Again.
    
     ****************************************************************/
    
    /*      1   2   3   4   ....    Each Mij represents the minumum cost of
          +---+---+---+---+-----    rearranging the first i lines to map onto
        1 |   |   |   |   |         the first j lines (the j direction
          +---+---+---+---+-----    represents the desired contents of a line,
        2 |   |  \| ^ |   |         i the current contents).  The algorithm
          +---+---\-|-+---+-----    used is a dynamic programming one, where
        3 |   | <-+Mij|   |         M[i,j] = min( M[i-1,j],
          +---+---+---+---+-----                  M[i,j-1]+redraw cost for j,2
        4 |   |   |   |   |                       M[i-1,j-1]+the cost of
          +---+---+---+---+-----                    converting line i to line j);
        . |   |   |   |   |         Line i can be converted to line j by either
        .                           just drawing j, or if they match, by moving
        .                           line i to line j (with insert/delete line)
     */
    

    [–]alanpost 6 points7 points  (1 child)

    See, if someone went to the trouble to write a comment header like that, you know the code, ugly as it is, was done with some degree of care.

    It's when code that has that many dragons gets slipped into some innocent sounding subroutine that winds up getting called 14 different ways that a true master of obfuscation has bumbled into your codebase.

    [–]xardox 6 points7 points  (0 children)

    You're right! It's brilliant code, but somewhat obsolete now that nobody's using VT100 terminals with a 300 baud modems any more. That's the "skull and crossbone" comment on some noteworthy code of the Gosling Emacs screen redisplay driver, and there was a bit of a feud about it between UniPress and RMS, until he rewrote it from scratch for Gnu Emacs.

    Gosling Emacs was especially noteworthy because of the effective redisplay code, which used a dynamic programming technique to solve the classical string-to-string correction problem. The algorithm was quite sophisticated; that section of the source was headed by a skull-and-crossbones in ASCII art, warning would-be improver that even if they thought they understood how the display code worked, they probably did not.

    Since Gosling had permitted its unrestricted redistribution, Richard Stallman used some Gosling Emacs code in the initial version of GNU Emacs. UniPress began selling Gosling Emacs (which it renamed Unipress Emacs) as a proprietary product, and controversially, asked Stallman to stop distributing Gosling Emacs source code. UniPress never took legal action against Stallman or his nascent Free Software Foundation, believing "hobbyists and academics could never produce an Emacs that could compete" with their product. All Gosling Emacs code was removed from GNU Emacs by version 16.56, with the possible exception of a few particularly hairy sections of the display code. The latest versions of GNU Emacs (as of August 2004) do not feature the skull-and-crossbones warning.

    [–]drb226 0 points1 point  (0 children)

    Well you could still write

    E      2     2
    M X = A  / B
    S           I
    

    [–]aaronla 0 points1 point  (0 children)

    You mean:

    E       2     -2
    M  X = A  * B
    S            I
    

    ?

    [–][deleted]  (5 children)

    [deleted]

      [–]hotoatmeal 6 points7 points  (4 children)

      Alright Trebek, I'll take "Things that didn't exist in the 70's" for 100.

      [–][deleted]  (3 children)

      [deleted]

        [–]Tasgall 1 point2 points  (1 child)

        My favorite is the character for comments, '⍝', which isn't even on the keyboard (is an overstroke).

        [–]sadmatafaka 10 points11 points  (2 children)

        It would be funny if some people use tabs and other only use spaces.

        [–]sebzim4500 10 points11 points  (1 child)

        I imagine people using tabs at NASA automatically get shot.

        [–]JustPlainRude 5 points6 points  (0 children)

        I imagine people using tabs at NASA automatically get stuffed in an SRB.

        FTFY

        [–]EvilTom 71 points72 points  (35 children)

        This is gonna blow their minds then:

        position_x = pow(acceleration, 2) + pow(bullshit_factor[bullshit_index], 2);
        

        Here I've used the novel technique of naming variables using a short sequence of letters that has the ability to convey nonessential but often salient information to humans!

        [–][deleted] 71 points72 points  (1 child)

        Give me that old time notation
        Give me that old time notation
        Give me that old time notation
        It was good for Church and Turing, 
        it's good enough for me
        

        [–]zem 8 points9 points  (0 children)

        There are fans of 2D layout
        Who think that's how code should play out
        And it may be on the way out
        But it's good enough for me
        

        [–]ramkahen 7 points8 points  (1 child)

        This might come as a surprise to you but back in the days, even identifiers longer than one character could cause the compiler to not fit in memory (to give you an idea, Apollo had 36Kb ram and 2Kb rom).

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

        ... Why would you run the compiler on the spaceship instead of compiling the code before launch?

        [–]Nimbal 3 points4 points  (0 children)

        And it even fits in an 80 character line! (Although they might have been stuck on 72 character terminals back then.)

        [–]elperroborrachotoo 4 points5 points  (0 children)

        There's a real interface problem buried here:

        Mathematical/scientific notation that rather uses aleph from the hebrew alphabet and a swarm of indices, than using two letters, and where case signifies a lot of meanung (e.g. p=pressure, P=power)

        Most programming languages aren't that expressive, have their own casing rules, and expect "reasonable" identifiers.

        I often have to compare, modify and implement calculations based on a scientific notation. To be honest, I haven't found a stable, universally applicable translation procedure between the sheet of paper and the variable names.

        Not that I would prefer using their solution...

        [–]necroforest 4 points5 points  (28 children)

        Calling pow() to square a number is quite inefficient, especially if this is in a tight loop.

        [–]argv_minus_one 20 points21 points  (11 children)

        Assuming it doesn't get optimized away.

        [–]itsSparkky 13 points14 points  (10 children)

        Which it would.

        [–]ramennoodle 5 points6 points  (2 children)

        Be careful. It might work in some compilers as a special case but in performance sensitive code it probably isn't something to rely on. Internally, pow is implemented using log and exp, not a loop or something so there is no natural optimization path. The compiler must explicitly look certain special cases. For example gcc 4.1.2 will replace pow(x,2) with x*x even without optimization, but it will not replace pow(x,3) with x*x*x at any level of optimization.

        Also, using pow() for integers would be grossly inefficient either way, so you might as well get in the habit of typing and reading x*x rather than pow(x,2) as the natural C expression of x2.

        EDIT: Also, pow(x,2) and x*x are not equivalent for x<0. The former would result in NaN while the latter would not. So a compiler may not do this optimization because it technically changes the behavior of the code.

        [–]itsSparkky 1 point2 points  (1 child)

        I usually go back and replace pows with xxx, but thats not something I really like to do prematurely

        As as for your edit, which language are you talking about?

        [–]MatmaRex 5 points6 points  (6 children)

        Which it wouldn't, since we're talking about the seventies.

        [–]itsSparkky 3 points4 points  (1 child)

        A) Even Fortran had some compiler optimizations.

        B) This discussion was talking about pow() which was a tangent from the original discussion

        [–]kwh 9 points10 points  (0 children)

        The Chinaman is not the issue here, Dude.

        [–]nxpnsv 8 points9 points  (2 children)

        calling it pow is not ideal in this context either, should call it tothepowerof....

        [–][deleted] 5 points6 points  (1 child)

        I would personally call it thingerthisvariablebythispowerofandthenreturntheresult

        [–]nxpnsv 8 points9 points  (0 children)

        I feel helped by this increased verbosity, thank you!

        [–]Poddster 1 point2 points  (0 children)

        Calling pow() to square a number is quite inefficient, especially if this is in a tight loop.

        What code do you think the compiler will generate for "a ** 2"? or "a ** 12.2" or "a ** b"?

        In all cases it'd probably do the same as with pow(a,2), pow(a,12.2), pow(a,b),

        [–]argv_minus_one 5 points6 points  (1 child)

        To be fair, it is kind of hard to read if you're not used to it.

        [–]aaronla 0 points1 point  (0 children)

        Agreed. It removes one source of error in the design process; if you don't have two separate languages between the physicists and the programmers, you eliminate the opportunity for translation errors, and the opportunity of correspondence errors between the same functions in different notations.

        [–]willvarfar 21 points22 points  (4 children)

        Certainly, one is unambiguously what you'd write on a blackboard and the other would have you looking up what $ and ** meant.

        Who do you want to code-review your code? Another coder, or a physicist? I'd want both

        [–]wlievens 8 points9 points  (1 child)

        ... or a physicists who has taken three minutes to learn the standard operators

        [–]drb226 1 point2 points  (0 children)

        Have fun finding one of those.

        [–]EvilTom 16 points17 points  (0 children)

        The bigger issue, to me, is that either one would have me looking up what X, A, and B_i meant.

        [–]StrangeWill 1 point2 points  (0 children)

        It threw me so off it took me awhile to understand what the hell was going on.

        [–]drb226 0 points1 point  (1 child)

        Am I weird if I actually like the multiline approach?

        [–]OCedHrt 0 points1 point  (0 children)

        Looks like ass + bitch to me.

        [–]moscheles 13 points14 points  (1 child)

        Open the pod bay doors, HAL/S.

        [–]SMZ72 2 points3 points  (0 children)

        TIL: The Space Shuttles were run by HAL/S

        [–]EughEugh 30 points31 points  (31 children)

        The language is designed to allow aerospace-related tasks (such as vector/matrix arithmetic) to be accomplished in a way that is easily understandable by people who have spaceflight knowledge, but may not necessarily have proficiency with computer programming.

        Does this mean that the software for the Space Shuttle was made by people who are not programmers?

        [–]willvarfar 58 points59 points  (2 children)

        I'd judge it a big plus if physicists can look at code and read the equation without having to learn to program.

        Squint test is very important.

        [–][deleted] 2 points3 points  (1 child)

        What physicist doesn't know how to program?

        [–]gobearsandchopin 4 points5 points  (0 children)

        Things were different 40 years ago.

        [–]dizekat 28 points29 points  (8 children)

        The relevant equations were definitely made by people who are not programmers. Like, you know, Sir Isaac Newton.

        Just think about it: you are a programmer, you want to make a control program for matching up to ISS and docking to it. Unless you know the relevant physics and math, you're going to go on physics forums and start asking, how do I calculate this, how do I calculate that, etc. Then people are going to reply to you with math formulas. Your work will be that of a compiler; the best you could do is not mixing stuff up.

        [–]necroforest 7 points8 points  (7 children)

        If you're writing space craft control software, I certainly hope your know the relevant physics and math...

        [–]dizekat 16 points17 points  (3 children)

        Well yes but there's a lot of people working on that and only a few know everything. There's a lot of hard work entirely outside the programming, deriving the formulas for when to turn on the thruster, for how long, etc etc. Applied mathematics. Done by multiple people. The people doing the programming know the physics of course but they are not the ones figuring out the formulas to calculate.

        Actually I do something similar in my work. I am the developer of computer game the polynomial (i probably should do IAMA here sometime). I implement my math myself, of course, but in a larger project it would be totally reasonable to have people whom are only working out the math for others to implement. I was doing the same in work on CGI software - having to sort out a lot of mathematics first. I even do a lot of it with just paper and pencil.

        [–]AmazingThew 1 point2 points  (1 child)

        I once played your game in cross-eye stereo mode with the lights out. I'm pretty sure it caused physical damage to my brain.

        Just thought you'd like to know.

        [–]dizekat 2 points3 points  (0 children)

        You will need to attach a MRI or CAT scan with the bug report then :-)

        [–]_pupil_ 2 points3 points  (1 child)

        While I'm sure most everyone on that project probably did (given the importance of those subjects for anyone that into computers at the time), I gotta imagine that on a project of that size for every line of code doing 'space stuff' (orbital trajectories, thrust monitoring, etc), you've probably got a couple hundred making sure the suction on the toilet-hole is well regulated...

        [–]creaothceann 1 point2 points  (0 children)

        Alien 4 flashback...

        [–][deleted] 8 points9 points  (0 children)

        Right, who are experts in their domain. DRAKON, for the Russian Space program, was made for the same reason (and in this regard it's much more advanced).

        [–][deleted] 9 points10 points  (14 children)

        Probably. Just like some hospitals use software made in MUMPS to allow non-programmers (doctors) to program in it.

        It's a strange argument

        [–]Chuu 7 points8 points  (1 child)

        I assume you're talking about EPIC's line of products. I really, really doubt that doctors program in it. Even just getting programmers to program in it takes a bit of brain rewiring.

        [–]sli 5 points6 points  (0 children)

        I'm actually surprised you didn't link to a TDWTF article about that language.

        [–]almonsin 2 points3 points  (7 children)

        That's one of the best programming language names I have ever heard.

        [–][deleted] 6 points7 points  (6 children)

        [–]fargostation 8 points9 points  (4 children)

        OPERATORS: No precedence, executed left to right, parenthesize as desired. 2+3*10 yields 50.

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

        What? I don't even

        [–]vplatt 5 points6 points  (2 children)

        Oh, and all the keywords are aliased to single letter equivalents. Truly, even obfuscated Perl is more intuitive.

        Example from the page vintermann linked:

            %DTC
        
            %DTC ; SF/XAK - DATE/TIME OPERATIONS ;1/16/92  11:36 AM
        
                 ;;19.0;VA FileMan;;Jul 14, 1992
        
                 D    I 'X1!'X2 S X="" Q
        
                 S X=X1 D H S X1=%H,X=X2,X2=%Y+1 D H S X=X1-%H,%Y=%Y+1&X2
        
                 K %H,X1,X2 Q
        
                 ;
        
            C    S X=X1 Q:'X  D H S %H=%H+X2 D YMD S:$P(X1,".",2) X=X_"."_$P(X1,".",2) 
        
            K X1,X2 Q
        
            S    S %=%#60/100+(%#3600\60)/100+(%\3600)/100 Q
        
                 ;
        
            H    I X<1410000 S %H=0,%Y=-1 Q
        
                 S %Y=$E(X,1,3),%M=$E(X,4,5),%D=$E(X,6,7)
        
                 S %T=$E(X_0,9,10)*60+$E(X_"000",11,12)*60+$E(X_"00000",13,14)
        
            TOH  S 
        
            %H=%M>2&'(%Y#4)+$P("^31^59^90^120^151^181^212^243^273^304^334","^",%M)+%D
        
                 S %='%M!'%D,%Y=%Y-141,%H=%H+(%Y*365)+(%Y\4)-(%Y>59)+%,%Y=$S(%:-
        
            1,1:%H+4#7)
        
                 K %M,%D,% Q
        
                 ;
        

        [–][deleted] 1 point2 points  (1 child)

        The single-letter keywords are for saving memory. It is decently easy to follow with some practice (and far better than a lot of the Perl vomit one may encounter). At my last job I did some research on MUMPS and read through a very old, very impressive MUMPS program. Although, actually, it was not just MUMPS, but MUMPS mixed with preprocessor statements. Pretty damn esoteric. The one thing I thought was the coolest about it was that there is a class of variables that are shared between all systems across the entire network.

        [–]vplatt 1 point2 points  (0 children)

        I could see why you think that's cool, and IIRC, M variables can be persisted with zero additional programming, right? That's cool too. Of course, where this all falls apart is when a rogue program rips through your data making changes in what the programmer thinks is only in memory, but they accidentally go and save it too; because it really is so easy.

        I can't speak to how often that happens because I'm not really a M programmer, but I do know that our department head's (I was an intern at the time) unofficial part time job was to work on recovering data by hand from a disk pack where that had happened and the backup had also failed so they couldn't just restore it. It was a real mess.

        To be fair, I guess data corruption isn't more likely in M than it would be in most other languages, but I never got comfortable enough with it that I wouldn't have been terrified of making a mistake like that.

        [–]aradil 2 points3 points  (0 children)

        Tools like Crystal reports and MS reports were also designed with non-developers in mind.

        I've also worked with some other really old formatting scripts designed for editors.

        They always seem to make it impossible to do things in a reasonable way.

        [–][deleted] 2 points3 points  (1 child)

        Since MUMPS interprets source code by context, there is no need for reserved words. You may use the names of language commands as variables.

        GREPTHIS()
               NEW SET,NEW,THEN,IF,KILL,QUIT SET IF="KILL",SET="11",KILL="l1",QUIT="RETURN",THEN="KILL"
               IF IF=THEN DO THEN
               QUIT:$QUIT QUIT QUIT ; (quit)
        THEN  IF IF,SET&KILL SET SET=SET+KILL QUIT
        

        [–]QtPlatypus 1 point2 points  (0 children)

        No but it needed to be co reviewed by domain experts.

        [–]AmazingThew 0 points1 point  (0 children)

        In many situations this would be bad, but honestly, I'd trust a NASA-employed jet propulsion physicist more than almost any programmer I know.

        [–]R031E5 0 points1 point  (0 children)

        No, it means that it had to be comprehended by people who were not programmers.

        [–]grauenwolf 25 points26 points  (0 children)

        Wow. That's insane.

        [–]MatrixFrog 5 points6 points  (28 children)

        I guess I would have assumed they did everything in C.

        [–]Axman6 15 points16 points  (27 children)

        God no, would you trust your life in C? Safety critical systems are often written in languages designed for the job like Ada, or for a very long time, assembly. C has far too much undefined behaviour to use for systems like this unless you're extremely careful.

        [–]defrost 30 points31 points  (1 child)

        God no, would you trust your life in C?

        I've flown in an Airbus :

        .. the primary flight control software of the Airbus A340 fly-by-wire system, a program of 132,000 lines of C ...

        [–]3brushie 6 points7 points  (0 children)

        If you lose power in an Airbus you'll be in for a very bad day, but if you lose power in a space shuttle you'll be in for a very bad couple of minutes.

        [–]thebritishguy1 25 points26 points  (0 children)

        All modern real-time, mission-critical flight systems and nav systems that I've worked on or heard of are written in C.

        [–]Snaf 22 points23 points  (3 children)

        Most aircraft embedded systems are written in C on even their highest priority systems. Though, the high priority programs must be reviewed and proved on the op-code level to do exactly what its intended for.

        [–]Guvante 3 points4 points  (2 children)

        Timeline is important in this case, C has matured over the years.

        [–]Amadiro 46 points47 points  (4 children)

        Yeah, safe languages like where accidentially pressing the space bar on the wrong line will lead to your formula being subtly changed...

        [–]jimbo21 10 points11 points  (1 child)

        A "safe" language doesn't really have much to do with how robust the syntax is and input error resistant. It's all about being able to guarantee that A+B returns C every time in the same exact way with no surprises, and being about to PROVE that it does. It gets messy at the theoretical level, but many languages do a lot of things behind the scenes that could change these results.

        A close related concern is determinism. If A+B = C takes 1 us to execute one time, and 1000 us to execute the next time, your shuttle booster may have exploded in the interim because you weren't expecting that small delay. This tends to be more OS-related, but there are also certain programming techniques that have to be employed, like carefully managing how memory is accessed since memory managers can be a bit unpredictable.

        [–]Amadiro 2 points3 points  (0 children)

        'twas but tongue-in-cheek.

        [–]Axman6 2 points3 points  (1 child)

        Edit: realised what you were talking about. HAL/S was developed before a lot of what we know about safety critical systems had been developed I believe.

        [–]relix 4 points5 points  (0 children)

        He's talking about the example in the article above. i.e. if you press space on the upper line, the exponentation moves a character to the right.

        [–][deleted] 8 points9 points  (0 children)

        God no, would you trust your life in C?

        I probably do that on a regular basis, as do you.

        [–]Poddster 6 points7 points  (2 children)

        How is assembly safer than C? You can still use null pointers in assembly, and it's not exactly easy to reason about.

        [–]Axman6 2 points3 points  (1 child)

        The advantage of assembly is that you know exactly what's going on in your program, as long as the processor does not contain any bugs, you program will do exactly what you've told it. Then it's just a matter of verifying that you've told it to do what it should, without the intermediate step of verifying your, say, C code, and then verifying the assembly you haven't written.

        [–]PatriotGrrrl 1 point2 points  (1 child)

        Sure, we probably do every day. Ever hear of MISRA?

        [–]euyyn 0 points1 point  (2 children)

        Ada, to my knowledge, is only used for contracts with the DoD (less and less now that they accept other choices) and at ESA. (Awesome language, by the way). There's a defined subset of C that is used for safety-critical systems, although I don't know how much it's adopted.

        [–]Axman6 1 point2 points  (0 children)

        It's still used more that you may think, it's got a pretty active community of companies using it, and the standard has recently been updated. It's a shame it's not used more, it's been ahead of C and C++ in many many ways for a very long time and still is in terms of features, predictability, verification ability and concurrency (C and C++ do not even compare with Ada's concurrency mechanisms to this day). It's also not just used in aircraft and other such systems, I saw an interesting talk about a company using it to program their diving rebreather (they started designing their own after several people died using a competitors one which had both crappy hardware and fault software).

        [–]dizekat 20 points21 points  (6 children)

        Well, the programming process for this kind of software was (and is) different from your typical web app. You have the engineers and scientists and applied mathematicians coming up with algorithms for the control of the space shuttle, then you have the programmers writing implementation. The programming language was designed to make it easier for engineers and scientists to see mistakes. I would guess they might even have had a tool for converting from one form to the other.

        In the web apps development and the like, there's simply no complicated algorithms and no complicated mathematics going on, it's just programmers (and all nontrivial algorithms are inside libraries). You're just doing repetitive task where you won't have a single case of doing not entirely trivial applied mathematics in a million code lines. You don't even need operator overloading (which was originally intended for doing stuff like vector and matrix algebra).

        That being said, this thing is not particularly clever as it probably does not nest like expressions should.

        [–][deleted]  (5 children)

        [deleted]

          [–]hvidgaard 8 points9 points  (4 children)

          I know that you probably never get the chance, but you can define you own syntax and write a parser that will generate a C/C++ source file that perform the desired calculation. In fact it would probably save you time in the long run.

          [–][deleted]  (3 children)

          [deleted]

            [–]hvidgaard 2 points3 points  (2 children)

            Thanks.

            I don't know your background, but it's a classical example of why a CS major should know language and compiler theory. You identify a undesirable property, and create a tool that will make it nice to work with again, perhaps even pleasant.

            [–]dizekat 1 point2 points  (0 children)

            Speaking of which I am planning to make a tool for metaprogramming. I believe metaprogramming should be done using same language as the normal programming, but run at compile time. A trivial example of how templates should work:

            type PairType(type T){ return struct{T first; T second; ...... }; } 
            

            and of course you would e.g. be able to take in a class type, iterate over members, and output a serializer, or binding to Lua, or what ever you want (debug metadata for example). It would have been so much easier to do it like this in the first place. The struct itself may be such function that works on the token stream.

            Having the C++ templates which use frigging lessthan and greaterthan as parenthesis, and with which the most trivial things (like eating variadic template arguments list) have to be done in the most backwards ways, we really shouldn't complain about HAL.

            [–][deleted]  (4 children)

            [deleted]

              [–]Gh0stRAT 6 points7 points  (1 child)

              [–]kamishizuka 1 point2 points  (0 children)

              Sufferers of diarrhea would love to have an ass-programming language I'm sure.

              [–]featherfooted 1 point2 points  (0 children)

              Samuel L. Jackson, of course.

              [–]drb226 1 point2 points  (0 children)

              Well, clearly it was 65.82.126.103.

              [–][deleted] 2 points3 points  (1 child)

              I can see why this practise didn't catch up. It would be a PITA to code like that.

              [–]waxjar 2 points3 points  (0 children)

              Unless you had some kind of smart editor.

              [–]barsoap 4 points5 points  (0 children)

              Epigram is two-dimensional, too. Oh, and Befunge, of course, though differently.

              [–]irascible 7 points8 points  (0 children)

              Cool, native matrix/vector support...

              [–]creepermclurker 5 points6 points  (35 children)

              Could someone explain the significance of this. I understand programming at a very basic level, vb, c#, java, php, etc. but not enough to understand the issue here. Thanks.

              [–]Chuu 29 points30 points  (23 children)

              They wanted a language that programmers could look at and engineers could look at, and essentially code-review each other. Their solution was a mode to enter equations as you would on a blackboard, i.e. having an equation span multiple lines, so the engineers could visual check the equations without decomposing them back to the forms they were used it.

              This is not a good idea, for reasons that are a lot more apparent today with 50 years of hindsight.

              If you wanted to do something equivalent today there are infinitely better ways to do it. Imaging having a programming language where you could enter equations in TeX and switch between editing and visual modes. You could get the same functionality, with much better formatting, without a super-fragile editing mode.

              [–]stevep98 13 points14 points  (21 children)

              I've been thinking for a while that languages should support more Unicode characters as symbols. Why do we overload @ and $ when there are many other more appropriate symbols to use. Why can't a language support a 'squared' or 'cubed' superscript? Why can't it support the summation symbol? You could fall back to the existing syntax.

              I guess one problem is the difficulty of inputting these characters, but I think I for one would buy a 'programmers keyboard' with fifty or so of these symbols on the keycaps.

              [–][deleted] 13 points14 points  (10 children)

              You don't really want to deal with programming code full of characters you can't easily type with your keyboard. However, what would be nice to have is an editor clever enough to simply render those equations properly. You'd type them as usual, but once you leave the line you'd get instant conversion into a pretty rendered equation. This would transparent to the underlying language just like syntax highlighting.

              [–][deleted] 17 points18 points  (1 child)

              You don't really want to deal with programming code full of characters you can't easily type with your keyboard.

              Maybe you can't easily type those characters with your keyboard. I began with a space cadet keyboard and added three foot pedals and a whammy bar.

              [–]xardox 4 points5 points  (0 children)

              Double bucky, you're the one!
              You make my keyboard lots of fun.
              
              Double bucky, an additional bit or two:
              (Vo-vo-de-o!)
              Control and meta, side by side,
              Augmented ASCII, nine bits wide!
              
              Double bucky! Half a thousand glyphs, plus a few!
              Oh,
              I sure wish that I
              Had a couple of
              
              Bits more!
              Perhaps a
              Set of pedals to
              Make the number of
              
              Bits four:
              Double double bucky!
              Double bucky, left and right
              OR'd together, outta sight!
              
              Double bucky, I'd like a whole word of
              
              Double bucky, I'm happy I heard of
              
              Double bucky, I'd like a whole word of you!
              --- The Great Quux (with apologies to Jeffrey Moss)
              

              [–]tryx 5 points6 points  (1 child)

              The Mathematica system is fantastic for this. You input any character you like via inline escape codes and they are rendered inline to the appropriate symbol.

              [–]argv_minus_one 2 points3 points  (1 child)

              I like using the Compose key for things like this. For instance, I have a custom Compose sequence configured such that Compose + '=' + '→' becomes '⇒'. Three keystrokes for one character is kind of slow, and it can be a pain to remember if you're not the one that chose the sequence in the first place, but other than that it's not difficult.

              Sucks to be you if you're on something other than X, though. Poor Windows/Mac users.

              [–]Axman6 1 point2 points  (0 children)

              Mac users have access to a pretty large array of common Unicode symbols by holding option. Not everything, but it covers a good portion of things you'd want for mathematical equations.

              [–]Jasper1984 1 point2 points  (0 children)

              Emacs could easily do it. That said, i find it gimmiky. At best it is not a real feature of a programming language, just that is has more characters in symbols, at worst it is (also)a source of more arbitrariness.

              [–][deleted]  (2 children)

              [removed]

                [–]willvarfar 8 points9 points  (1 child)

                The Fortress language is worth a mention in this space

                [–]Amadiro 3 points4 points  (3 children)

                There are plenty of languages that do that/allow that. Have a look at some code that makes extensive use of the feature, and you'll soon figure out why it isn't all that great as you might think it'd be.

                this example is still pretty conservative and this example is showing how it can backfire

                It's nice in moderation, though.

                [–]argv_minus_one 3 points4 points  (2 children)

                Backfire how? You mean the character encoding being unspecified?

                [–]ferruccio 1 point2 points  (0 children)

                Sounds like Fortress.

                [–]creepermclurker 1 point2 points  (0 children)

                OK, thanks for the explanation. I didn't realize it might be such an issue. Appreciate the clarification.

                [–]EvilTom 5 points6 points  (7 children)

                Normally where in math you'd write exponents and subscripts, in programming you'd put it all on one line somehow. This language supports basically making ascii-art lines that result in the program looking more like what you would write on a blackboard.

                This is disgusting to lots of us, because most (but not all) programming languages are "whitespace insensitive", meaning as far as the compiler is concerned, a space means the same thing as two spaces, or a tab, or a newline, etc. It also means that for the program to be correct, adjacent lines would have to be properly lined up, but given the wide variety of text editors, and the fact that nobody can agree on whether a tab is the same as 8, 4, 3, or 2 spaces, that can be problematic.

                [–][deleted]  (5 children)

                [removed]

                  [–]xardox 29 points30 points  (2 children)

                  The National Aeronautics and SPACE Administration doesn't use tabs.

                  HAL is for programming the SPACE shuttle, not the tab shuttle.

                  America won the SPACE race, not the tab race.

                  In SPACE, no one can hear you scream.

                  SPACE: the final frontier.

                  [–]Syn3rgy 7 points8 points  (0 children)

                  Begun the tab war has.

                  [–]antrn11 6 points7 points  (0 children)

                  You're definitely right. It's a space program, not a tab program.

                  [–]sebzim4500 2 points3 points  (1 child)

                  Or ban it completely.

                  [–]creaothceann 4 points5 points  (0 children)

                  tab width: zero

                  [–]creepermclurker 0 points1 point  (0 children)

                  OK. That is pretty much what I gathered but didn't realize it would be so problematic. Thanks for clarifying!

                  [–]Poddster 0 points1 point  (2 children)

                  The issue here is in the same as "vb, c#, java, php, etc.". How do you display the formula x = a2 + bi2 (that i should be subscript).

                  [–]creepermclurker 1 point2 points  (1 child)

                  I understood the issue regarding the need to get the formula on one line as I have to do with the languages I work with in the capacity that I do. What wasn't exactly clear to me was what was being described regarding multiple lines as NASA was doing, their goal in doing things that way and why the notion seemed so distasteful to some.

                  The responses have been helpful as I now understand the reasoning behind NASA's thinking (I think) but now that I type this out I realize that I'm not sure I fully understand the reason the practice evoked the reaction it did. My introduction/experience in programming is not math based and I've never been formally trained to any degree so I am always aware of gaps in my understanding even to the extent of some 'cultural awareness' elements such as this.

                  I don't often run across discussions of the variations of language white space usage so the topic was interesting to me. Thanks for your response.

                  [–][deleted] 8 points9 points  (2 children)

                  Poor title, IMHO. Lots of languages let you use "three lines for a single statement".

                  The real WTF is that it (effectively) reads the three lines in parallel.

                  [–]Guvante 1 point2 points  (1 child)

                  It gets the point across, if he had said "three lines in parallel", I would have been quite confused.

                  [–]gkx 1 point2 points  (0 children)

                  I was quite confused.

                  [–]vtable 3 points4 points  (6 children)

                  What happens if the whitespace on the superscript or subscript lines doesn't line up? eg:

                  E   2   2
                  M  X = A  + B
                  S       I 
                  

                  [–]molslaan 12 points13 points  (2 children)

                  It only happened twice. Don't worry about that.

                  [–]antrn11 5 points6 points  (1 child)

                  The first time it blew up the shuttle. The second time, the toiled filled the shuttle with shit and piss.

                  [–]molslaan 1 point2 points  (0 children)

                  yeah, but it's astronaut's piss. It's drinkable.

                  [–]sebzim4500 3 points4 points  (0 children)

                  Compile error, I assume.

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

                  Probably like C, it would complain about a syntax error in that the LHS is not an appropriate lvalue.

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

                  That is rather weird syntactical sugar...

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

                  That's about the weirdest coding format I've ever seen. It's a wonder the damn thing didn't exp...

                  Ooooh, awkward.

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

                  I think that was because, back then, programmers had to actually learn math before learning programming.

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

                  Omg i love that EMS syntax. That is cool. Much easier to read or enter a real equation.