Operators
Power function
a^xforpow(a, x)(as in Julia),- “raise a to the power of x”.
Boolean operators
and,or,nand,nor,xorin addition to&&/&,||/|, …- similar to Python, Carbon
- Used for both
- boolean operation (when used on Bool)
aBoolandanotherBool->Bool
- bitwise operation (when used on integers)
anIntandanotherInt->Int
- No mixed types allowed (you need to explicitly cast one side instead).
- boolean operation (when used on Bool)
- Words like
andandorIMHO are a bit clearer than&&/&and||/|, so they are recommended. - Still also use
&and|for bitwise operation,- as C/C++/Java/C# programmers are used to it,
- as we keep
&=and|=anyway.
- Still also use
&&and||for boolean operation,
notin addition to!(for boolean negation)notis a bit clearer than!(especially as many modern languages like Rust and Swift use!also for error handling).- Still also
!for negation (in addition tonot), as we keep!=for “not equal” anyway.
(We could use<>instead of!=, but that’s really not familiar to C/C++ programmers.) - Still use
~for bitwise negation,- as C/C++/Java/C# programmers are used to it,
- as we keep
~Tfor the destructor anyway.
xorinstead of^
because we want^for the power function.
Equality
- Default
operator==- If not defined, then
- use negated
operator!=(if defined), or - use
operator<=>(if defined), or - use elementwise comparison with
==- Only possible if all elements themselves offer the
operator==. - Optimization for simple types: Byte-by-byte comparison.
- Only possible if all elements themselves offer the
- use negated
- If not defined, then
- Default
operator!=- If not defined, then
- use negated
operator==(if defined), or - use
operator<=>(if defined), or - use negated generated
operator==.
- use negated
- If not defined, then
Range operator .. and ..<
1..10and0..<10are ranges- as in Kotlin
- Similar, but different:
- Swift would be
and1...100..<10 - Rust would be
and1..=100..10 - Cpp2 would be
and1..=10(as of recently)0..<10
- Swift would be
- Different kinds of ranges:
1..3– 1, 2, 3Range(1, 3)
0..<3– 0, 1, 2RangeExclusiveEnd(0, 3)
- Range with step (especially to iterate with the given step size in the
forloop)1..6:2– 1, 3, 5RangeByStep(1, 6, 2)
0..<6:2– 0, 2, 4RangeExclusiveEndByStep(0, 6, 2)
- Downwards iterating range (especially to iterate downwards in the
forloop).
Step size is mandatory here (to make it clear that we are counting down, to avoid wrong conclusions).8..0:-1– 8, 7, 6, 5, 4, 3, 2, 1, 0RangeByStep(8, 0, -1)- Not
, as8..0Range(8, 0)is always empty (it is counting up, not down!) - Not
8..<0:-1- With staticAssert in
RangeExclusiveEndByStepthatstep > 0:
“The range operator with exclusive end (..<) is not compatible with negative increments, because when counting downwards it would be necessary/logical to write..>and that is not available.” - It simply would be too much, IMHO.
- Use
8..1:-1instead.
- With staticAssert in
- If both start and end of the range are compile time constants, then it may be warned when the range contains no elements at all (e.g. when
start >= endwithstep > 0). - Incomplete ranges (need lower and/or upper bounds to be set before use)
..2– …, 1, 2RangeTo(2)
..<3– …, 1, 2RangeToExclusiveEnd(3)
0..– 0, 1, 2, …RangeFrom(0)
..RangeFull()
- Incomplete range with step
..2:2–RangeToByStep(2, 2)..<3:2–RangeToExclusiveEndByStep(3, 2)0..:2–RangeFromByStep(0, 2)..:2–RangeFullByStep(2)
- See Rust Ranges and Slices
Bit-Shift & Rotation
>>Shift right- Logical shift with unsigned integers,
- arithmetic shift with signed integers.
<<Shift left- Here a logical shift left with unsigned integers is the same as an arithmetic shift left with signed integers.
>>>Rotate right- Circular shift right,
- only defined for unsigned integers,
- and only for fixed size integers (i.e. not for
BigUInt).
<<<Rotate left- Circular shift left,
- only defined for unsigned integers,
- and only for fixed size integers (i.e. not for
BigUInt).
Operator Declaration
- Keyword
operatorinstead offunc. - As with normal functions: Parameters are passed as
inby default (i.e.const T&orconst T).
Assignment operator
class Int256 {
operator =(Int256 other) { ... }
}
- No return of this-reference,
- as in Swift,
- so
if a = b { ... }is not accidentally allowed.
- Move assignment
class Int256 { operator =(move Int256 other) { ... } }
Arithmetic operators
operator +(Int256 a, b) -> Int256 { ... }
operator -(Int256 a, b) -> Int256 { ... }
operator *(Int256 a, b) -> Int256 { ... }
operator /(Int256 a, b) -> Int256 { ... }
operator %(Int256 a, b) -> Int256 { ... }
Shift and rotate operators
operator <<(Int256 a, Int shiftCount) -> Int256 { ... }
operator >>(Int256 a, Int shiftCount) -> Int256 { ... }
operator <<<(UInt256 a, Int shiftCount) -> UInt256 { ... }
operator >>>(UInt256 a, Int shiftCount) -> UInt256 { ... }
Compound assignment operators
class Int256 {
operator +=(Int256 other) { ... }
operator -=(Int256 other) { ... }
operator *=(Int256 other) { ... }
operator /=(Int256 other) { ... }
operator %=(Int256 other) { ... }
operator <<=(Int shiftCount) { ... }
operator >>=(Int shiftCount) { ... }
operator &=(Int256 other) { ... }
operator |=(Int256 other) { ... }
}
class UInt256 {
operator <<<=(Int shiftCount) { ... }
operator >>>=(Int shiftCount) { ... }
}
- Not
operator ^=(Int256 other) { ... }
Increment and decrement operators
class Int256 {
operator ++() -> Int256& { ... }
operator ++(Int dummy) -> Int256 { ... } // post-increment
operator --() -> Int256& { ... }
operator --(Int dummy) -> Int256 { ... } // post-decrement
}
Relational and comparison operators
operator ==(Int256 a, b) -> Bool { ... }
operator !=(Int256 a, b) -> Bool { ... }
operator <(Int256 a, b) -> Bool { ... }
operator >(Int256 a, b) -> Bool { ... }
operator <=(Int256 a, b) -> Bool { ... }
operator >=(Int256 a, b) -> Bool { ... }
operator <=>(Int256 a, b) -> Int { ... }
Logical operators
- Boolean operators
operator and(Bool a, b) -> Bool { ... } operator or(Bool a, b) -> Bool { ... } operator nand(Bool a, b) -> Bool { ... } operator nor(Bool a, b) -> Bool { ... } operator xor(Bool a, b) -> Bool { ... } operator not(Bool a) -> Bool { ... } operator &&(Bool a, b) -> Bool { return a and b } operator ||(Bool a, b) -> Bool { return a or b } operator !(Bool a) -> Bool { return not a } operator ∧(Bool a, b) -> Bool { return a and b } operator ∨(Bool a, b) -> Bool { return a or b } operator ⊼(Bool a, b) -> Bool { return a nand b } operator ⊽(Bool a, b) -> Bool { return a nor b } operator ⊻(Bool a, b) -> Bool { return a xor b }- Defined for
Bool(not for integers), - operators
!, not,~&&and||, not.&and|
- Defined for
- Bitwise operators
operator and(Int256 a, b) -> Int256 { ... } operator or(Int256 a, b) -> Int256 { ... } operator nand(Int256 a, b) -> Int256 { ... } operator nor(Int256 a, b) -> Int256 { ... } operator xor(Int256 a, b) -> Int256 { ... } operator not(Int256 a) -> Int256 { ... } operator &(Int256 a, b) -> Int256 { return a and b } operator |(Int256 a, b) -> Int256 { return a or b } operator ~(Int256 a) -> Int256 { return not a } operator ∧(Int256 a, b) -> Int256 { return a and b } operator ∨(Int256 a, b) -> Int256 { return a or b } operator ⊼(Int256 a, b) -> Int256 { return a nand b } operator ⊽(Int256 a, b) -> Int256 { return a nor b } operator ⊻(Int256 a, b) -> Int256 { return a xor b }- Defined for integers (not for
Bool), - operators
~, not,!&and|, not.&&and||
- Defined for integers (not for
Subscript/Bracket Operator
class MyArray<type T> {
// Array subscript
operator [Int i] -> T& {
return data[i]
}
}
class MyImage<type T> {
// 2D array (i.e. image like) subscript
operator [Int x, y] -> T& {
return data[x + y*stride]
}
}
Parenthesis/Functor Operator
class MyFunctor {
// Functor call
operator (Int a, Float b, String c) {
...
}
}