Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Cheesily copied-and-pasted from 99-bottles-of-beer.net (http://www.99-bottles-of-beer.net/language-mumps-415.html):

    Mumps is now called M or cache but it was originally called Mumps.
    See http://www.camta.net/aboutm.htm

    ; The following is a single line of code
    beer    ; Randy M. Hayman ([email protected])
            for i=99:-1:1 w !,i," bottle",$S(i=1:"",1:"s"),
            " of beer on the wall, ",i," bottle",$S(i=1:"",1:"s"),
            " of beer.",!,"Take one down, pass it around, ",
            i-1," bottle",$S(i=2:"",1:"s")," of beer on the wall.",!
I've written compilers for GNU Make, and I've translated C into Perl, and that still makes my eyes bleed... so, as far as I can tell:

Commands can be abbreviated down to a single letter, so w = WRITE. Multiple commands can be glued together with whitespace. Strings are as normal, but ' is the not operator. There is no => or <= operators; use `< or `> respectively. There is Javascript-esque dodgy implicit type conversion from strings to ints, but dodgier ("aa1"+1 is 1; "1aa"+1 is 2). Commands can be suffixed with a colon and a boolean expression and they'll be executed conditionally. $ precedes a function call. ! is the OR operator, except in a WRITE command where it prints a newline. The @ expression is the equivalent of eval(), and yes, all your local variables are in scope when it runs. $test contains the value of the conditional in the IF command most recently in scope (as distinct from conditional execution). ELSE is a statement which executes the rest of the line only if $test is 0. Putting IF and ELSE on the same line doesn't work (imaginary cookie for anyone who can guess why). An extra space is required between commands if the first command takes no arguments. Variables are global unless declare local.

I believe $S(...) is the equivalent of switch; $S(i=1:"",1:"s") contains two conditions; if i=1, then ""; otherwise if 1, "s" (1 is boolean true).

The break statement is called QUIT. The return statement is also called QUIT. The BREAK statement actually drops out to the debugger. The quit statement is actually called HALT. the sleep statement is called HANG.

If a global variable is preceded with a ^, it is persisted by name to the database; some versions have transactions. Arrays are key/value sets with many indices. The docs say that trees are common, using a syntax like ^mytree(path,to,tree,node,from,root). ...which is actually quite cool.

I am torn between admiration for people who can get useful work done in this, and horror that such a thing really exists in a non-ironic sense.

All that's from: https://www.cs.uni.edu/~okane/source/MUMPS-MDH/MumpsTutorial...



Another thing that's really weird about MUMPS is that variables are dynamically scoped. So this bit of code prints 5:

  foo() ; declare function foo
    n x ; declare variable x
    s x=1 ; set x to 1
    d bar() ; call bar
    w x ; print x
    q ; return
  bar()
    s x=5 ; set x to 5. Since x is not declared in this function's scope, it will search the symbol table of the calling function and overwrite its x
    q
I've run into so many bugs caused by something like this.


That'll be because there's only a single namespace, and the NEW command simply copies the values of the named global variables onto the stack and copies them back again at the end of the function.

I'm actually kinda used to that; I grew up with BBC Basic, which behaves the same way:

     10 i = 0
     20 PROCtest1
     30 END
     40 :
     50 DEF PROCtest1
     60 LOCAL i
     70 i = 1
     80 PROCtest2
     90 ENDPROC
    100 :
    110 DEF PROCtest2
    120 PRINT i
    130 ENDPROC
    
    > RUN
    1
...it occurs to me that BBC Basic, at least the later versions with block IFs, is a better language than Mumps in almost every way (except the integrated database stuff)!


Modern use of MUMPS mandates that each subroutine use the N(EW) command to instantiate its own versions of variables. If that was done above, '1' would have been printed instead of '5'.


Many of the M implementations today (Cache, MiniM, GT.M) support <= and >=. That's a recent development in the case of GT.M (mid 2014).




Consider applying for YC's Fall 2026 batch! Applications are open till July 27.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: