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

Environment

Owns an explicit ordered environment snapshot with exact native-unit keys. Find/TrySet/Remove search linearly; edits do not affect the host environment. Portable edits require nonempty names without equals. Windows startup decoding may also retain native pseudo names beginning with equals. Keys remain unique by ordinal native representation. Every name and value uses the same representation. This is an explicit portable model, not a Windows host-name comparison adapter. Entries expose readonly views only, preventing mutation of lookup keys. Structural edits/movement/destruction invalidate cursors and borrowed views; replacement invalidates views of the replaced entry. Concurrent reads require a stable owner; externally synchronize edits. No I/O or hidden process lookup.

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.process

import std.process;

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

Environment

pub final class Environment

Owns an explicit ordered environment snapshot with exact native-unit keys. Find/TrySet/Remove search linearly; edits do not affect the host environment. Portable edits require nonempty names without equals. Windows startup decoding may also retain native pseudo names beginning with equals. Keys remain unique by ordinal native representation. Every name and value uses the same representation. This is an explicit portable model, not a Windows host-name comparison adapter. Entries expose readonly views only, preventing mutation of lookup keys. Structural edits/movement/destruction invalidate cursors and borrowed views; replacement invalidates views of the replaced entry. Concurrent reads require a stable owner; externally synchronize edits. No I/O or hidden process lookup.

Example

module example.environment;
from std.process import Environment, EnvironmentEntry, EnvironmentSetError;
from std.text import NativeString, NativeStringError;
from std.prelude import Result;
fn TryEntry(Name: str, Text: str) -> Result<EnvironmentEntry, NativeStringError> {
    var Key = {
        // Scoped writable carriers end immediately after explicit payload transfer.
        var KeyCreation = NativeString.TryCreate(Name);
        switch KeyCreation {
            case .Ok { Value = Value: mut NativeString& } => break move(Value);
            case .Err { Error = Error } => return .Err { Error = Error };
        }
    };
    var Content = {
        var ValueCreation = NativeString.TryCreate(Text);
        switch ValueCreation {
            case .Ok { Value = Value: mut NativeString& } => break move(Value);
            case .Err { Error = Error } => return .Err { Error = Error };
        }
    };
    return .Ok { Value = EnvironmentEntry(move(Key), move(Content)) };
}
fn Main() -> i32 {
    var Values = Environment();
    if !Values.IsEmpty || Values.Encoding is .Some { Value = _ } { return 1; }
    if Values.TryReserve(2) is .Err { Error = _ } { return 2; }
    var Entry = {
        var EntryCreation = TryEntry("MODE", "");
        switch EntryCreation {
            case .Ok { Value = Value: mut EnvironmentEntry& } => break move(Value);
            case .Err => return 3;
        }
    };
    var Copy = {
        var CopyCreation = Entry.TryClone();
        switch CopyCreation {
            case .Ok { Value = Value: mut EnvironmentEntry& } => break move(Value);
            case .Err => return 4;
        }
    };
    if !Copy.Name.EqualsOrdinal(Entry.Name) || !Copy.Value.IsEmpty { return 5; }
    if Values.TrySet(move(Entry)) is .Err { Error = _ } { return 6; }
    if Values.Length != 1 || Values.Find(Copy.Name).Unwrap().UnitLength != 0 { return 7; }
    var Updated = {
        var UpdatedCreation = TryEntry("MODE", "shipping");
        switch UpdatedCreation {
            case .Ok { Value = Value: mut EnvironmentEntry& } => break move(Value);
            case .Err => return 8;
        }
    };
    if Values.TrySet(move(Updated)) is .Err { Error = _ } { return 9; }
    if Values.Length != 1 || Values.Find(Copy.Name).Unwrap().TryViewUtf8().Unwrap() != "shipping" { return 10; }
    var Invalid = {
        var InvalidCreation = TryEntry("BAD=NAME", "retained");
        switch InvalidCreation {
            case .Ok { Value = Value: mut EnvironmentEntry& } => break move(Value);
            case .Err => return 11;
        }
    };
    {
    var Attempt = Values.TrySet(move(Invalid));
    switch Attempt {
        case .Err { Error = Failure: readonly EnvironmentSetError& } => {
            if !(Failure.Reason is .InvalidName) || Failure.Entry.Value.TryViewUtf8().Unwrap() != "retained" { return 12; }
        }
        case .Ok => return 13;
    }
    }
    {
    var Cursor = Values.CreateIterator();
    switch Cursor.Next() { case .Some { Value = ObservedEntry } => { if !ObservedEntry.Name.EqualsOrdinal(Copy.Name) { return 14; } } case .None => return 15; }
    }
    if !Values.Remove(Copy.Name) || Values.Remove(Copy.Name) { return 16; }
    if Values.Find(Copy.Name) is .Some { Value = _ } { return 17; }
    if Values.TrySet(move(Copy)) is .Err { Error = _ } { return 18; }
    var Moved = move(Values);
    if !Values.IsEmpty || Moved.Length != 1 { return 19; }
    return 0;
}

Environment.init

pub init()

Creates an empty allocation-free explicit snapshot.

Environment.init

pub init(Source: readonly Self&) = delete;

Rejects implicit allocating copies. Source: Existing owner.

Environment.init

pub init(Source: mut Self&&)

Transfers entry storage without host mutation or allocation. Source: Owner left empty.

Environment.operator

pub fn operator =(Source: readonly Self&) -> void = delete;

Rejects implicit allocating assignment. Source: Existing owner. Return: No runtime result; this assignment is deleted and cannot be invoked.

Environment.operator

pub fn operator =(Source: mut Self&&) -> void

Replaces ownership by explicit transfer. Source: Owner left empty except unchanged self-move. Return: No value after transferring environment backing; nested vector self-move is unchanged.

Environment.Length

pub Length: usize;

Counts distinct exact native names.

Environment.IsEmpty

pub IsEmpty: bool;

Observes whether the explicit snapshot has no entries.

Environment.Encoding

pub Encoding: NativeStringEncoding?;

Observes the shared unit kind, or none for an empty snapshot. Return: Encoding without searching, conversion or allocation.

Environment.TryReserve

pub fn TryReserve(Capacity: usize) -> Result<void, AllocationError>

Reserves entry slots without changing names or values. Capacity: Minimum requested slots; may allocate. Return: Ok or storage failure; existing entries unchanged on failure.

Environment.Find

pub readonly fn Find(Name: NativeStringView) -> NativeStringView?

Searches exact native names without Unicode/case conversion. Name: Borrowed key used only during this call. Return: Borrowed value or none; present empty values return Some. Warning: Linear search; returned view follows entry stability.

Environment.TryFindWindows

pub readonly fn TryFindWindows(Name: NativeStringView) -> Result<NativeStringView?, WindowsEnvironmentError>

Searches explicit UTF-16 entries using native Windows name comparison. Name: Borrowed UTF-16 key used only during this call. Return: Last equivalent borrowed value, none if absent, or exact typed failure. Warning: Linear search may allocate native comparison operands. Returned views follow entry stability. No host environment is read or mutated.

Example

module example.windows_environment_lookup;
from std.process import Environment, EnvironmentEntry;
from std.text import NativeString;
fn Main() -> i32 {
    let Upper: u16[4] = [0x50_u16, 0x41_u16, 0x54_u16, 0x48_u16];
    let Lower: u16[4] = [0x70_u16, 0x61_u16, 0x74_u16, 0x68_u16];
    let Empty: u16[0] = [];
    var Key = {
        // Scoped writable carriers end immediately after explicit payload transfer.
        var KeyCreation = NativeString.TryFromNativeUtf16(Upper);
        switch KeyCreation {
            case .Ok { Value = Value: mut NativeString& } => break move(Value);
            case .Err => return 1;
        }
    };
    var Query = {
        var QueryCreation = NativeString.TryFromNativeUtf16(Lower);
        switch QueryCreation {
            case .Ok { Value = Value: mut NativeString& } => break move(Value);
            case .Err => return 2;
        }
    };
    var Content = {
        var ValueCreation = NativeString.TryFromNativeUtf16(Empty);
        switch ValueCreation {
            case .Ok { Value = Value: mut NativeString& } => break move(Value);
            case .Err => return 3;
        }
    };
    var Values = Environment();
    if Values.TrySet(EnvironmentEntry(move(Key), move(Content))) is .Err { Error = _ } { return 4; }
    // Portable lookup remains exact; native lookup reports unavailable hosts.
    if Values.Find(Query.View) is .Some { Value = _ } { return 5; }
    switch Values.TryFindWindows(Query.View) {
        case .Ok { Value = PatternPayload5075 } => {
            switch PatternPayload5075 {
                case .Some { Value = Found } => { if !Found.IsEmpty { return 6; } }
                default => return 7;
            }
        }
        case .Err { Error = PatternPayload5076 } if (PatternPayload5076 is .Unsupported) => return 0;
        default => return 7;
    }
    return 0;
}

Environment.TrySet

pub fn TrySet(mut Entry: EnvironmentEntry) -> Result<void, EnvironmentSetError>

Inserts or replaces by exact native name, retaining rejected ownership. Entry: Owned name/value transferred on success or into returned failure. Return: Ok or invalid-name/mixed-representation/storage error owning Entry. Warning: Linear name search; insertion may allocate. No host mutation occurs.

Environment.Remove

pub fn Remove(Name: NativeStringView) -> bool

Removes one exact name while preserving remaining entry order. Name: Borrowed search key; never retained after return. Return: True if an entry was removed; false if absent. Warning: Linear search/compaction; invalidates affected views and all cursors.

Environment.CreateIterator

pub readonly fn CreateIterator() -> SliceIterator<EnvironmentEntry>

Creates allocation-free readonly traversal in insertion order. Return: Borrowed cursor; structural edits/movement/destruction invalidate it.

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