Operators in Nim
Learn arithmetic, comparison, logical, and bitwise operators in Nim, plus how to define your own custom operators.
Operators are the building blocks of expressions. In Nim, operators behave much like they do in Python or C, but with a few twists rooted in Nim’s static, strongly-typed nature. Because Nim is statically typed with type inference, the compiler decides which version of an operator to call based on the types of its operands — and you can define entirely new operators yourself.
Nim is a multi-paradigm language (procedural, object-oriented, functional, metaprogramming), so operators are not magic syntax: they are just procedures with symbolic names. This means 1 + 2 is sugar for `+`(1, 2), and you can overload or invent operators using the same proc keyword used for any other function.
In this tutorial you’ll see arithmetic, comparison, logical, bitwise, and assignment operators, learn how Nim handles integer vs. floating-point division, and finish by defining a custom operator.
Arithmetic, Division, and Modulo
Nim uses familiar infix arithmetic operators: +, -, *, /, plus div and mod for integer division and remainder. Note the important distinction: / always returns a float, while div performs integer division.
Create a file named arithmetic.nim:
| |
The ^ integer power operator lives in the std/math module and must be imported. Floating-point exponentiation uses pow from the same module.
Comparison and Logical Operators
Comparisons in Nim return a bool. The logical operators and, or, not, and xor are spelled as words (not && / ||) and short-circuit where appropriate.
Create a file named comparison.nim:
| |
Bitwise and Shift Operators
Because Nim targets systems programming, it offers a full set of bitwise operators. They are spelled with words to avoid confusion with logical operators: and, or, xor, not, shl, shr. The compiler picks the bitwise meaning when both operands are integers.
Create a file named bitwise.nim:
| |
Note: toBin lives in std/strutils and must be imported explicitly. It formats an integer as a binary string padded to the given width.
Assignment, Compound, and String Operators
Nim supports compound assignment (+=, -=, *=, /=) on mutable var bindings. Strings concatenate with &, and &= appends in place.
Create a file named assignment.nim:
| |
The $ prefix is Nim’s stringify operator — it converts any value with a defined $ proc to a string. It’s the operator behind echo.
Operator Precedence and Custom Operators
Nim’s precedence rules mostly mirror mathematics: unary operators bind tightest, then *, /, div, mod, then + and -, then comparisons, then and, then or. Use parentheses when in doubt.
Because operators are just procedures, you can define your own. Symbolic identifiers must be wrapped in backticks at the definition site.
Create a file named custom_op.nim:
| |
The name of a custom operator determines its precedence: operators ending in = (other than ==, <=, etc.) get the lowest precedence, and the first character of the operator name signals its precedence class (see the Nim manual for the full table).
Running with Docker
| |
Expected Output
Output from arithmetic.nim:
a + b = 22
a - b = 12
a * b = 85
a / b = 3.4
a div b = 3
a mod b = 2
2 ^ 10 = 1024
negated = 42
Output from comparison.nim:
x == y: false
x != y: true
x < y: true
x <= y: true
x > y: false
x >= y: false
inRange: true
outside: false
not inRange: false
true xor false: true
Output from bitwise.nim:
flags and mask = 0b1000
flags or mask = 0b1110
flags xor mask = 0b0110
not flags (8-bit) = 0b11110101
flags shl 2 = 40
flags shr 1 = 5
Output from assignment.nim:
counter = 9
Hello, Nim
Count: 9
Output from custom_op.nim:
2 ** 8 = 256
3 ** 4 = 81
2 + 3 * 4 = 14
(2 + 3) * 4 = 20
Key Concepts
- Operators are procedures.
a + bis shorthand for`+`(a, b), which means any operator can be overloaded or newly defined withproc. /vsdiv. The/operator always yields afloat; usedivfor integer division andmodfor the remainder.- Word-spelled logical and bitwise operators.
and,or,xor,not,shl,shrserve both logical and bitwise duty — the compiler chooses based on operand types. - String concatenation uses
&. Use$to stringify any value before concatenating. - Compound assignment requires
var.letbindings are immutable, so+=and friends only apply tovar. - Custom operators inherit precedence from their first character. This lets you design DSL-like syntax without surprising the parser.
- Power lives in
std/math. Import^(integer) orpow(float) when you need exponentiation.
Running Today
All examples can be run using Docker:
docker pull nimlang/nim:alpine
Comments
Loading comments...
Leave a Comment