Beginner

Operators in REXX

Learn arithmetic, comparison, logical, and concatenation operators in REXX, plus operator precedence, with Docker-ready Regina REXX examples

Operators are the verbs of arithmetic and logic—they combine values into expressions that produce new values. REXX, an imperative and procedural language with dynamic, typeless data, treats every value as a character string. That single design choice shapes how its operators behave: numbers are just strings that happen to look like numbers, and REXX decides at evaluation time whether to do arithmetic or text manipulation.

Because of its mainframe heritage and decimal-arithmetic philosophy, REXX has a few operators you won’t see elsewhere. Division (/) always produces a decimal result, while % and // give you integer division and remainder separately. Comparison comes in two flavors: a forgiving “normal” comparison that ignores leading and trailing blanks, and a strict comparison (==) that demands an exact character match. And concatenation has three forms—explicit, blank, and abuttal—reflecting REXX’s string-first worldview.

This tutorial walks through each operator family with runnable examples. By the end you’ll understand REXX arithmetic, how true and false are represented (as 1 and 0), the difference between = and ==, the three ways to join strings, and how precedence decides evaluation order.

Arithmetic Operators

REXX provides the familiar arithmetic operators plus a few that reflect its decimal-math design. Note that / always yields a decimal result, while % (integer division) and // (remainder) handle integer-style math.

Create a file named arithmetic.rexx:

1
2
3
4
5
6
7
8
9
/* Arithmetic operators in REXX */
say 7 + 3      /* Addition:        10   */
say 7 - 3      /* Subtraction:      4   */
say 7 * 3      /* Multiplication:  21   */
say 7 / 2      /* Division:         3.5 */
say 7 % 2      /* Integer divide:   3   */
say 7 // 2     /* Remainder:        1   */
say 2 ** 10    /* Power:         1024   */
say -5 + 2     /* Prefix minus:    -3   */

Unlike many languages where 7 / 2 truncates to 3, REXX returns the exact decimal 3.5. When you actually want integer division, use %; when you want the leftover, use //. The ** operator raises a number to a power.

Comparison Operators

Comparison operators return 1 for true and 0 for false—there is no separate boolean type, just those two strings. REXX offers a “normal” comparison (=, \=, <, >, <=, >=) that ignores leading and trailing blanks, and a “strict” comparison (==, \==) that requires an exact character match.

Create a file named comparison.rexx:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
/* Comparison operators in REXX (1 = true, 0 = false) */
say 5 = 5            /* Equal:             1 */
say 5 \= 4           /* Not equal:         1 */
say 5 > 4            /* Greater than:      1 */
say 5 < 4            /* Less than:         0 */
say 5 >= 5           /* Greater or equal:  1 */
say 4 <= 5           /* Less or equal:     1 */
say "abc" == "abc"   /* Strict equal:      1 */
say "abc" == "abc "  /* Strict + trailing: 0 */
say "abc" = "abc "   /* Normal (padded):   1 */

The last two lines show the key distinction: == treats "abc" and "abc " as different because the trailing blank matters, while normal = pads the shorter string with blanks before comparing, so it reports them as equal. The \ character is REXX’s “not” symbol, so \= means “not equal.”

Logical Operators

Logical operators work on the boolean values 1 and 0. REXX uses & for AND, | for OR, && for exclusive OR (XOR), and the prefix \ for NOT.

Create a file named logical.rexx:

1
2
3
4
5
6
7
8
9
/* Logical operators in REXX */
say 1 & 1    /* AND: both true   -> 1 */
say 1 & 0    /* AND: one false   -> 0 */
say 1 | 0    /* OR:  one true    -> 1 */
say 0 | 0    /* OR:  both false  -> 0 */
say 1 && 0   /* XOR: differ      -> 1 */
say 1 && 1   /* XOR: same        -> 0 */
say \1       /* NOT: 1 negated   -> 0 */
say \0       /* NOT: 0 negated   -> 1 */

The double-ampersand && is the exclusive-or operator: it yields 1 only when its two operands differ. The prefix \ flips a single boolean value.

Concatenation Operators

Because strings are REXX’s fundamental type, joining them is central to the language. There are three ways to concatenate, giving you precise control over spacing.

Create a file named concatenation.rexx:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
/* Concatenation operators in REXX */
first = "Hello"
last  = "World"

say first || last      /* Abuttal (||):  HelloWorld   */
say first last         /* Blank concat:  Hello World  */
say first", "last"!"   /* Mixed abuttal: Hello, World! */

count = 3
say "Item" count       /* Blank + number: Item 3 */
say "ID" || count      /* No space:       ID3    */

The || operator joins values with no space between them. Separating two terms with a blank performs blank concatenation, inserting exactly one space. Placing terms directly adjacent (as in first", "last"!") is abuttal concatenation, which joins them with no added space—handy for building strings out of literals and variables.

Operator Precedence

When an expression mixes operators, REXX evaluates them according to precedence. Prefix operators (\, unary -, unary +) bind tightest, followed by **, then * / % //, then + -, then concatenation, then comparison, then &, and finally | &&. Operators of equal precedence evaluate left to right. Parentheses override the default order.

Create a file named precedence.rexx:

1
2
3
4
5
6
/* Operator precedence in REXX */
say 2 + 3 * 4      /* 14: * before +          */
say (2 + 3) * 4    /* 20: parentheses first   */
say 10 - 2 - 3     /*  5: left to right       */
say 2 * 3 ** 2     /* 18: ** before *         */
say \0 & 1         /*  1: prefix \ before &   */

In 2 * 3 ** 2, the power runs first (3 ** 2 is 9), then the multiplication (2 * 9 is 18). In \0 & 1, the prefix \ negates 0 to 1 before the & runs, giving 1. When in doubt, add parentheses—they make intent explicit and override every precedence rule.

Running with Docker

1
2
3
4
5
6
7
8
9
# Pull the Regina REXX image
docker pull rzuckerm/rexx:3.6-5.00-1

# Run each example
docker run --rm -v $(pwd):/app -w /app rzuckerm/rexx:3.6-5.00-1 rexx /app/arithmetic.rexx
docker run --rm -v $(pwd):/app -w /app rzuckerm/rexx:3.6-5.00-1 rexx /app/comparison.rexx
docker run --rm -v $(pwd):/app -w /app rzuckerm/rexx:3.6-5.00-1 rexx /app/logical.rexx
docker run --rm -v $(pwd):/app -w /app rzuckerm/rexx:3.6-5.00-1 rexx /app/concatenation.rexx
docker run --rm -v $(pwd):/app -w /app rzuckerm/rexx:3.6-5.00-1 rexx /app/precedence.rexx

Expected Output

Running arithmetic.rexx:

10
4
21
3.5
3
1
1024
-3

Running comparison.rexx:

1
1
1
0
1
1
1
0
1

Running logical.rexx:

1
0
1
0
1
0
0
1

Running concatenation.rexx:

HelloWorld
Hello World
Hello, World!
Item 3
ID3

Running precedence.rexx:

14
20
5
18
1

Key Concepts

  • Division is decimal/ always produces an exact decimal result (7 / 2 is 3.5); use % for integer division and // for the remainder.
  • Power uses **2 ** 10 evaluates to 1024, and ** binds tighter than *, /, %, and //.
  • Booleans are 1 and 0 — comparison and logical operators return the strings 1 (true) and 0 (false); there is no separate boolean type.
  • Normal vs. strict comparison= ignores leading/trailing blanks (padding the shorter operand), while == demands an exact character-for-character match.
  • \ is “not” — REXX uses backslash for negation: \= means “not equal” and prefix \ flips a boolean value.
  • && is exclusive-or& is AND, | is OR, and && is XOR (true only when operands differ).
  • Three ways to concatenate|| joins with no space, a blank between terms inserts one space, and adjacency (abuttal) joins literals and variables with no added space.
  • Precedence, then left-to-right — prefix operators bind tightest, followed by **, multiplicative, additive, concatenation, comparison, then logical operators; use parentheses to make order explicit.

Running Today

All examples can be run using Docker:

docker pull rzuckerm/rexx:3.6-5.00-1
Last updated:

Comments

Loading comments...

Leave a Comment

2000 characters remaining