Arithmetic

This page describes the arithmetic expressions available in FlowScript. All of the information on this page applies to script steps as well as templates.

Like in most languages, FlowScript defines an order of evaluation for operators. For example, the multiplication and division operators are evaluated before the addition and subtraction operators, as expected: the expression 1 + 2 * 3 should be read as equivalent to 1 + (2 * 3). Use parantheses to change the order of evaluation. For a full list of operator precedences, refer to the listing at the bottom of this page.

Comparison operators

Equals

Syntax: a = b or a == b

The equals operator expresses a boolean value indicating whether its two operands are equal. The equals operator can be written either using a single or a double equals sign (=).

The equals operator can be used with any type of value, but both sides must have the same type. Equality is structural: two records, for example, are considered equal of their members have the same labels and those members have equal values. (Some programming languages have a concept of reference equality, but this does not exist in FlowScript.)

For two sequences to be equal, they must have the same length, and the element at each position in the left-hand side sequent must be equal to the element at the corresponding position on the other side.

1 == 2 // false

[1, 2] == [1, 2] // true

{email: "info@novacura.com"} == {email: "info@novacura.com"} // true

Although two function values can be equated, they are never considered the same.

Not equals

Syntax: a != b or a <> b

The not equals operator is the inverse of the equals operator: it expresses a boolean value indicating whether the two operands are different. All the other rules of the equals operator apply.

1 != 2 // true

[1, 2] != [1, 2] // false

{email: "info@novacura.com"} != {email: "info@novacura.com"} // false

Ordering operators

Syntax: a > b, a < b, a >= b, a <= b

This group of operators express a boolean value indicating an ordering relation between the two operands. The expression a > b is true if a is greater than b; a < b is true if a is less than b; a >=b is true if a is greater than or equal to b, and a <= b is true if a is less than or equal to b.

The relational operators are defined for values of types number, boolean, text and datetime, including their nullable counterparts.

1 < 2 // true
2 < 1 // false

"abc" > "bcd" // false
"abc" < "bcd" // true

date("2024-02-01") > date("1982-11-21") // true
date("1982-11-21") < date("2024-02-01") // true

true > false // true
false <= false // true

Numeric operators

Addition

The main purpose of the plus operator is to express the sum of two numbers. If the left-side operand is a datetime, the value is instead that datetime offset by a number of days specified by the right-side operand.

// Addition of numbers: x has type number and value 3.
let x = 1 + 2; 

// Addition of datetime and number:
// The addition operator offsets the date on the left-hand side
// by some number of days.
// The variable y will have a datetime value representing
// tomorrow at the current time of day.
let y = now() + 1; 

Subtraction

The minus operator calculates the difference between two numbers. If the left-side operand is a datetime, the value is instead that datetime offset backwards in time by the number of days specified by the right-side operand.

// Subtraction of numbers: x has type number and value 4.
let x = 8 - 4; 

// Subtraction of datetime and number:
// The variable y will have a datetime value representing
// yesterday at the current time of day.
let y = now() + 1; 

Unary minus

The minus operator can also be used in the prefix position on a single expression, expressing a value multiplied by -1.

// Example: negate the variable x
let x = 3;
return -x; // returns -3

Multiplication

The asterisk (*) operator expresses the product of two numbers.

// Example: Return the number six, expressed as the product of two and three.

let x = 2;
return x * 3;

Division

The slash (/) operator expresses the factor of two numbers. Note that the application will fail at runtime if the right-hand-side evaluates to zero.

// Return the number five, expressed as ten divided by two.
return 10 / 2;

Modulo

The mod operator expresses the remainder of the integer division of two numbers. Is is commonly used to check if a number is odd or even (based on the fact that an even number can be divided by two without remainder).

// Example 1: calculcate how many are left is we divide 22 apples
// into groups of exactly six each.
let remainingApples = 22 mod 6; // remainingApples == 4

// Example 2: create a pair of functions, isEven and isOdd,
// defined in terms of the mod operator.
function isEven(n: number): boolean {
    return n mod 2 == 0;
}

function isOdd(n: number): boolean {
    return n mod 2 != 0;
}

Boolean operators

and

The and operator expresses a boolean value indicating whether both its operands are true.

let isRaining = false;
let isOutside = true;

let getsWet = isRaining and isOutside; // getsWet == false

Note that the and operator binds tighter than the or operator: it has higher precedence and is evaluated first, much like multiplication is evaluated before addition. An expression A or C and B should thus be read as equivalent to A or (C and B).

The and operator is short-circuiting: the left-hand side is evaluated first, and if it is found to be false, the right-hand side is not evaluated at all.

or

The or operator expresses a boolean value indicating whether either of its operands are true.

let isRaining = true;
let isSnowing = false;

let precipitation = isRaining or isSnowing; // precipitation == true

The or operator binds less tightly than the and operator and is evaluated after it, no matter the order in which they are written. An expression A or C and B should thus be read as equivalent to A or (C and B).

The or operator is short-circuiting: the left-hand side is evaluated first, and if it is found to be true, the right-hand side is not evaluated at all.

not

The unary not operator negates its boolean operand so that true becomes false and false becomes true.

let sunny = true;
let windy = false;
let fairWeather = sunny and not windy; // fairWeather == true

Miscellaneous operators

Concat (&)

The concatenation operator can be used to concatenate two text values, or to concatenate or extend sequences.

// Example 1: concatenate two strings
let greeting = "hello" & "world"; // greeting == "helloworld"

// Example 2: concatenate two sequences
let result = [1, 2] & [3, 4]; // result == [1, 2, 3, 4]

It is also possible to use the concatenation operator on two records, in which case the result becomes a sequence containing the two records.

let user1 = {name: "Annie", email: "annie@example.com"};
let user2 = {name: "Aisha", email: "aisha@example.com"};

return user1 & user2; // equivalent to [user1, user2]

Furthermore, you can use the operator to add single records to the beginning or end of a sequence of records:

let users = [
    {name: "Adah", email: "adah@example.com"},
    {name: "Mary", email: "mary@example.com"}
];

let result = users & {name: "Fatima", email: "fatima@example.com"};

Star (*)

The unary star prefix operator turns a value of any type into a sequence.

let result = *1; // equivalent to [1]
Advanced: Operator precedence

The following listing shows the order of precedence of all operators described in this document. Operators with a lower number have higher precedence: they are evaluated before the operators with a higher.

  1. Unary operators: not and unary minus

  2. Multiplicative operators: multiplication and division

  3. Additive operators: addition and subtraction

  4. Ordering operators: greater than, less than, greater than or equal, less than or equal

  5. Equational operators: equals and not equals

  6. Conjunction: the and operator

  7. Disjunction: the or operator

Last updated