Under heavy development. This site describes the intended 1.0 language. Current features and performance vary. Development status
Sn50SnThe SnAPI programming language
Development · Evolving reference

CallableFold

Reduces a cursor with an owned concrete callback and Copyable seed.

Sn is under heavy development. This reference includes the intended 1.0 design; features may be incomplete in the current compiler. 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, C>(mut Cursor: I, mut Seed: A, mut Reducer: C) -> A
    where T: Movable where A: Copyable, CopyAssignable
    where I: TypedIterator<T> where C: BinaryCallable<A, T, A>, Movable

Reduces a cursor with an owned concrete callback and Copyable seed.

Traversal is left-to-right and calls the callback once per item. Empty input returns Seed without invocation. Callback storage is concrete; the terminal adds no allocation or synchronization. Captures retain their own lifetimes; owning item carriers transfer and exact reference items retain aliases. T: Exact Movable input type. A: Copyable and CopyAssignable accumulator value/reference type. I: Structural source cursor, inferred from Cursor. C: Movable safe readonly BinaryCallable, inferred from Reducer. Cursor: Owned traversal state; move non-Copy named state explicitly. Seed: Initial accumulator, copied under ordinary A semantics. Reducer: Owned callback; borrowed capture backing must outlive traversal. Return: Final accumulator or Seed for empty input. Warning: Infinite input never completes; callback may have its own costs/side effects.

Example

module example.concrete_fold;
from std.iteration import Fold;
fn Main() -> i32 {
    let Factor: i32 = 2;
    let AddScaled = (Total: i32, Item: i32) => Total + Item * Factor;
    let Total = Fold<i32, i32>((10_i32..12_i32).CreateIterator(), 0, AddScaled);
    if Total != 42 { return 1; }
    let Empty = Fold<i32, i32>((0_i32..0_i32).CreateIterator(), 7, AddScaled);
    if Empty != 7 { return 2; }
    return 0;
}

Fold

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

Reduces owning state through a concrete consuming-access callback.

The callback borrows live Seed with mut A&& and returns one owned replacement. Selected move assignment installs that replacement; final/empty Seed moves into the result. Current's owning payload transfers without moving referents of reference payloads. The terminal owns C and adds no allocation or locking. T: Exact Movable input item type. A: Owned Movable/MoveAssignable accumulator type. I: Structural cursor, inferred from Cursor. C: Concrete safe readonly consuming reducer, inferred from Reducer. Cursor: Owned traversal state; non-Copy named cursors require move. Seed: Owned initial accumulator; move non-Copy named state explicitly. Reducer: Owned environment; borrowed backing must survive traversal. Return: Final owned Seed, transferred also for empty input. Warning: Callback must not publish aliases into consumed state or invalidate source backing.

Example

module example.concrete_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;
    }
}
class ScaledReducer {
    priv Factor: i32;
    pub init(Factor: i32) { this.Factor = Factor; }
    pub readonly fn Invoke(Sum: mut Total&&, Item: i32) -> Total {
        return Total(Sum.Value + Item * Factor);
    }
}
fn Main() -> i32 {
    var Seed = Total(0);
    let Result = Fold<i32, Total>((10_i32..12_i32).CreateIterator(),
        move(Seed), ScaledReducer(2));
    if Result.Value != 42 || Seed.Value != 0 { return 1; }
    let Empty = Fold<i32, Total>((0_i32..0_i32).CreateIterator(),
        Total(7), ScaledReducer(2));
    if Empty.Value != 7 { return 2; }
    return 0;
}
Documentation snapshot: October 24, 2026 About versions ↗
Searching Development · language & standard library