Range
Lazy half open Int64 progressions, constant time arithmetic access and membership, checked bounds and efficient iteration.
Range is an import free immutable lazy sequence of Int64 values. It describes an arithmetic progression without allocating a List or array of its elements.
Construction and half open bounds
let samples: Range = Range(start: 0, stop: 10, step: 2)
print(samples.len()) // 5
for index in samples {
print(index) // 0, 2, 4, 6, 8
}Range(stop: Int64) starts at zero with a step of one. Range(start: Int64, stop: Int64) uses a step of one. The three argument overload accepts an explicit nonzero step: Int64.
The stop value is excluded. A positive step produces elements smaller than stop; a negative step produces elements greater than stop. A direction that cannot reach an eligible value yields an empty range. A zero step fails during construction. Negative values are ordinary progression values and do not enable negative indexing.
for index in Range(start: 5, stop: 0, step: -2) {
print(index) // 5, 3, 1
}
print(Range(3, 3).is_empty()) // trueConstruction retains an exact unsigned native element count, including ranges larger than the positive Int64 count limit. len() fails when that exact count cannot be represented as Int64; it never wraps or approximates. find likewise fails if a matching sequence index is larger than Int64. Boundary calculations avoid signed overflow; iteration never computes an unused out of range final value.
Access, search, and iteration
| Method | Result | Contract |
|---|---|---|
len() | Int64 | Exact count without iteration, or an error if the count does not fit Int64. |
is_empty() | Bool | Whether the count is zero. |
start() | Int64 | Declared first endpoint. |
stop() | Int64 | Declared exclusive stop endpoint. |
step() | Int64 | Declared nonzero step. |
get(index: Int64) | Int64 | Value at a nonnegative zero based sequence index. |
contains(value: Int64) | Bool | Check direction, bounds, and step divisibility arithmetically. |
find(value: Int64) | Int64 | Return the sequence index, or −1 when absent. |
get requires a nonnegative Int64 index smaller than the exact native count; it does not require calling len() first. find and contains do not use a linear scan or a search tree. for value in range evaluates the Range expression once and introduces an immutable Int64 loop binding for each element. Existing execution step limits apply; laziness avoids allocation but does not make a very long loop instantaneous.
A Range cannot be resized or mutated. Copies retain the original endpoints and step. Equality compares the declared descriptor, rather than materializing values. type(value) reports Range; dtype(value) reports Int64.
Errors and limits
A zero step, invalid index, or count/index not representable by a requested Int64 result produces a located runtime error R3403. Wrong static argument types or arities produce E1002. A runtime failure retains the normal program or persistent session error contract.
Time and space complexity
Construction, accessors, get, contains, find, descriptor equality, and copying use O(1) time and O(1) additional space with fixed width checked arithmetic. Persistent storage is O(1), independently of the element count. Iterating n elements adds O(n) sequence work and O(1) sequence state; loop body time and retained output space are additional. No O(n) element buffer is allocated.
Run the complete Range example, and see Duration for monotonic loop timing.