Skip to main content

Operators and punctuations

Operators in Jacy are not something internally special in comparison with functions. When calling a + b the trait std::ops::Add will be used. Mostly all operators are overloadable.

Operators in expressions

OperatorTrait to overload
a + bstd::ops::Add
a - bstd::ops::Sub
a * bstd::ops::Mul
a / bstd::ops::Div
a % bstd::ops::Rem
a ** b (*)std::ops::Pow
a or bN/A
a and bN/A
!astd::ops::Not
a & bstd::ops::BitAnd
a ∣ bstd::ops::BitOr
a << bstd::ops::Shl
a >> bstd::ops::Shr
a ^ bstd::ops::Xor
a < b   a > b   a >= b   a <= b   a <=> bstd::ops::Cmp
a == b   a != bstd::ops::Eq
a === b   a !== b??? (Not described)
a..bstd::ops::Range
a..=bstd::ops::RangeIncl
..bstd::ops::RangeTo
a..std::ops::RangeFrom
..=bstd::ops::RangeToIncl
..std::ops::RangeFull (**)
a += bstd::ops::AddAssign
a -= bstd::ops::SubAssign
a *= bstd::ops::MulAssign
a /= bstd::ops::DivAssign
a %= bstd::ops::RemAssign
a **= bstd::ops::PowAssign
a ∣= bstd::ops::BitOrAssign
a &= bstd::ops::BitAndAssign
a <<= bstd::ops::ShlAssign
a >>= bstd::ops::ShrAssign
a ^= bstd::ops::XorAssign
a?std::ops::Try::branch
a!std::ops::Try::unwrap
a.bN/A
a()std::ops::Invoke
*astd::ops::Deref
*a = bstd::ops::DerefMut
&aN/A
a ∣> bN/A
  • (*) For the exponentiation operator, there can be a conflict with dereferencing operator *, to solve it you need to put white space between terms. E.g. a**b == a ** b as far as a **b == a ** b but not == a * *b, and a*b == a * b. So, with dereferencing, always put white space before * (as dereferencing operator).
  • (**) RangeFull is not a real operator, it is an empty struct which can be passed somewhere.

Punctuations

SymbolUsages
:Type annotations in almost all constructions, function call argument name
->Function types, lambdas
;Statement terminator, body ignorance, item declaration
=>match arms

Operators and punctuations precedence

Precedence (from highest to lowest)

This table shows which operators are stronger than others, associativity is marked as "left to right" for left-associative operators and "right to left" for right-associative operators. This table also includes expressions that are not operator expressions, anyway, it might be helpful to know that they are parsed assuming this figurative precedence.

Precedence index is placed just for some help, sometimes you need to know the order.

The table is from high to low precedence ordered -- the operators in the first row have the strongest precedence.

Non-Assoc means non-associative operator, i.e. it is not allowed to combine it with itself like so a OP b OP c

NOperator groups / expressionsAssociativity
20Paths (::)N/A
19Field expression (aka member access - a.b)left to right
18Invocations (aka calls - a(...)), array access (aka indexing - a[...])N/A
17[Postfix operators] ?N/A
16[Prefix operators] !, &, &mut, -, *N/A
15asleft
14* / %left
13+ -left
12.. ..=non-assoc
11<< >>left
10& (infix)left
9^left
8left
7innon-assoc
6<=>non-assoc
5< > <= =>non-assoc
4== !=non-assoc
3andleft
2orleft
1= += -= *= /= %= &= ∣= ^= <<= >>=left

Prefix operators: not, & (borrow), &mut (borrow as mutable, & and mut can have whitespace between), - (negation), * (dereference).

Postfix operators: ? (optional chaining), ! (unwrap).

Range operators precedence [why?]
Range operators have this kind of precedence as we want to write `a..b+1` which means `a..(b+1)` as far as writing `a..b == c..d` which means `(a..b) == (c..d)`