Beginner

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Pull the YottaDB image
docker pull yottadb/yottadb-base:latest-master

# Run the local variables example
docker run --rm -v $(pwd):/app -e ydb_routines=/app yottadb/yottadb-base:latest-master yottadb -run variables

# Run the type coercion example
docker run --rm -v $(pwd):/app -e ydb_routines=/app yottadb/yottadb-base:latest-master yottadb -run coercion

# Run the globals example
docker run --rm -v $(pwd):/app -e ydb_routines=/app yottadb/yottadb-base:latest-master yottadb -run globals

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" becomes 123; "hello" becomes 0.
  • 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 — Returns 0 (undefined), 1 (value only), 10 (descendants only), or 11 (both value and descendants).
  • KILL removes variables — Unlike setting a variable to empty, KILL completely 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
Last updated:

Comments

Loading comments...

Leave a Comment

2000 characters remaining