Operators Galore
2026-03-10
Raku has one of the richest operator sets of any programming language. This is not complexity for its own sake. Each operator exists to make a specific pattern concise and readable. In this tutorial, we will cover the operators you will use most often, from basic arithmetic to the mind-bending magic of junctions.
Numeric vs String Operators
One of the first things to understand in Raku is that numeric and string operations use different operators. This eliminates an entire class of bugs common in other languages.
Comparison Operators
| Operation |
Numeric |
String |
| Equal |
|
eq |
| Not equal |
!= |
ne |
| Less than |
< |
lt |
| Greater than |
> |
gt |
| Less or equal |
<= |
le |
| Greater or equal |
>= |
ge |
| Three-way compare |
<=> |
leg |
say 10 == 10;
say "10" eq "10";
say 10 == "10";
say "aa" lt "bb";
say "2" lt "10";
say 2 < 10;
That last pair is exactly why separate operators matter. "2" lt "10" is False because string comparison goes character by character, and "2" is greater than "1". Use < for numbers, lt for strings, and you will never be surprised.
Arithmetic Operators
The basics work as you would expect:
say 10 + 3;
say 10 - 3;
say 10 * 3;
say 10 / 3;
say 10 ** 3;
say 10 % 3;
say 10 div 3;
Notice that 10 / 3 gives you a Rat (rational number), not a floating-point approximation. Raku uses rational arithmetic by default, which means 1/3 + 1/3 + 1/3 actually equals 1. No floating-point weirdness.
say (1/3 + 1/3 + 1/3) == 1;
say (1/3).WHAT;
String Operators
say "Hello" ~ " " ~ "World";
say "ha" x 3;
The ~ operator concatenates strings. The x operator repeats a string. These are distinct from + and so there is never confusion between numeric and string operations.
Ranges
The range operator .. creates a Range object:
my @digits = 0..9;
say @digits;
my @letters = 'a'..'f';
say @letters;
say (0..^5).list;
say (0^..5).list;
say (0^..^5).list;
Ranges are lazy by default. Writing 1..Inf does not try to create an infinite list in memory; it generates values on demand.
for 1..5 -> $n {
say "Number $n";
}
The Sequence Operator (...)
The sequence operator ... is one of Raku's most powerful features. It generates sequences by inferring patterns:
say (1, 2, 4 ... 64).list;
say (1, 3, 5 ... 15).list;
say (1, 1, *+* ... 89).list;
The + is a WhateverCode expression meaning "add the previous two values." The sequence operator figures out the pattern from the initial values and generates terms until it hits the endpoint.
say (10, 9, 8 ... 1).list;
say (1, 3, 9 ... 729).list;
say (1, 2, 4 ... *)[^8];
Chaining Comparisons
Raku lets you chain comparison operators naturally, just like you would write them in mathematics:
my $x = 5;
say 1 < $x < 10;
say 1 < $x < 3;
say 1 <= $x <= 5;
my $y = 5;
say $x == $y == 5;
This is much cleaner than writing $x > 1 && $x < 10. The chain can be as long as you need:
say 1 < 2 < 3 < 4 < 5;
say 1 < 2 < 3 < 2 < 5;
The Ternary Operator (?? !!)
Where most languages use ? : for ternary expressions, Raku uses ?? !!:
my $age = 20;
my $status = $age >= 18 ?? "adult" !! "minor";
say $status;
The doubled characters make the ternary operator much easier to spot in code, especially when nested:
my $score = 85;
my $grade = $score >= 90 ?? "A"
!! $score >= 80 ?? "B"
!! $score >= 70 ?? "C"
!! "F";
say $grade;
Smart Match ()
The smart match operator is context-sensitive. It adapts its behavior based on what is on the right side:
say 42 ~~ Int;
say "hello" ~~ /hell/;
say 5 ~~ 1..10;
say "cat" ~~ "cat";
say 7 ~~ (1, 3, 5, 7);
Smart match is the backbone of Raku's given/when construct (covered in the control flow tutorial).
Junctions (any, all, one, none)
Junctions are one of Raku's most unique features. A junction is a single value that simultaneously represents multiple values:
my $j = any(1, 2, 3);
say 2 == $j;
say 5 == $j;
There are four types of junctions:
say "found" if 5 == any(1, 3, 5, 7);
say "all big" if all(10, 20, 30) > 5;
say "just one" if one(1, 2, 2) == 1;
say "none zero" if none(1, 2, 3) == 0;
The | operator creates an any junction, and & creates an all junction:
my $color = "red";
if $color eq "red" | "blue" | "green" {
say "$color is a primary color";
}
my @scores = 85, 92, 78, 95;
if all(@scores) >= 70 {
say "Everyone passed!";
}
Junctions can replace many common patterns that would otherwise require loops:
my @allowed = <admin editor viewer>;
my $role = "editor";
if $role eq any(@allowed) {
say "Access granted";
}
my @temperatures = 36.5, 37.0, 36.8;
if all(@temperatures) < 38 {
say "No fevers detected";
}
Assignment Operators
Raku supports the usual compound assignment operators:
my $n = 10;
$n += 5;
$n -= 3;
$n *= 2;
$n /= 4;
my $s = "Hello";
$s ~= " World";
Precedence Tip
When in doubt about precedence, use parentheses. But here is a quick mental model for the most common operators, from highest to lowest precedence:
- Method calls (
.method)
- Exponentiation (
)
- Multiplication, division (
, /, %, div)
- Addition, subtraction (
+, -)
- Concatenation (
~)
- Comparisons (
, <, eq, etc.)
- Logical and (
&&, and)
- Logical or (
||, or)
- Ternary (
?? !!)
- Assignment (
=, :=)
What is Next?
With operators under your belt, you are ready to put them to work in conditional statements and loops. Next up: control flow in Raku, from if to given/when to all the looping constructs you could want.