Ranges and Iterators
Calibre has a built-in range type, which you use with syntax like 0..10 or 1..=5.
The stdlib adds useful methods to range.
let r := 0..5;
print(r.len());print(r.start());print(r.end());print(r.contains(3));print(r.to_list());print(r.sum());Ranges can also be turned into iterators with .into_iter().
The stdlib defines several iterator types:
ListIter:<T>for listsRangeIterfor rangesStrIterfor strings
These types implement the stdlib Iter trait, which provides iterator-style methods such as:
.collect().map(...).filter(...).for_each(...).fold(...).any(...).all(...).find(...).count().take(...).skip(...).enumerate().step_by(...).partition(...)
For example:
let mapped := list:<int>[1, 2, 3].into_iter().map(fn (x : int) -> int => x * 10).collect();let filtered := list:<int>[1, 2, 3, 4].into_iter().filter(fn (x : int) -> bool => x % 2 = 0).collect();let folded := list:<int>[1, 2, 3, 4].into_iter().fold(0, fn (acc : int, x : int) -> int => acc + x);You can also work with iterator values manually through .next().
let mut it : RangeIter = (0..3).into_iter();
print(it.next());print(it.next());print(it.next());
let mut it : RangeIter = (0..3).into_iter();for let .Some : x => it.next() => print(x);String iteration uses StrIter and yields char values.
let mut chars : StrIter = "abc".into_iter();print(chars.next());