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

Memory & lifetime

Explicit ownership and deterministic cleanup.

Sn is under heavy development. This reference includes the intended 1.0 design; features may be incomplete in the current compiler. Read the status →

Native values

Ordinary values live inline unless a pointer, reference, slice, interface view, or explicit allocation introduces indirection. The design excludes a garbage collector and hidden allocation.

References and pointers

T&, T*, and T[] provide read-only access by default. mut T&, mut T*, and mut T[] grant writable access. Ordinary writable references may alias; this is not a Rust-style general borrow-checking model.

Allocation

Allocator-aware APIs make storage acquisition visible and fallible. Raw memory operations and lifetime operations require their documented safety contracts. Consult each library API before retaining a reference or view across mutation.

Cleanup

defer registers work for normal scope exit. Object cleanup and deferred work follow their lifetime contracts. Fatal traps and panic do not provide exception-style unwinding.

Views can become invalid

A non-owning view does not extend the owner's lifetime. Container growth, structural mutation, moves, and destruction may invalidate aliases; the specific operation's contract is authoritative.

Example: move ownership and release it deterministically

module example.unique;
from std.memory import Unique;
fn Main() -> i32 {
    var Owner = {
        // Keep writable result storage through the explicit noncopy payload transfer.
        var OwnerCreation = Unique<i32>.TryCreate(41);
        switch OwnerCreation {
            case .Ok { Value = Value: mut Unique<i32>& } => break move(Value);
            case .Err { Error = _ } => return 1;
        }
    };
    Owner.Value().Unwrap() += 1;
    {
        let Readonly: readonly Unique<i32>& = Owner;
        if Readonly.IsEmpty || Readonly.Value().Unwrap() != 42 { return 2; }
    }
    var Moved = move(Owner);
    if !Owner.IsEmpty || Moved.Value().Unwrap() != 42 { return 3; }
    Owner = move(Moved);
    if Owner.Take().Unwrap() != 42 || !Owner.IsEmpty { return 4; }
    if Owner.Take() is .Some { Value = _ } { return 5; }
    Owner.Clear();
    return 0;
}

This is the standard library’s maintained Unique workflow. The allocation failure is explicit, a move leaves the original owner empty, and cleanup belongs to the owner. Borrowed access does not extend the owner’s lifetime. See [Unique](/reference/dev/std-memory-unique/) for the full contract.

Documentation snapshot: October 24, 2026 About versions ↗
Searching Development · language & standard library