The following table summarizes all 11l operators in order of precedence from highest to lowest:
x.y
module:f
a[i]
a[%i]
f(x)
x--
x++
x!
x.*
| Member access
Module function or variable access
Subscript
N. Subscript ({…if i is negative, the index is relative to the end of the array})
Function call
Postfix decrement
Postfix increment
Non-null assertion operator
Pointer dereference |
^ | Power operator (right to left associative) |
-x
+x
!x
~x
--x
++x
&x
| Unary minus
Unary plus
Logical NOT
Bitwise NOT
Prefix decrement
Prefix increment
Address-of |
x * y
x *& y
x / y
x I/ y
x -I/ y
x % y
x -% y
| Multiplication
Overflow multiplication (rationale: {…this is similar to UInt32((Int64(x) * y) [&] FFFF'FFFFh).as(Int32) , so *& is more logical, than &* in Swift (there is *% in Zig, which is quite logical also [because you can replace [&] with % : Int32((Int64(x) * y) % 1'0000'0000h) ], but -% in 11l is already used for N. Remainder)})
Division
Integer division {…note that -5 // 2 = -3 in Python whereas -5 I/ 2 = -2 in 11l, but this is merely because of performance considerations, and if you know efficient implementation of Python integer division, please write at the forum}
N. Integer division ({…performs floor division if dividend is negative})
Remainder
N. Remainder ({…result is positive even if x is negative}, rationale: {…% in 11l works [for performance reasons] as in C++, not as in Python}) |
x""y and x‘’y | String concatenation (rationale) |
x + y
x - y
x +& y
x -& y | Addition
Subtraction
Overflow addition
Overflow subtraction |
x << y
x >> y | Bitwise left shift
Bitwise right shift |
x [&] y | Bitwise AND (rationale: {…
[&] looks similar to AND gate:
}) |
x (+) y | Bitwise XOR (rationale: {…
Symbols (+) look like symbol ⊕, which is used in Boolean algebra for exclusive or operation: .
And although ⊕ is used more often for single-bit values, in Wikipedia it is sometimes used for pointers and for arrays of bytes. In addition, the symbol ⊕ can be found in scientific articles, as well as in problem texts on Codeforces (1, 2).
[Besides, usage of ^ for this operation I consider a bad idea (at least this is confusing for novices).]
}) |
x [|] y | Bitwise OR (rationale: {…
Symbol | looks like 1 and [1] looks similar to OR gate:
}) |
x < y, x <= y
x > y, x >= y | Comparison operators |
x ? y | Null coalescing (rationale: {…
This operator is denoted differently in different programming languages: some of them use ?: (e.g., Kotlin, Groovy, Objective-C), while others use ?? (e.g., C#, JavaScript, PHP, Swift, PowerShell).
Besides, in 11l (like in Kotlin), I /if is an expression: it returns a value. Therefore, there is no ternary operator (condition ? then : else ) because ordinary I /if works fine in this role.
}) |
x..y, x.<y, x.+len
x<.y, x<.<y | Ranges |
x == y, x != y
e in c, e !in c
e C c, e !C c
| Comparisons
Including membership tests |
x & y | Logical AND (rationale: {…
& is used instead of && because:
- Logical AND is needed much more often than bitwise AND.
- Bitwise AND is almost always used just for check if some flag is set, but this is error-prone {…
Consider following C++ code:
class Render
{
public:
static const unsigned F_CAST_SHADOWS = 1 << ...;
};
class Control
{
public:
unsigned flags;
static const unsigned F_DISABLED = 1 << ...;
};
void some_func(Control *c)
{
if (c->flags & Control::F_DISABLED) {
...
}
if (c->flags & Render::F_CAST_SHADOWS) { // this is wrong, but will be correctly compiled in C++!
...
}
}
11l solution:
T Control
T.flags flags
DISABLED
or:
T Control
T Flags
Bool DISABLED
Flags flags
F some_func(Control c)
I c.flags.DISABLED
...
}, so the decision was made to discourage from such usage of bitwise AND operator at all.
Sometimes bitwise AND is used as a modulo (% ) operation of powers of 2, but if the second operand is constant, then operator % should be used instead (x [&] y = x % (y + 1) ). If operator % works for negative numbers like in Python (i.e. e.g. -1 % 4 = 3 ), then expression x % (y + 1) will be compiled to bitwise AND.
There should not be any problem with converting code from C-like language to 11l, because in case you forget to replace & with [&] , then there will be a compile-time error as <number> & <number> is not valid in 11l (only <boolean> & <boolean> is valid, e.g. <number> != 0 & <number> != 0 ).
The symbol & is also used as logical AND in Oberon and ALGOL 68.
}) |
x | y | Logical OR |
arr1 [+] arr2 | Array concatenation (rationale: {…
Because arrays are defined using square brackets: [1, 2, ...] .
As this operation is quite expensive, it has dedicated operator.
}) |
() -> expr
x -> expr
(x, y) -> expr | Lambda expression |
x = ...
x += ...
-= *= /= I/=
%= >>= <<= ^=
[+]= [&]= [|]=
(+)= ‘’= .= | Assignments (right to left associative) |