Hacker News new | ask | show | jobs
by al2o3cr 4515 days ago
/me drops the MUMPS reference manual on the table

That whole language is one long-running WTF.

2 comments

This line in MUMPS is not only valid, it also actually does something potentially useful:

    s:foo'="" foo(foo)=foo
It's actually a bit tricky to explain what it does. Everything in MUMPS is effectively a tree. Each tree has a value in the "root node" and you can set it like this:

    set foo="hello"
You can also put data deeper into the tree:

    set foo("fizz")="buzz"
So if something is passed to you and you want to know if you can treat it as a string, you test to see if it's a null string:

    if foo'="" do [something]
('= means !=)

Two more features: 1) Almost every directive can be reduced to one letter. 2) If I want to quit based on a condition, I can do either if condition quit or quit:condition

So the line above is more legibly written as

    if foo'=""  set foo(foo)=foo
So if foo="bar", it's equivalent to:

    set foo("bar")="bar"
It is amazing that MUMPS will be 50 years old in 2 years -- and it still alive and kicking.

An emergency MUMPS project is still my highest billing project (per hour) ever.

What was the rate?
f p=2,3:2 s q=1 x "f f=3:2 q:f(asterisk)f>p!'q s q=p#f" w:q p,?$x\8+18

(Not sure if this is going to mess up the formatting, so apologies in advance). This (shamelessly stolen from a usenet sig) will print out a table of primes with formatting. Adding a quit based on max prime size is left as exercise to the reader.

Explanation: f = for, but basically used as a while loop since we don't have a terminate condition ('p' is used as the counter variable and we would normally have an upper limit, but since we don't it will keep iterating until something breaks)

We're setting the variable 'p' to 2 on first iteration of the loop, 3 on the next, and then going up by 2 on subsequent.

Then, we're setting the variable 'q' to 1.

'x' is short for XECUTE. It looks at the string following it and executes it as code.

"f f=3:2 q:f(asterisk)f>p!'q s q=p#f"

This is another loop, with the variable 'f' used as the counter, starting at 3 and incrementing by 2.

Each loop iteration, it checks if f^2 is greater than p or if q == 0. If not, it proceeds to set q to p modulo f.

To sum things up: We quit the loop if either we've checked all candidates (excluding evens) up to ~sqrt(p) or if one of these evenly divides p (that is, modulo 0).

The tricky bit:

w:q p,?$x\8+18

w:q == WRITE, using the value of 'q' as a post-conditional, only to be executed for non-zero values of q.

If we write, we will write 'p', setting the position of the cursor with '?' (syntax particular to write) using the '$x' variable (built-in for the current cursor position).

Note: $x\8+18 evaluates to (($x INTEGER DIV 8)+1)8

First line:

GTM>f p=2,3:2 s q=1 x "f f=3:2 q:ff>p!'q s q=p#f" w:q p,?$x\8+18

2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71

Edit: Formatting is messed up. (asterisk == '* '). I could have escaped, but didn't want to add whitespace.

That's actually more readable than APL, and once you said "f = for" I automatically made the mental association "s = set" and "x = execute". It wasn't actually that hard to figure out the rest from that...

and something about that code reminds me of vi commands.