The first time I had ever heard of MUMPS (also known as the M programming language) it was in an entry on the awesome Daily WTF. After the first pass through the article, I assumed, like several other people, that MUMPS was a cooked up name for a language whose identity was being protected. However, one very helpful commenter wrote that the language did, indeed, exist and had not been anonymized. Recently, the PLNews blog announced that there had been a new release of an Open Source MUMPS compiler/interpreter system. Curious, for reasons of archeology, if nothing else, I downloaded the source and compiled it. Then the fun part: I started playing with this relic.
Mumps documentation is a little hard to find. I suppose that the mere fact that some can be found is, in itself, a small miracle. The only real guide (aside from buying a book; 40 bucks isn’t a bad investment if you are doing this professionally, but for the casual tinkerer it seems sort of ridiculous) that I found was the quick and dirty manual that came packaged with the compiler itself.
The language itself is not unlike BASIC (and, I assume, COBOL or RPG) in spirit. The familiar procedural idiom is highly visible when looking at snippets like
> set a=”foo”
> write a
and is mostly interpreted (the manual indicates that, according to the M language spec, it is impossible to create a fully compiled M program that includes all the relevant features).
The most interesting feature of the language is none of its BASIC-esque glory, but the way it handles what are termed global arrays. Arrays in M/UMPS are, basically, multidimensioned hashtables. These themselves act like the arrays you would be used to if you have used PHP or Perl (as an interesting note along these lines, the $ sigil is basically the opposite of the one used in PHP, variables, or Perl’s scalar variables; it is used to, instead, denote functions). Once one uses the ^ operator to access “global arrays”, one is no longer simply working on the currently running script. Rather, this data is written directly to disk in a tree-like structure which is not unlike the representation used by modern database systems. In addition, basic set operators are included in the language.
It is this whole idea that interests me. In many domains, this idea would be either nonsensical, but for most business apps that is all we really do. We read the database, do some processing, and write it back out. This model goes completely out the window for such programs as Latrunculi or Ocean that I am working on right now, neither of which use a database.
However, as I indicated, virtually every business application on the planet has this core workflow, even if the operation is to chew up some data and spit out some pretty pictures. Where does this leave us? All programs are stored procedures running on the database (or, all stored procedures are programs at the main computer’s level; however you want to see it). Now, there has been a great deal of talk about keeping all of the database layer in and of itself. This method of doing things seems to have, by and large, been passing in favor or using prepared statements in the main application code, eliminating the middle man of stored procedures. For better or worse, this makes the whole idea of separating a database intensive application (which is what every tracking, accounting, or point of sale system really is) more or less superflous. Alex of the Daily WTF even wrote an article on this subject. The reason why the line between the business rule layer and the data access is so blurry is because the line itself is really nonexistant. Business rules are little more than a description of what data we want to retrieve and what calculations we want to run.