Skip to content

Latest commit

 

History

History
218 lines (176 loc) · 10.1 KB

STANDARD_LIBRARY_SPEC.md

File metadata and controls

218 lines (176 loc) · 10.1 KB

ProScript standard-library specification

This document indexes the standard-library surface decided through STD-150. It is normative together with the current Decided entries in the design and delivery record, which contains the exact signatures, byte-level contracts, algorithms, failure rules, rationale, explicit omissions, and conformance evidence. If this summary omits detail, the later current STD entry governs; implementation behavior is never a substitute for an STD decision.

Package model

Standard-library APIs are ordinary directory packages under std; they are not compiler-predeclared globals. Importers use the same qualified-name and visibility rules as other packages.

Decided v1 package inventory

Package or owner Current decision range Contract nucleus
std.fmt STD-001–STD-008, revised by STD-108 atomic string console writes; explicit Display; canonical Debug with default derivation, redaction, and omission
predeclared Result companion STD-009–STD-011 map, map_error, and_then, and or_else with exact typed failures
std.io STD-016–STD-022 typed Reader/Writer protocols, exact progress, EOF, partial-failure, and no-artificial-Result rules
std.fs STD-023–STD-027, STD-087–STD-090, STD-143–STD-144, STD-147 resource-backed files, bounded portable errors, whole-file and streaming directory operations, metadata, and exact host boundaries
collections STD-028–STD-031 array construction/mutation, map/set methods, value independence, and unobservable capacity
std.time STD-032–STD-036, STD-091–STD-094, STD-144–STD-146 Duration, monotonic Instant, sleep/deadlines, Timestamp, locations, civil conversion, and reference layouts
std.num STD-042–STD-047, revised by STD-109 limits, checked/wrapping/saturating arithmetic, checked conversions, float operations, and exact bit operations
std.strconv STD-048–STD-052, STD-133, STD-141 exact primitive parsing, radix/float rendering, and rune-to-string conversion
std.iter STD-053–STD-055 the compiler-recognized Iterator<Element> and Iterable<Element> protocols only
std.strings STD-056–STD-063 exact search/count/substring/split, Unicode-aware named units, whitespace, padding, and resource-backed Builder
std.unicode STD-064–STD-067, STD-150 Unicode 17 normalization, case operations, grapheme behavior, whitespace, and version reporting
std.encoding.utf8, .base64, .hex STD-068–STD-071, STD-130–STD-132, STD-147 exact validation, lossy decoding, RFC 4648 codecs, hex, offsets, and failure families
std.sort STD-072–STD-075 in-place stable array sort and binary search with exact comparator rules
std.math STD-076–STD-079, revised by STD-105 and STD-140 optimized platform transcendental functions with fixed special cases and accuracy contracts, not cross-platform final-bit identity
std.testing.assert STD-080–STD-082, revised by STD-103 unit-returning assertions that panic on failed expectations
std.path STD-083–STD-086, STD-134 lexical validated path algebra independent of filesystem access
std.random, std.crypto.random STD-095–STD-098, STD-106–STD-107, STD-139 reproducible pinned PCG streams and infallible system entropy with exact URL-token semantics
std.hash.*, std.crypto.* STD-099–STD-102, STD-135–STD-138 FNV, CRC, SHA-3, HMAC, and constant-time comparison
std.log STD-110–STD-117 levels, eagerly rendered named fields, filtering, deterministic stderr records, and contextual loggers
std.environment, std.process STD-118–STD-129, STD-142, STD-148–STD-149 immutable process context, environment, cwd, identity, exit/signals, resource-backed command/child lifecycle, errors, and streams

The inventory is a map, not a replacement for the exact declarations in the design record. Networking, HTTP, TLS, databases, compression, collation, calendar arithmetic, reusable timers, and other unlisted facilities are not implied.

std.fmt

The public console surface is:

package fmt

pub fn print(text: string)
pub fn println(text: string)
pub fn eprint(text: string)
pub fn eprintln(text: string)

pub protocol Display {
    fn display(self) string,
}

pub fn display<Value: Display>(value: Value) string
pub fn debug<Value: Debug>(value: Value) string

The four output functions accept exactly one string and return unit. println and eprintln append exactly one U+000A LF on every platform. One call is not interleaved with another ProScript call to the same stream; calls from different tasks may be ordered arbitrarily. The call may suspend for backpressure. An output failure panics; there is no implicit conversion, formatting, byte-count result, or typed I/O result.

Display is opt-in user-facing text. Its standard conformances cover string, bool, all integer types, float32, and float64. Exact aliases are transparent; byte and rune display numerically. There is no automatic aggregate or inherited nominal conformance. Interpolation, console output, Debug, diagnostics, logging, templates, JSON, and serialization never invoke Display implicitly.

debug performs exactly one Debug dispatch and returns the provider string unchanged. Automatic and standard providers use the compact canonical layout defined by STD-005 through STD-008, including stable collection ordering, declared-name nominal labels, qualified user-enum variants, unqualified Option/Result variants, canonical primitive escaping, redaction rules, and complete traversal. It is diagnostic text, not a parseable or serialized format. Manual providers are ordinary code and are responsible for their own determinism.

std.result

The authenticated companion implementation defines these exact inherent methods over the predeclared Result type:

pub fn Result<Value, Failure>::map<Next>(
    self,
    transform: fn(Value) Next,
) Result<Next, Failure>

pub fn Result<Value, Failure>::map_error<NextFailure>(
    self,
    transform: fn(Failure) NextFailure,
) Result<Value, NextFailure>

pub fn Result<Value, Failure>::and_then<Next>(
    self,
    transform: fn(Value) Result<Next, Failure>,
) Result<Next, Failure>

pub fn Result<Value, Failure>::or_else<NextFailure>(
    self,
    transform: fn(Failure) Result<Value, NextFailure>,
) Result<Value, NextFailure>

Each method evaluates its receiver and callback once, invokes the callback only for the selected variant, and preserves the untouched variant exactly. It introduces no implicit error conversion or recovery.

std.io

The decided primitive protocols are:

pub enum ReadOutcome {
    Data(int),
    End,
}

pub protocol Reader<Failure> {
    fn read(
        mut self,
        mut destination: Array<byte>,
    ) Result<ReadOutcome, Failure>,
}

pub protocol Writer<Failure> {
    fn write(
        mut self,
        data: Array<byte>,
        count: int,
    ) Result<unit, Failure>,
}

For a nonempty destination, Data(count) guarantees 1 <= count <= destination.length; exactly 0..count is produced data. End is graceful termination. Empty destinations panic, successful zero progress is forbidden, and the complete destination must be ignored after Err. A Reader cannot retain the destination or its writable lease.

Writer consumes exactly data[0..count] without defining a slice value. Negative or oversized counts panic before acceptance; zero succeeds without work. Ok(unit) means every selected byte was accepted once and in order, but does not promise flush, acknowledgement, synchronization, durability, or commit. After Err, an externally visible prefix may exist and generic code must not blindly retry.

Every concrete Reader or Writer selects one exact failure type through its unique protocol-family conformance. Generic calls may infer that type using the directional P-367 rule. There is no universal std.io::Error, implicit conversion, dynamic box, Any, or use of + as an error union. Generic algorithms retain source and destination failures in named enums such as CopyError<ReadFailure, WriteFailure>.

An operation with no expected operational failure returns its success type directly. It does not invent Result<Success, unit>, Infallible, a bottom type, or a duplicate success-only protocol hierarchy.

Filesystem failure model

Platform-backed packages classify evolving failures with an open opaque nominal integer and exact-type constants:

pub type opaque ErrorKind int;

pub const NOT_FOUND: ErrorKind = ErrorKind(1);
pub const PERMISSION_DENIED: ErrorKind = ErrorKind(2);
pub const ALREADY_EXISTS: ErrorKind = ErrorKind(3);
pub const NO_SPACE: ErrorKind = ErrorKind(4);

Matches require a fallback. Published numeric values are compatibility-stable and never reused, but their ordering and raw numbers carry no portable semantic meaning. Closed, fully controlled domains continue to use enums.

std.fs uses one bounded error family for related filesystem operations:

pub struct Error {
    kind: ErrorKind,
    operation: string,
    path: Option<string>,
    platform_code: Option<int>,
}

pub fn Error::kind(self) ErrorKind;
pub fn Error::operation(self) string;
pub fn Error::path(self) Option<string>;
pub fn Error::platform_code(self) Option<int>;

The fields and construction are package-private. The accessors return independent ordinary values. File conforms to io::Reader<fs::Error> and io::Writer<fs::Error>. Other packages own their own exact operational error families and application code maps them explicitly into domain errors.

Remaining boundary

No API is implied merely by appearing in an example, roadmap row, historical exploration, implementation file, or conformance note. The exact v1 omissions recorded by each decided package remain absent. New packages or conveniences require a later STD decision; in particular, the current baseline does not silently add networking, HTTP, TLS, databases, compression, Unicode collation, calendar arithmetic, reusable timers, per-task unseeded randomness, or a general error hierarchy.