The Massachusetts General Hospital Utility Programming System (known a MUMPS, or simply M) is both a language and a database management system. First standardized by ANSI in 1977, it is actually quite a bit older, with roots extending into the 1960s. Since that time, it has become an ISO standard (with the most recent version being ISO/IEC 11756:1999). As a database management system, it is remarkably ahead of its time, being a type of NoSQL database (technically, a key/value store with hierarchical keys).

From a health IT perspective, it is important because many important systems such as VistA and Epic are written in MUMPS or related languages (such as Caché ObjectScript from InterSystems). Unfortunately, classical MUMPS has not evolved significantly since the MUMPS Development Committee (MDC) was suspended. As a DBMS, MUMPS (or more correctly, its implementations, which include at least InterSystems Caché and the open source GT.M) is excellent. As a language, on the other hand, it lacks critical features that any modern programming language really needs. Roughly, in order of importance, here are some of the features that I think are sorely needed, and which could be added to the language without breaking backward compatibility.

Libraries

The current language makes no provision for standard libraries For exaample, mathematical and string handling functions, I/O and networking, and support for standards such as XML and JSON. The MDC draft of the MUMPS standard does include standard notation for libraries, and specifies three required libraries: one for  character related functions (such as collation), one for strings, and one for mathematics. As an example, the cosine function is

$%COS^MATH

A library system should provide a mechanism for both implementers and users to define their own libraries. It should also provide a mechanism for linking to native libraries (written in C, or possibly another language such as Go).

Namespaces and Modules

In classical MUMPS there are no proper namespaces. Instead, code is logically divided into “modules” by prefixing names with a fixed string. For example, all routines in File Manager (used in VistA) have names beginning with “DI”, “DD”, or “%D”. Other applications are prohibited from using these  names by rule, rather than by mechanism. This makes modularity into a convention, and not something enforced or managed at the language level. This could be accomplished in part by allowing hierarchical (“dot separated”) names, such as

MyModule.PatientName

But a true module system requires more than this: it must be possible to import modules without fear of namespace collisions and, just as importantly, without otherwise changing the behavior of existing programs. For example, code in a module must not be able to modify non-module variables without being given explicit permission. This implies a concept of scope that does not now exist in MUMPS. There is the NEW command, which makes it possible to allocate new cocpies of variables on the stack frame, so that changes to that variable will disappear when the stack is popped (e.g., when a function or DO returns). This is similar to the situation in Perl prior to the advent of Perl 5. In Perl 4, there was a local() function that did essentially what NEW does in MUMPS. It put a copy of the variable on the stack, so that changes to that variable would not effect the caller. This is a restriction on extent, not on scope. With Perl 5 came the my operator. In code like

{
  my name;
 ...
}

The variable name is limited in scope to the section of code occuring inside the curly braces ({}). It does not descend into other scopes the way a local variable would, or in any other way “live on”. For the inclusion of modules to be side-effect free it is necessary to be able to specify that variables have module scope, and thus cannot affect the enclosing module except through defined interfaces.

Unicode

This is 2016, and there is no excuse for not supporting Unicode. As it happens, bot Caché and GT.M include support for Unicode, so long as the installation is configured to support it. They do it in different ways, but it comes down to using Z-functions to provide alternate versions of functions like $EXTRACT, one version operating on characters, and one on bytes.

Standardized I/O and Networking

As a philosophical matter, MUMPS has left input and output (I/O) to implementations. I understand the reasons for doing this, and note that C also relegates I/O to libraries. But there is a standard library that C programmers can rely on. There is no corresponing libray in MUMPS. Today, distributed and network aware applications are the rule, and not the exception.It can be argued that MUMPS is a database language, and that it should focus on doing one thing well. But healthcare applications need to support HL7, FHIR, and low level networking (sockets), and need to be able to do so in a standard, predictable way.

Conclusion

I do not intend this to be a criticism or an argument against using MUMPS. In fact, I think the longevity of MUMPS is a testament to its continued viability. But there are certain features of the language that are prorblematic, and the stalleddd standardization process makes it difficult to update. I’ve argued elsewhere that code needs to be actively maintained if it is to remain useful. The same is true of standards.