Variables and Types in MUMPS
Learn about local variables, typeless coercion, and hierarchical globals in MUMPS with practical Docker-ready examples
MUMPS takes a radically different approach to variables and types compared to most programming languages. There are no type declarations, no type keywords, and no distinction between strings and numbers at the storage level. Every value in MUMPS is stored as a string, and the language silently coerces between string, integer, and floating-point representations depending on context.
What makes MUMPS truly unique is its built-in hierarchical database. Variables prefixed with a caret (^) are called globals — they persist to disk automatically, surviving program termination and even system restarts. This means MUMPS has a database engine woven directly into the language itself, something no other mainstream language offers.
In this tutorial, you’ll learn how to create and manipulate local variables, understand how MUMPS coerces values between types, and work with the hierarchical globals that make MUMPS the backbone of healthcare information systems.
Local Variables
Local variables exist only during the execution of a routine. They require no declaration — simply assign a value with the SET command (abbreviated S).
Create a file named variables.m:
variables ; Local variables in MUMPS
; Assign variables with SET (or abbreviated S)
set name="MUMPS"
set year=1967
set pi=3.14159
;
; All values are stored as strings internally
write "name=",name,!
write "year=",year,!
write "pi=",pi,!
;
; Multiple variables can be set to the same value
set (a,b,c)=0
write "a=",a," b=",b," c=",c,!
;
; String concatenation uses the _ operator
set first="Hello"
set second="World"
set greeting=first_", "_second_"!"
write "greeting=",greeting,!
;
; KILL removes a variable entirely
kill greeting
;
; $DATA() checks if a variable is defined
; Returns 0 if undefined, 1 if defined with a value
write "$data(greeting)=",$data(greeting),!
write "$data(name)=",$data(name),!
;
; $GET() returns a variable's value or a default if undefined
write "$get(greeting,""gone"")=",$get(greeting,"gone"),!
;
; Special variables (intrinsic) start with $
write "$horolog=",$horolog,!
write "$job=",$job,!
quit
The $HOROLOG special variable contains the current date and time as two comma-separated integers: days since December 31, 1840 and seconds since midnight. The $JOB special variable contains the process ID. These are read-only system-provided values.
Type Coercion
MUMPS is typeless — there are no integers, floats, or strings as distinct types. Every value is a string, but arithmetic and comparison operators interpret values numerically when needed. This implicit coercion follows precise rules.
Create a file named coercion.m:
coercion ; Type coercion in MUMPS
;
; Arithmetic operators force numeric interpretation
set x="42"
write """42""+8=",(x+8),!
;
; Leading numeric characters are extracted
set mixed="123abc"
write """123abc""+7=",(mixed+7),!
;
; Non-numeric strings evaluate to 0 in numeric context
set word="hello"
write """hello""+5=",(word+5),!
;
; Decimal and negative strings work too
set neg="-3.5"
write """-3.5""*2=",(neg*2),!
;
; Numeric comparison: > < = use numeric interpretation
write "10>9=",(10>9),!
;
; String comparison: ] (follows) uses ASCII collation
; "9" sorts AFTER "10" because "9" > "1" character-by-character
write """9""]""10""=",("9"]"10"),!
write """10""]""9""=",("10"]"9"),!
;
; Boolean operators: & (and), ' (not)
; Any non-zero value is true, 0 is false
write "1&1=",(1&1),!
write "1&0=",(1&0),!
write "'0=",('0),!
write "'1=",('1),!
;
; The unary + operator forces numeric interpretation
write "+""007""=",(+"007"),!
write "+""3.50""=",(+"3.50"),!
write "+""abc""=",(+"abc"),!
quit
The numeric coercion rules are straightforward: MUMPS scans from the left of the string, extracting as many characters as form a valid number (including an optional leading minus sign and one decimal point). Everything after the first non-numeric character is ignored. If no leading digits exist, the value is zero.
The ] (follows) operator performs string collation comparison rather than numeric comparison. This distinction is critical when working with data that might look numeric but should be compared as strings.
Hierarchical Globals
Globals are MUMPS’s most distinctive feature — variables that persist automatically to disk. They are prefixed with a caret (^) and can have multiple subscript levels, forming a sparse hierarchical tree structure. This built-in database is what has made MUMPS the foundation of healthcare information systems for decades.
Create a file named globals.m:
globals ; Hierarchical globals in MUMPS
;
; Local variable - exists only during execution
set localVar="I am local"
write "Local: ",localVar,!
;
; Global variables (^prefix) persist to disk
set ^color(1)="Red"
set ^color(2)="Green"
set ^color(3)="Blue"
;
; Traverse a global with $ORDER()
write !,"Colors in ^color:",!
set i=""
for set i=$order(^color(i)) quit:i="" do
. write " ^color(",i,")=",^color(i),!
;
; Globals support multiple subscript levels
set ^employee("E100","name")="Ada Lovelace"
set ^employee("E100","dept")="Engineering"
set ^employee("E100","skills",1)="Analysis"
set ^employee("E100","skills",2)="Mathematics"
;
write !,"Employee record:",!
write " Name: ",^employee("E100","name"),!
write " Dept: ",^employee("E100","dept"),!
;
; Traverse subscripts at the skills level
write " Skills:",!
set s=""
for set s=$order(^employee("E100","skills",s)) quit:s="" do
. write " ",s,": ",^employee("E100","skills",s),!
;
; $DATA() return values for globals:
; 0 = undefined
; 1 = has value, no descendants
; 10 = no value, has descendants
; 11 = has value AND descendants
write !,"$data(^employee(""E100""))=",$data(^employee("E100")),!
write "$data(^employee(""E100"",""name""))=",$data(^employee("E100","name")),!
write "$data(^employee(""E999""))=",$data(^employee("E999")),!
;
; Clean up globals so they don't persist between runs
kill ^color,^employee
quit
The $ORDER() function is fundamental to MUMPS programming. It returns the next subscript at a given level in collation order, making it the primary way to iterate through globals. When there are no more subscripts, it returns an empty string, which serves as the loop termination condition.
Notice the $DATA() return values: 10 means a node has descendant nodes but no value of its own (like ^employee("E100")), while 1 means a node has a value but no descendants (like ^employee("E100","name")). This distinction is important for navigating hierarchical data structures.
Running with Docker
| |
Expected Output
Output from variables.m (note: $horolog and $job values will vary):
name=MUMPS
year=1967
pi=3.14159
a=0 b=0 c=0
greeting=Hello, World!
$data(greeting)=0
$data(name)=1
$get(greeting,"gone")=gone
$horolog=67890,43200
$job=1234
Output from coercion.m:
"42"+8=50
"123abc"+7=130
"hello"+5=5
"-3.5"*2=-7
10>9=1
"9"]"10"=1
"10"]"9"=0
1&1=1
1&0=0
'0=1
'1=0
+"007"=7
+"3.50"=3.5
+"abc"=0
Output from globals.m:
Local: I am local
Colors in ^color:
^color(1)=Red
^color(2)=Green
^color(3)=Blue
Employee record:
Name: Ada Lovelace
Dept: Engineering
Skills:
1: Analysis
2: Mathematics
$data(^employee("E100"))=10
$data(^employee("E100","name"))=1
$data(^employee("E999"))=0
Key Concepts
- Typeless by design — MUMPS has no type declarations. Every value is stored as a string and coerced to numeric form only when an operator demands it.
- Coercion rules are deterministic — MUMPS scans from the left, extracting leading numeric characters.
"123abc"becomes123;"hello"becomes0. - Local vs global variables — Local variables (no prefix) exist only during execution. Global variables (
^prefix) persist automatically to disk. - Hierarchical globals are the database — Globals with subscripts form a sparse tree structure, eliminating the need for a separate database system.
$ORDER()traverses data — The primary way to iterate through subscripted variables, returning the next subscript in collation order.$DATA()reveals structure — Returns0(undefined),1(value only),10(descendants only), or11(both value and descendants).KILLremoves variables — Unlike setting a variable to empty,KILLcompletely removes it and all its descendants.- Special variables provide system info — Intrinsic variables like
$HOROLOG(date/time) and$JOB(process ID) are read-only system values.
Running Today
All examples can be run using Docker:
docker pull yottadb/yottadb-base:latest-master
Comments
Loading comments...
Leave a Comment