Under heavy development. This site describes the intended 1.0 language. Current features and performance vary. Development status
Sn50SnThe SnAPI programming language
0.2.0 Preview 1 · Frozen documentation

Fold

Reduces a cursor left-to-right from an explicit Copyable seed.

Sn is under heavy development. Reference extracted from this release’s bundled standard library. Public API examples are not an exhaustive compatibility test. Read the matching release guide for tested workflows and limitations. Read the status →

Module std.iteration

import std.iteration;

Public declaration contracts and authored examples. A page can document several related symbols. Implementation bodies are excluded.

Fold

pub fn Fold<T, A, I>(mut Cursor: I, mut Seed: A, Reducer: fn(A, T) -> A) -> A
    where T: Movable
    where A: Copyable, CopyAssignable
    where I: TypedIterator<T>

Reduces a cursor left-to-right from an explicit Copyable seed.

Calls Reducer once per item, releases each consumed carrier before the next pull and returns Seed for an empty source. Checked/trapping operations inside Reducer retain their normal semantics. No intermediate allocation occurs; callback cost, side effects and reference invalidation are caller contracts. T: Exact Movable item value/reference category. A: Copyable and CopyAssignable accumulator type. I: Structural source cursor, inferred from Cursor. Cursor: Input traversal state; move a non-Copy cursor explicitly. Seed: Initial accumulator value, copied under ordinary A semantics. Reducer: Safe function receiving the previous accumulator and next item. Return: Final accumulator, or Seed if no item is present. Warning: Nonterminating input does not produce a final result; no synchronization is added.

Example

module example.fold_iterator;
from std.iteration import Fold;
fn Add(Total: i32, Item: i32&) -> i32 { return Total + Item; }
fn Main() -> i32 {
    let Values: i32[3] = [10, 20, 12];
    if Fold<i32&, i32>(Values.CreateIterator(), 0, Add) != 42 { return 1; }
    let Empty: i32[0] = [];
    if Fold<i32&, i32>(Empty.CreateIterator(), 7, Add) != 7 { return 2; }
    return 0;
}

Fold

pub fn Fold<T, A, I>(mut Cursor: I, mut Seed: A,
    Reducer: fn(mut A&&, T) -> A) -> A
    where T: Movable
    where A: Movable, MoveAssignable
    where I: TypedIterator<T>

Reduces a cursor with explicit consuming access to an owning accumulator.

The reducer receives the live Seed through mut A&& and returns an owned replacement. Seed assignment selects A's move assignment and cleanup; final or empty Seed transfers into the result. Input carriers transfer owned T or preserve reference T without moving referents. No implicit clone, allocation or synchronization is added. Callback and lifecycle work are additional costs. T: Exact Movable source item type. A: Owned Movable/MoveAssignable accumulator value type. I: Structural source cursor returning T?. Cursor: Owned traversal state, consumed in source order. Seed: Owned initial accumulator; move a non-Copy named value explicitly. Reducer: Safe consuming-access callback returning one owned replacement. Return: Final owned accumulator, or the transferred seed for empty input. Warning: Reducer must not publish aliases into consumed state or invalidate source backing.

Example

module example.owning_fold;
from std.iteration import Fold;
class Total {
    pub Value: i32;
    pub init(Value: i32) { this.Value = Value; }
    pub init(Source: readonly Self&) = delete;
    pub init(Source: mut Self&&) { this.Value = Source.Value; Source.Value = 0; }
    pub fn operator =(Source: mut Self&&) -> void {
        this.Value = Source.Value; Source.Value = 0;
    }
}
fn Add(Sum: mut Total&&, Item: i32) -> Total {
    return Total(Sum.Value + Item);
}
fn Main() -> i32 {
    // Use a value-producing cursor so the reducer receives exact i32 input.
    let Result = Fold<i32, Total>((10_i32..13_i32).CreateIterator(), Total(9), Add);
    if Result.Value != 42 { return 1; }
    let Empty = Fold<i32, Total>((0_i32..0_i32).CreateIterator(), Total(42), Add);
    if Empty.Value != 42 { return 2; }
    return 0;
}
Documentation snapshot: October 24, 2026 About versions ↗
Searching Development · language & standard library