Skip to main content

Iterables

Iterable values introduce a unified concept for processing sequences in various data structures. While the compiler uses an internal type iterable<T>, which cannot be explicitly declared in code, several types can be used as iterable<T>.

Iterable types

  1. range: iterable<integer>

    • Generates a sequence of integers.

    • Examples:

      • range(10) produces 0 to 9.

      • range(1, 10) produces 1 to 9.

      • range(0, 10, 2) produces 0, 2, 4, 6, 8.

  2. list<T>: iterable<T>

    • Stores an ordered collection of elements of type T.

    • Example:

      • list<integer> = [1, 2, 3, 4, 5]
  3. set<T>: iterable<T>

    • Holds a unique collection of elements of type T.

    • Example:

      • set<text> = {"apple", "banana", "cherry"}
  4. map<K,V>: iterable<(K,V)>

    • Associates keys of type K with values of type V.

    • Example:

      • map<text, integer> = {"one": 1, "two": 2, "three": 3}
  5. Virtual collections

    • virtual<list<T>>, virtual<set<T>>, virtual<map<K,V>>

    • Represent virtual collections that behave like their non-virtual counterparts.

Key applications of iterables

  1. for loops

    Easily iterate through elements:

    for (x in range(10)) {
    print(x);
    }
  2. Collection-at expressions

    Apply operations to each element:

    val doubled = range(1, 6) @* {} ( $ * 2 );
  3. List/Set/Map constructors

    Build new collections from iterables:

    struct Person {
    name: text;
    age: integer;
    }

    val people = [
    Person("Alice", 28),
    Person("Bob", 35),
    Person("Charlie", 22),
    Person("David", 41),
    Person("Eve", 19)
    ];

    // List constructor: names of people over 30
    val senior_names = list<text>();
    for (p in people) {
    if (p.age > 30) {
    senior_names.add(p.name);
    }
    }

    // Set constructor: unique ages
    val unique_ages = set<integer>();
    for (p in people) {
    unique_ages.add(p.age);
    }

    // Map constructor: name to age mapping
    val name_to_age = map<text, integer>();
    for (p in people) {
    name_to_age[p.name] = p.age;
    }

    // Printing names of seniors
    for (name in senior_names) {
    print("Senior name: " + name);
    }

    // Printing unique ages
    for (age in unique_ages) {
    print("Unique age: " + age);
    }

    // Printing name to age map
    for (name in name_to_age.keys()) {
    print(name + " is " + name_to_age[name] + " years old.");
    }

Practical examples

Working with ranges

// Generate squares of numbers from 0 to 9
val squares = list<integer>();
for (i in range(10)) {
squares.add(i * i);
}
print("Squares: " + squares);

// Create a set of natural numbers from 1 to 9
val naturals = set<integer>();
for (i in range(1, 10)) {
naturals.add(i);
}
print("Naturals: " + naturals);

// Generate even numbers from 0 to 18
val evens = list<integer>();
for (i in range(0, 20, 2)) {
evens.add(i);
}
print("Evens: " + evens);

Constructing and manipulating maps

// Construct a map from tuples
val tuples = [(1,'A'), (2,'B'), (3,'C')];
val m = map(tuples);
print(m); // Output: {1=A, 2=B, 3=C}

// Convert a map to a list of tuples
val L = list(m);
print(L); // Output: [(1,A), (2,B), (3,C)]

// Create a map from two lists
val keys = ["name", "age", "city"];
val values = ["Alice", "30", "New York"];
val details = map<text, text>();
for (i in range(keys.size())) {
details[keys[i]] = values[i];
}
print(details); // Output: {name=Alice, age=30, city=New York}

Working with sets

// Create a set from a list with duplicates
val numbers = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4];
val unique_numbers = set(numbers);
print(unique_numbers); // Output: [1, 2, 3, 4]

Advanced iterable usage

// Filter and transform a list
val numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
val even_numbers = list<integer>();
for (number in numbers) {
if (number % 2 == 0) {
even_numbers.add(number);
}
}
print(even_numbers); // Output: [2, 4, 6, 8, 10]



// Combine multiple iterables
val numbers1 = [1, 2, 3];
val numbers2 = [4, 5, 6];
val combined = list<integer>();
for (number in numbers1) {
combined.add(number);
}
for (number in numbers2) {
combined.add(number);
}
print(combined); // Output: [1, 2, 3, 4, 5, 6]