- MUMPS Language Syntax
MUMPS syntax allows multiple commands to appear on a line, grouped into procedures (subroutines) in a fashion similar to moststructured programming systems. Storing variables in the database (and on other machines on the network) is designed to be simple, requiring no libraries and using the same commands and operators used for working with variables in RAM.Overview
There have been several revisions to the MUMPS language standard between 1975 and 1999. The basic language structure has remained constant. The language standard can be viewed at [http://71.174.62.16/Demo/AnnoStd Annotated MUMPS Language Standard] , with examples of use in the online book [http://www.jacquardsystems.com/Examples/ MUMPS By Example] .
Whitespace
In MUMPS syntax, some spaces are significant; they are not merely
whitespace . There are contexts in which a pair of spaces has a different syntactic significance than a single space. However, extra spaces (in this context not syntactically significant) may always be added between commands for clarity, up to the line length limit in an implementation. Lines are syntactically significant, and carriage returns and linefeeds are not treated as white space; they are statement/function terminators. There is no requirement to put semicolons at the end of commands, and lines may be explicitly continued when needed.Procedures - MUMPS routines
A typical M procedure (a "routine" in MUMPS terminology) is analogous to a source file in C (in that the subroutines and functions relevant to a particular task/category are grouped together, for instance) and consists of lines of MUMPS code. Line labels can be used to create memory resident subroutines within the routine by starting the line with a label instead of whitespace. The same subroutine can be used from outside the parent routine's scope by referencing the label and routine name separated by a caret character (as in
SUBRTN^ABC
).A routine file might look like this (for a routine called 'sampleproc'):
In this case, labels have been attached to the first, fourth and eighth lines, creating subroutines within the parent routine. The fifth line makes a subroutine call within the same routine, to a subroutine called 'subproc'. It would also be possible for any other program to call that subroutine by fully specifying it, as
do subproc^sampleproc(argument)
. Even though the fourth line appears to be inside another subroutine, it can still be called from other routines withdo dosets^sampleproc
, and execution will continue with the first part of sampleproc() ignored.Even though sampleproc is defined as needing an argument, dosets is not, ao you would not pass any arguments to dosets. MUMPS also allows the programmer to jump to an arbitrary line within a subroutine.
do sampleproc+3^sampleproc
is equivalent todo dosets^sampleproc
.Variables and datatypes
MUMPS does not require declaration of variables, and is untyped: all variables, including numbers, are effectively strings. Using variables in a numeric context (eg, addition, subtraction) invokes a well-defined conversion in case the string is not a canonical number, such as "123 Main Street".
MUMPS has a large set of string manipulation operators, and its hierarchical variable management system extends to both RAM-based and disk-based variables. Disk resident (ie, database) variables are automatically stored in hierarchical structures. Most implementations use caching, node indexes and name compression to reduce the time/space cost of disk references.
All variables are considered to be 'sparse' arrays. In a MUMPS context, this means that there is no requirement for sequential nodes to exist —
A(1), A(99)
andA(100)
may be used without defining, allocating space for, or using any space for, nodes 2 through 98. Indeed, one can even use floating-point numbers and strings (A(1.2), A(3.3), A("foo")
, etc) where the subscript names have some meaning external to the program. The access function$ORDER ( A(1.2) )
returns the next defined key or subscript value, 3.3 in this example, so the program can readily manage the data. Subscripts are always returned (and usually stored) in sorted order.Given their sorting and naming features, it's not uncommon for subscript/variable names to be used as data stores themselves, independent of any data stored at their locations. This feature is often used for database indexes. Eg,
SET ^INDEX(lastname,firstname,SSNumber)=RecordNum
.Global variables - the database
The MUMPS term globals does not refer strictly to unscoped variables, as in the C tradition. MUMPS Globals are variables which are automatically and transparently stored on disk and persist beyond program, routine, or process completion. Globals are used exactly like ordinary variables, but with the caret character prefixed to the variable name. Modifying the earlier example as follows
results in creation of a new disk record, which is immediately inserted within the file structure of the disk. It is persistent, just as a file persists in most operating systems. Globals are stored in highly structured data files by MUMPS, and accessed only as MUMPS globals. MUMPS has a long history of efficient, stable, theoretically-sound cached, journaled, and balanced B-tree key/value disk storage, including transaction control for multiple file transaction 'commit' and 'roll-back' at the language/operating system level. Real-world databases can often grow unpredicatably (such as having 20 patients with a last name of 'Anderson' before you get any with surnames starting with 'B'), but modern MUMPS implementations are designed to structure the database efficiently as it grows.
For all of these reasons, one of the most common MUMPS applications is database management. MUMPS provides the classic
ACID properties as part of any standard MUMPS implementation. FileMan is an example DBMS built with MUMPS. Intersystems' Caché implementation allows dual views of selected data structures—as MUMPS globals, or as SQL data—and has SQL built in (called M/SQL). The MUMPS view allows programmers rather more control of the data, as there is no requirement to fit the data into the assumed rows and columns of relational SQL.Variable scoping
Since MUMPS's global variables are stored on disk, they are immediately visible to and modifiable by any other running program once they are created. RAM-based variables, called locals are only visible inside the currently running process, and their value is lost when the process exits. By default, however, all routines running in the same process share the same variable scope. A variable created by one routine is visible to its calling routine (and other routines it may call) and can be modified by them as well. The '
new
' command allows a routine to hide variables its caller might have created, and prevent itself from modifying them. It cannot prevent routines it calls from modifying its own variables, so good MUMPS programming practice is to have every routine 'new' the variables it uses.Multi-user, multi-tasking, multi-processor
MUMPS allowed multi-user operation at a time when memory was measured in kilobytes, and processor time was both scarce and slow, but processors themselves were even more so. Many MUMPS implementations included full support for multi-tasking, multi-user, multi-machine programming even when the host
operating system itself does not. For instance, a single PC running MUMPS under MS-DOSand equipped with multiple RS232 ports, behaved as a large minicomputer serving multiple ASCII terminals, with proper data sharing and protection.To demonstrate the ease of network operations, consider:
which gives A a value as before, but this time on the remote machine "DENVER". MUMPS programs are accordingly nearly trivial to distribute over multiple machines. This ease of network operation made it easy to expose the same sorts of distributed operation in SQL (and other) layers with ease.
Another use of MUMPS in more recent times has been to create
object database s. Intersystems' Caché implementation, for instance, includes such features natively.MUMPS can generate text in HTML or XML format as well, and can be called via the CGI interface to serve web pages directly from the database. It can also be used as a backend for web applications using Ajax background communication.
MUMPS also reads delimited datasets easily, such as the .csv (
comma-separated values ) files commonly used as an interchange format (eg, in exports from spreadsheets).
Wikimedia Foundation. 2010.