Nyx by Example

Iterator: fold

fold is the general-purpose iterator consumer that reduces a sequence to a single value. It takes an initial accumulator and a two-argument function, applies the function to each element and the running accumulator, and returns the final accumulated result.

Code

// fold: reducir un iterator a un valor acumulando con una función

fn add(acc: int, x: int) -> int {
    return acc + x
}

fn multiply(acc: int, x: int) -> int {
    return acc * x
}

fn max_val(acc: int, x: int) -> int {
    if x > acc {
        return x
    }
    return acc
}

fn is_even(x: int) -> bool {
    return x % 2 == 0
}

fn main() -> int {
    let nums: Array = [1, 2, 3, 4, 5]

    // Suma con fold — equivale a un loop manual con acumulador
    let suma: int = nums.iter().fold(0, add)
    print("suma(1..5) = " + int_to_string(suma))         // 15

    // Producto con fold
    let producto: int = nums.iter().fold(1, multiply)
    print("producto(1..5) = " + int_to_string(producto)) // 120

    // Máximo con fold
    let maximo: int = nums.iter().fold(0, max_val)
    print("max(1..5) = " + int_to_string(maximo))        // 5

    // Sumar solo los pares con filter + fold
    let nums2: Array = [10, 3, 8, 7, 2, 6]
    let suma_pares: int = nums2.iter().filter(is_even).fold(0, add)
    print("suma pares = " + int_to_string(suma_pares))   // 26 (10+8+2+6)

    // fold con valor inicial distinto de cero
    let nums3: Array = [1, 2, 3]
    let con_offset: int = nums3.iter().fold(100, add)
    print("100 + sum(1,2,3) = " + int_to_string(con_offset)) // 106

    return 0
}

Output

suma(1..5) = 15
producto(1..5) = 120
max(1..5) = 5
suma pares = 26
100 + sum(1,2,3) = 106

Explanation

fold(init, f) is equivalent to manually writing a loop with an accumulator variable: it starts with acc = init and for each element x computes acc = f(acc, x), returning the final acc. The choice of initial value is important: 0 is the identity for addition (adding zero changes nothing), while 1 is the identity for multiplication. Choosing the wrong initial value gives incorrect results.

The max_val accumulator function selects the larger of the current accumulator and the incoming element, so folding an array with 0 as the start finds the maximum. This works correctly here because all values are positive; for arrays that may contain negatives, the initial value should be set to the minimum possible integer.

Combining filter and fold in one pipeline — as in the even-sum example — is idiomatic Nyx: filter narrows the stream, then fold reduces it, with no intermediate array allocated. Many classic operations (sum, product, count, any, all) are special cases of fold and can be expressed this way.

← Previous Next →

Source: examples/by-example/30-iterator-fold.nx