Skip to main content

Operators

Motoko provides various operators for working with numbers, text, and boolean values. They can be categorized as follows:

CategoryDescriptionExamples
ArithmeticMath operations on numbers+, -, *, /, %, **
BitwiseOperations on individual bits&, |, ^, <<, >>, <<>, <>>
TextText concatenation#
LogicalLogical/boolean operationsnot, and, or
OrderedComparing values==, !=, <, >

Bitwise operators can only be used with bounded types, such as Int8, Nat8.

Short-circuit evaluation

In Motoko, the logical operators and and or use short-circuit evaluation:

  • and evaluates the second operand only if the first is true.
  • or evaluates the second operand only if the first is false.

This avoids unnecessary computation and potential side effects.

Short circuit and

If the first operand is false, the second is not evaluated.

let x = false;

if (x and someOtherExp) {
Debug.print("Unreachable code executed! something is wrong!"); // This should never be printed.
};

Short circuit or

If the first operand is true, the second is not evaluated.

let y = true;

if (y or someOtherExp) {
Debug.print("This will be printed");
};

Unary operators

OperatorDescription
-Numeric negation
+Numeric identity
^Bitwise negation

Relational operators

Relational operators compare two values and return true or false.

OperatorDescriptionExample
==Equalsa == b
!=Not equalsa != b
<Less thana < b
>Greater thana > b
<=Less than or equala <= b
>=Greater than or equala >= b

Numeric binary operators

Binary operators combine two numbers to produce a result.

OperatorDescriptionExample
+Additiona + b
-Subtractiona - b
*Multiplicationa * b
/Division (integer division)a / b
%Modulus (remainder)a % b
**Exponentiationa ** b

Division (/) on integers truncates decimals. For floating-point division, use Float.fromInt():

let result = Float.fromInt(10) / Float.fromInt(3);

Bitwise operators

Bitwise operators manipulate numbers at the binary level.

OperatorDescriptionExample
&Bitwise ANDa & b
|Bitwise ORa | b
^Bitwise XORa ^ b
<<Shift lefta << b
>>Shift right (must be preceded by a whitespace)a >> b
<<>Rotate left (circular shift)a <<> b
<>Rotate right (circular shift)a <> b

Bitwise operators can only be used with bounded types. eg: Int8, Nat8.

Wrapping operators

Bounded integers trap on overflow, but wrapping versions allow overflow behavior.

OperatorDescriptionExample
+%Addition with wrap-arounda +% b
-%Subtraction with wrap-arounda -% b
*%Multiplication with wrap-arounda *% b
**%Exponentiation with wrap-arounda **% b

Text operators

OperatorDescriptionExample
#Concatenates two Text valuesa # b

Assignment operators

Assignment operators modify variables in place. Both mutable variables declared with var and elements of mutable arrays can be assigned new values.

OperatorDescriptionExamples
:=Assign a valuea := b
+=Add and assigna += b
-=Subtract and assigna -= b
*=Multiply and assigna *= b
/=Divide and assigna /= b
#=Concatenate and assign (for Text)a #= b

For example:

var done = false; done := true;

let a = [var 1, 2];
a[0] += a[1];

Operator precedence

Operators follow precedence rules, meaning that, in the absence of explicit parentheses, some operators are evaluated before others.

  1. Unary operators (-, !, ^)
  2. Exponentiation (**, **%)
  3. Multiplication & division (*, /, %, *%)
  4. Addition & subtraction (+, -, +%, -%)
  5. Bitwise operators (&, |, ^)
  6. Comparison operators (==, !=, <, >, <=, >=)
  7. Assignment operators (:=, +=, -=, etc.)

For example:

let result = 10 + 5 * 2; // result = 20

Use parentheses to enforce a different order.

let result = (10 + 5) * 2; // result = 30

Pipes

Pipes (|>) chain together function calls in a readable way. Instead of nesting function calls, pipes pass the result of one expression as an argument to the next function. The value of the left side of the pipe is referenced on the right side using an underscore (_).

func double(n : Int) : Int { n * 2 };
func increment(n : Int) : Int { n + 1 };

let result = 5 |> double(_) |> increment(_); // (5 * 2) + 1 = 11
Logo