Index, range, and bitwise operators
Index and range operators make it concise to select positions and slices, including positions counted from the end. Bitwise operators work with the individual bits of integer values and flags.
Prefixing an expression with ^ produces a System.Index value that counts
from the end of a sequence. The operand must be implicitly convertible to
int, and the result keeps its Index type even when not target-typed, so
val offset = ^2 is valid without annotations. When indexing arrays, from-end
indices are computed using the array's length and are evaluated exactly once
alongside the receiver.
^ is parsed as a tight prefix form: ^expr. Trivia between ^ and the
operand is rejected, so ^1 is valid while ^ 1 is not.
Range expressions
.. produces an inclusive-notation Range form, and ..< produces a half-open
form with an exclusive upper bound. Both can be stored, passed to APIs, or used for
slicing receivers that understand .NET ranges. Both endpoints are optional, and
either endpoint may be written as a from-end index by prefixing it with ^.
val r = 3..^5
val halfOpen = 3..<10
val head = ..3
val tail = 3..
val all = ..
Forming a range evaluates each supplied boundary exactly once, left-to-right.
Each boundary expression must be implicitly convertible to int; the ^ prefix
indicates the operand counts from the end of the receiver instead of from the
start. The resulting Range uses Index.FromStart for ordinary boundaries and
Index.FromEnd for prefixed ones, and omitting a boundary produces
Range.StartAt, Range.EndAt, or Range.All accordingly. A range expression
retains its Range type even when no target type is provided, enabling
declarations like val r = 3..^5 without additional annotations.
Element access applies these types directly:
- One-dimensional arrays accept a single
Rangeargument (array[range]) and produce a sliced array. - Non-array receivers resolve
[]using argument-type matching, so indexers that differ byIndexvsRangecan coexist.
Bitwise operators
Raven supports unary bitwise-not ~ plus binary &, |, ^, <<, and >>.
~is defined forintandlong.&,|, and^are defined forint,long,bool, and matching enum operands.<<and>>are defined forintandlongleft operands with anintshift count.
When both operands are bool, &, |, and ^ evaluate without short-circuiting and return bool, allowing direct use in non-conditional contexts or within compound assignments. Operands must share the same enum type when applied to enums; the result has that enum type.
Compound assignments &=, |=, and ^= are available and apply the corresponding binary operator after evaluating the left-hand side once. These operators share left-to-right associativity with other Raven binary operators, and their precedence sits between the logical (||, &&) and equality operators.
Enum member accesses support leading-dot syntax when a target type is already known, including inside bitwise combinations and argument lists:
val flags: BindingFlags = .NonPublic | .Static
func WithBinding(flags: BindingFlags) { /* ... */ }
WithBinding(.Public | .Instance)
Object creation and tuple syntax are documented separately in Object creation and Tuple expressions.