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

CallableFold

Reduces a cursor with an owned concrete callback and 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, 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