Arithmetic operator 'plus' (+)

Arithmetic operator 'minus' (-)

Arithmetic operator 'times' (*)

Arithmetic operator 'divided by' (/)

Arithmetic operator 'integer divided by' (\)

Arithmetic operator 'modulo' (#)

Arithmetic operator 'to the power of' (**)

String operator 'concatenate' (_)

Assignment operator 'becomes' (=)

Relational operator 'is equal to' (=)

Relational operator 'object is equal to' (==)

Relational operator 'is greater than' (>)

Relational operator 'is less than' (<)

Relational operator 'is less than or equal to'

Relational operator 'is greater than or equal to'

Relational operator 'matches pattern' (?)

Relational operator 'contains' ([)

Relational operator 'follows' (])

Relational operator 'follows or equal to' (]=)

Relational operator 'collates after' (]])

Relational operator 'collates after or equal to'

Logical operator 'and' (&)

Logical operator 'or' (!)

Logical operator 'exclusive or' (!!)

Logical unary operator 'not' (')

Indirection operator (@)

The M[UMPS] programming language knows a number of 'operators'. Some operators are the familiar arithmetic ones while others operate on strings or compare values. In M[UMPS], the operators can be mixed in any order, but keep in mind that some operators imply a specific interpretation of their operands. The only order of precedence for binary operators in M[UMPS] is the strict left- to-right evaluation, and unary operators only apply in a right- to-left order. If that order of precedence needs to be overridden, parentheses can be used to indicate that a sub- expression has to be evaluated first.

Depending on where one went to school, different schemes for the order of computations were taught. The main different 'schools' that I am aware of are:

Central Europe |
USA and Great Britain | ||
---|---|---|---|

1. | Raising to a power | 1. | Raising to a power (including taking roots) |

2. | Multiplication | ||

3. | Division | ||

4. | Take root | 2. | Multiplication or division |

5. | Addition | ||

6. | Subtraction | 3. | Addition or subtraction |

So that the result of: `4/2*2` is equal to `1` in
The Netherlands (multiplication takes precedence over division),
but equal to `4` in England (multiplication and division
have no difference in precedence, so the left-to-right evaluation
prevails).

M[UMPS] evaluates strictly from left to right, so that
`1+1*2` yields `4` and not `3`.

When a different precedence is to be established, parentheses
should be used: the expressions `1+(1*2)` and
`1*2+1` will both yield `3`.

Assume that `K=34`; the expression
`"_11_22_33_"["_"_K_"_"` will evaluate as `"134_"`.
The order of evaluation is: first evaluate
`"_11_22_33_"["_"`, which yields `1` (*true*),
then the rest of the expression becomes: `1_K_"_"`, which
leads to the value `"134_"`.

If one wished to perform a check to verify that the value of
`K` is contained in a list, parentheses are required:

`"_11_22_33_"[("_"_K_"_")` will return a true-or-false
value (**bve**, **b**oolean **v**alued
**e**xpression), which is only *true* when `K` has
one of the values `11`, `22` or `33`.

Assume that `L=29` and `K=34`; the series of
commands

will result in the text

In this case, the order of evaluation is: first compare

The formula that was intended could be either

Introduced in the 1977 ANSI M[UMPS] language standard.

Reference | Value | |
---|---|---|

1+1 |
2 | |

2+2 |
4 | |

(-3)+(-4) |
-7 |

Unary usage

Reference | Value | |
---|---|---|

+1 |
1 |

Forced numeric interpretation

Reference | Value | |
---|---|---|

+"27 apples" |
27 |

Resolve multiple leading signs

Reference | Value | |
---|---|---|

+++---+--+3 |
-3 |

Force numeric interpretation

Reference | Value | |
---|---|---|

"2 apples"+"3 oranges" |
5 |

Introduced in the 1977 ANSI M[UMPS] language standard.

Reference | Value | |
---|---|---|

3-1 |
2 | |

7-2 |
5 | |

2-7 |
-5 | |

(-3)-(-4) |
1 |

Unary usage

Reference | Value | |
---|---|---|

-1 |
-1 |

Resolve multiple leading signs

Reference | Value | |
---|---|---|

+++---+--+3 |
-3 |

Force numeric interpretation

Reference | Value | |
---|---|---|

"5 apples"-"3 oranges" |
2 |

Introduced in the 1977 ANSI M[UMPS] language standard.

Reference | Value | |
---|---|---|

3*3 |
9 | |

7.5*2 |
15 | |

-2.5*2.5 |
-6.25 | |

2.5*-2.5 |
-6.25 | |

(-3)*(-4) |
12 |

Force numeric interpretation

Reference | Value | |
---|---|---|

"5 apples"*"3 oranges" |
15 |

Introduced in the 1977 ANSI M[UMPS] language standard.

Reference | Value | |
---|---|---|

9/3 |
3 | |

5/2 |
2.5 | |

5/-2 |
-2.5 | |

-5/2 |
-2.5 |

No leading zero in canonic representation of numbers between -1 and +1:

Reference | Value | |
---|---|---|

1/2 |
.5 | |

-1/2 |
-.5 |

The number of digits is implementation-specific; 1977 ANSI standard guarantees 12 digits

Reference | Value | |
---|---|---|

1/2 |
.5 | |

1/3 |
.333333333333 | |

1/128 |
.0078125 |

Definitely not equal to 1:

Reference | Value | |
---|---|---|

1/3*3 |
.999999999999 |

Force numeric interpretation

Reference | Value | |
---|---|---|

"15 apples"/"3 oranges" |
5 |

In 1995 standard:

The 1995 standard guarantees 15 digits

Reference | Value | |
---|---|---|

1/3 |
.333333333333333 |

Added in the 1995 ANSI M[UMPS] language standard:

Reference | Value | |
---|---|---|

X/0 |
Error (M9) |

Introduced in the 1977 ANSI M[UMPS] language standard.

Reference | Value | |
---|---|---|

9\3 |
3 | |

5\2 |
2 | |

-5\2 |
-2 | |

1\2 |
0 | |

-1\2 |
0 |

Definitely not equal to 1

Reference | Value | |
---|---|---|

1\3*3 |
0 |

Added in the 1995 ANSI M[UMPS] language standard:

Reference | Value | |
---|---|---|

X\0 |
Error (M9) |

Introduced in the 1977 ANSI M[UMPS] language standard.

This is probably the most mis-understood operator (or function) in many programming languages. FORTRAN and C have 'remainder' operators, Ada and M[UMPS] have a true 'modulo' operator. These two are not the same (although the result is identical when both operands are positive).

The definition of *remainder* depends on *where you went
to school*. If you learned math in Europe, you will have a
radically different opinion about the sign of a remainder than if
you went to school in the USA (when either or both of the
operands are negative, that is, when both operands are positive,
everyone agrees).

Both 'schools' are correct, and, as long as you follow your
definition consistently, you will have no problems.

In M[UMPS], however, there is no *remainder* operator. There
is the *modulo* instead.

The definition of *modulo* is based on Abelian group theory,
and the true mathematical definition is little known outside of
mathematical graduate schools (see for instance Donald Knuth's
** The Art of Computer Programming**, Volume 1, page 23
and further), but the following explanation is close enough for
practical purposes:

The mathematical definition of Modulo maps a potentially
infinitely large set of numbers onto a (usually finite) subset.
The subset is repeated cyclically to map every number from the
original set onto a member of the subset.

`number#sub` means: map the number on the left-hand side
onto the subset ` [0,sub)` (0, zero inclusive, sub
exclusive). If sub is negative, this should be

For example,

number | -9 | -8 | -7 | -6 | -5 | -4 | -3 | -2 | -1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |

number#(5) | 1 | 2 | 3 | 4 | 0 | 1 | 2 | 3 | 4 | 0 | 1 | 2 | 3 | 4 | 0 | 1 | 2 | 3 | 4 |

number#(-5) | -4 | -3 | -2 | -1 | 0 | -4 | -3 | -2 | -1 | 0 | -4 | -3 | -2 | -1 | 0 | -4 | -3 | -2 | -1 |

Added in the 1995 ANSI M[UMPS] language standard:

Reference | Value | |
---|---|---|

X#0 |
Error (M9) |

Introduced in the 1995 ANSI M[UMPS] language standard.

Reference | Value | |
---|---|---|

2**5 |
32 | |

2**3 |
8 | |

-2**3 |
-8 | |

16**.25 |
2 | |

-32**(1/5) |
-2 | |

-2**.5 |
not specified | |

-27**(1/3) |
not specified | |

3**2 |
9 | |

2**3**4 |
4096 | |

4**0.5 |
2 | |

4**(-2) |
.0625 | |

27**(1/3) |
3 (if 1/3 is that exact...) | |

2.5**2 |
6.25 | |

-1**3 |
-1 | |

-8**(1/3) |
-2 or error |

Square root:

Reference | Value | |
---|---|---|

4**.5 |
2 | |

2**.5 |
1.4142... |

The standard does not (yet) define any behavior in the case of imaginary or complex results

Reference | Value | |
---|---|---|

-1**.5 |
error or "0%1" |

This should always work

Reference | Value | |
---|---|---|

32**.2 |
2 |

But this depends on the precision that the implementation offers internally

Reference | Value | |
---|---|---|

-32**.2 |
-2 (or error) |

Introduced in the 1977 ANSI M[UMPS] language standard.

Reference | Value | |
---|---|---|

9_3 |
93 |

No separator remains

Reference | Value | |
---|---|---|

"First"_"Second" |
FirstSecond |

Unless embedded in either operand

Reference | Value | |
---|---|---|

"First"_" Second" |
First Second |

Or explicitly specified

Reference | Value | |
---|---|---|

"First"_" "_"Second" |
First Second |

Introduced in the 1977 ANSI M[UMPS] language standard.

**SET** X=1

**SET** X=A+B*23_" apples"

**SET** X=A=B

Note: the first "=" sign is an assignment operator, the second
"=" sign is a relational operator.

Introduced in the 1977 ANSI M[UMPS] language standard.

**IF** A=123 **SET** X=1

**SET** Y=**$SELECT**(B=938457:124,1:23746)

Approved for inclusion in a future ANSI M[UMPS] language standard.

This operator only returns a true value if both operands are pointers to objects, and both pointer identify the same instance of the same object.

**IF** docA==docB **SET** X=1

**SET** Y=**$SELECT**(graph1==graph4:124,1:23746)

Introduced in the 1977 ANSI M[UMPS] language standard.

**IF** A>123 **SET** X=1

**SET** Y=**$SELECT**(B>938457:124,1:23746)

Introduced in the 1977 ANSI M[UMPS] language standard.

**IF** A<123 **SET** X=1

**SET** Y=**$SELECT**(B<938457:124,1:23746)

Approved for inclusion in a future ANSI M[UMPS] language standard.

**IF** A<=123 **SET** X=1

**SET** Y=**$SELECT**(B<=938457:124,1:23746)

Approved for inclusion in a future ANSI M[UMPS] language standard.

**IF** A>=123 **SET** X=1

**SET** Y=**$SELECT**(B>=938457:124,1:23746)

Introduced in the 1977 ANSI M[UMPS] language standard.

The pattern-codes to be used in pattern-matching are:

` A`: the 26 upper and 26 lower-case alphabetic
characters

Modified for internationalization in the 1995 ANSI M[UMPS]
language standard:

` A`: upper and lower-case characters

1 (

1 (

1 (

Addition in the 1995 ANSI M[UMPS] language standard

In order to support the Japanese character sets, two new pattern identifiers are added:

for Kanji
(**$CHAR**(161) - **$CHAR**(223))

for JIS
(**$CHAR**(8481) - **$CHAR**(32382))

Additions in the 1995 ANSI M[UMPS] language standard (and correction in a future) ANSI M[UMPS] language standard:

The concept of 'alternation' is introduced. An 'alternation' is a list of possible patterns that each are a valid match for a pattern.

is equivalent to

`X?2N1"-"1(3N1"-"1N,1N1":"4N)`

would match `"12-345-6"` and `"12-3:4567"`.

`X?.1(1"("3N1")".1(1"-",1"_"))3N.1(1"-",1"_")4N`

would match any of:

555-1212

555_1212

(000)5551212

(000)555-1212

(000)555_1212

(000)-5551212

(000)-555-1212

(000)-555_1212

(000)_5551212

(000)_555-1212

(000)_555_1212

In order to support the character ISO-8859-1/USA, a new pattern identifier is added:

` I`: "International" characters (any non-ASCII characters
in ISO-8859-1/USA).

It is made possible to exclude certain patterns:

1 (

1 (

The concept of "ranges" is introduced. It is made possible to specify that a pattern is matched when one of a set of specified characters occurs:

Reference | Value | |
---|---|---|

"word"?.["aeiouAEIOU"] |
0 (false) | |

"ff3a"?.["a":"f"]["A":"F"]N |
1 (true) |

The first pattern would be matched by strings that contain only vowels; the second pattern would be matched by purely hexadecimal numbers.

As a new feature, it has been made possible to extract the substring that matches a specific sub-pattern from the string that is being "matched". When using this new feature, the name of the variable that is to receive the string-segment in question is named between parentheses following the pattern-atom that it is intended to match.

Assume that the value of local variable `X` matches the
following pattern: `X?4N1","1.3N`, i.e. 4 numeric digits, one comma
and then between one and 3 more digits. The code segment:

**IF** '(X?4N(ITEM)1","1.3N(QUANT(ITEM)) **DO** ...

would cause the values of local variables `ITEM` and
`QUANT(ITEM)` to be set to `ITEM= $EXTRACT(X,1,4)`
(the part that matches

Note that the assignment occurs as the pattern is being
matched (strict left-to-right), so that the value of local
variable `ITEM` is well defined when the pattern matching processor
will attempt to assign a value to `QUANT(ITEM)`.

Introduced in the 1977 ANSI M[UMPS] language standard.

Assume that `DIAGNOSIS="flu-patient"`.

Reference | Value | |
---|---|---|

DIAGNOSIS["pat" |
1 (true) | |

DIAGNOSIS["lu" |
1 (true) | |

DIAGNOSE["flute" |
0 (false) | |

DIAGNOSE["pantie" |
0 (false) |

Note that all characters of both `"pantie"` and
`"flute"` do occur in `"flu-patient"`; those of
`"flute"` even occur in the same order. The contains
operator insists not only that the symbols in the substring occur
in that order, but also as a 'solid' substring.

Introduced in the 1977 ANSI M[UMPS] language standard.

Assume that `TXT1="ABC"` and `TXT2="ABD"`.

Reference | Value | |
---|---|---|

TXT2]TXT1 |
1 (true) | |

"ABCD"]TXT1 |
1 (true) |

Note that the lexicographical order of the texts `"1"`,
`"2"` and `"10"` is: `"1"`, `"10"`,
`"2"`, i.e.:

Reference | Value | |
---|---|---|

10]1 |
1 (true) | |

2]1 |
1 (true) | |

10]2 |
0 (false) |

Approved for inclusion in a future ANSI M[UMPS] language standard.

Reference | Value | |
---|---|---|

10]=10 |
1 (true) | |

2]=1 |
1 (true) | |

10]=2 |
0 (false) | |

10]=1 |
1 (true) | |

2]=2 |
1 (true)) |

Introduced in the 1995 ANSI M[UMPS] language standard.

Assume that `TXT1="ABC"` and `TXT2="ABD"`.

Reference | Value | |
---|---|---|

TXT2]]TXT1 |
1 (true) | |

"ABCD"]]TXT1 |
1 (true) | |

"ABCD"]]1 |
1 (true) | |

TXT1]]2 |
1 (true) | |

10]]1 |
1 (true) | |

2]]1 |
1 (true) | |

10]]2 |
1 (true) |

A future ANSI M[UMPS] language standard introduces an override
mechanism for collating purposes. See the library functions
`$%COLLATE^CHARACTER` and
`$%COMPARE^CHARACTER`
for more information
about the override options.

Approved for inclusion in a future ANSI M[UMPS] language standard.

Reference | Value | |
---|---|---|

TXT2]]=TXT1 |
1 (true) | |

"ABCD"]]=TXT1 |
1 (true) | |

"ABCD"]]=1 |
1 (true) | |

TXT1]]=2 |
1 (true) | |

10]]=10 |
1 (true) | |

2]]=2 |
1 (true) | |

10]]=2 |
1 (true) |

A future ANSI M[UMPS] language standard introduces an override
mechanism for collating purposes. See the library functions
`$%COLLATE^CHARACTER` and
`$%COMPARE^CHARACTER`
for more information
about the override options.

Introduced in the 1977 ANSI M[UMPS] language standard.

Reference | Value | |
---|---|---|

0&0 |
0 (false) | |

0&1 |
0 (false) | |

1&0 |
0 (false) | |

1&1 |
1 (true) |

Reference | Value | |
---|---|---|

"5 apples"&"3 pears" |
1 (true) | |

1&"3 pears" |
1 (true) | |

"5 apples"&"trees" |
0 (false) | |

"0.125"&1 |
1 (true) | |

"5 apples"&0 |
0 (false) | |

"apples"&0 |
0 (false) |

Careful with:

Reference | Value | |
---|---|---|

A>3&B<6 |
1 (always true) |

(`A>3&B` is `0` or `1`, both
`0` and `1` are `<6`)

The value of `(A>3)&(B<6)` depends on the values
of `A` and `B`

Introduced in the 1977 ANSI M[UMPS] language standard.

Reference | Value | |
---|---|---|

0!0 |
0 (false) | |

0!1 |
1 (true) | |

1!0 |
1 (true) | |

1!1 |
1 (true) |

Reference | Value | |
---|---|---|

"5 apples"!"3 pears" |
1 (true) | |

1!"3 pears" |
1 (true) | |

"5 apples"!"trees" |
1 (true) | |

"0.125"!1 |
1 (true) | |

"5 apples"!0 |
1 (true) | |

"apples"!0 |
0 (false) |

Careful with:

Reference | Value | |
---|---|---|

A>3!B<6 |
1 (always true) |

(`A>3!B` is `0` or `1`, both `0`
and `1` are `<6`)

The value of `(A>3)!(B<6)` depends on the values of
`A` and `B`

Approved for inclusion in a future ANSI M[UMPS] language standard.

Reference | Value | |
---|---|---|

0!!0 |
0 (false) | |

0!!1 |
1 (true) | |

1!!0 |
1 (true) | |

1!!1 |
0 (false) |

Reference | Value | |
---|---|---|

"5 apples"!!"3 pears" |
0 (false) | |

1!!"3 pears" |
0 (false) | |

"5 apples"!!"trees" |
1 (true) | |

"0.125"!!1 |
0 (false) | |

"5 apples"!!0 |
1 (true) | |

"apples"!!0 |
0 (false) |

Careful with:

Reference | Value | |
---|---|---|

A>3!!B<6 |
1 (always true) |

(`A>3!!B` is `0` or `1`, both `0`
and `1` are `<6`)

The value of `(A>3)!!(B<6)` depends on the values of
`A` and `B`

Introduced in the 1977 ANSI M[UMPS] language standard.

Reference | Value | |
---|---|---|

'12345 |
0 (false) | |

'0 |
1 (true) | |

'"Apples" |
1 (true) |

The logical or Boolean value of `X`:

Reference | Value | |
---|---|---|

''X |
0 or 1 |

The exclusive or of two values:

Reference | Value | |
---|---|---|

'X'='Y |
X xor Y |

This operator can also be used to modify the meaning of other operators:

`'=` is not equal to

`'>` is not greater than, i.e. is less than or equal to

`'<` is not less than, i.e. is greater than or equal to

`'?` does not match the pattern

`'[` does not contain

`']` does not follow

`'&` not and

`'!` not or

Added in 1995:

`']]` does not collate after

To be added in a future standard:

`'<=` is not less than or equal to, i.e. is greater than

`'>=` is not greater than or equal to, i.e. is less than

`']=` does not follow and is not equal to

`']]=` does not collate after and is not equal to

`'!!` not exclusive or

Introduced in the 1977 ANSI M[UMPS] language standard.

Three types of indirection:

Name indirection

**SET** X="ABC"

IF 123+@X=456

Argument indirection

**SET** SPACE="!!!",PAGE="#"

**WRITE** @**$SELECT**(ENOUGH:SPACE,1:PAGE)

Pattern indirection

**SET** CODE="3U"_**$SELECT**(SPECIAL:"2N",1:"")_"5L"

**IF** X?@CODE

Addition in 1984 ANSI M[UMPS] language standard.

Fourth type of indirection, subscripted reference indirection:

**SET** ARRAY="PRICES"

**SET** PRICE=(100+SALESTAX/100)*@ARRAY@(1,2,3)

**SET** ARRAY="^CUSTOMER(123,45)"

**SET** TOTAL=TOTAL+@ARRAY@(2,3,4)

Fifth type of indirection, "generic" indirection.

This new type of indirection involves a "catch-all" recovery after all other types of indirection have been attempted by a M[UMPS] language processor. When code is encountered that uses indirection, and none of the above forms of indirection leads to a valid interpretation of the code, the indirection operator and the expression on which it operates are to be replaced by the value of the expression in question, and then the line of code is to be re-evaluated. This may lead to some surprising possibilities:

**SET** X1="Y"

**SET** X2="Z="

**SET** X3="SecretAccnt=1E9,N"

**SET** X4="N=1 HALT"

**SET** Y="Example"

**SET** Y1="Example1"

**SET** Z1="Program"

**SET** Z2="TAG^Program"

**SET** Z3="(1,2,3)"

**SET** Z4=",2,3,4)"

With these values:

**SET** @X1="HELLO"

will be executed as: **SET** Y="HELLO"

**SET** @X2"HELLO"

will be executed as: **SET** Z="HELLO"

**SET** @X3="HELLO"

will be executed as: **SET** SecretAccnt=1E9,N="HELLO"

**SET** @(X1)1="Example"

will be executed as: **SET** Y1="Example1"

**DO** ^@(Z1)(1,2,3)

will be executed as: **DO** ^Program(1,2,3)

**DO** @(Z2)(1,2,3)

will be executed as: **DO** TAG^Program(1,2,3)

**DO** @(Z2)@Z3

will be executed as: **DO** TAG^Program(1,2,3)

**DO** @(Z2)("BLUE"@Z4

will be executed as: **DO** TAG^Program("BLUE",2,3,4)

This document is © Ed de Moel, 1995-2005.

It is part of a book by Ed de Moel that is published under
the title "M[UMPS] by Example" (ISBN 0-918118-42-5).

Printed copies of the book are no longer available.

This document describes the various operators that are defined in the M[UMPS] language standard (ANSI X11.1, ISO 11756).

*The information in this document is NOT authoritative and subject to
be modified at any moment.
Please consult the appropriate (draft) language standard for an authoritative
definition.*

*In this document, information is included that will
appear in
future standards.
The MDC cannot guarantee that these 'next'
standards will indeed appear.*