slovo/docs/language/SPEC-v1.md

254 KiB

Slovo v1 Specification

Status: living beta contract for 1.0.0-beta, with the post-beta 1.0.0-beta.1 tooling/install update, 1.0.0-beta.2 runtime/resource foundation update, 1.0.0-beta.10 developer-experience API discovery update, 1.0.0-beta.11 local package API documentation update, and 1.0.0-beta.12 concrete vector query and prefix parity update, and 1.0.0-beta.13 diagnostic catalog and schema policy update, and 1.0.0-beta.14 benchmark suite catalog and metadata gate, 1.0.0-beta.15 reserved generic collection boundary hardening and collection ledger, 1.0.0-beta.16 string scanning and token boundary foundation, 1.0.0-beta.17 JSON primitive scalar parsing foundation, 1.0.0-beta.18 JSON string token parsing foundation, and 1.0.0-beta.19 test discovery and user-project conformance tooling. The language contract integrates promoted language slices through exp-125 and the historical publication baseline through exp-123. 1.0.0-beta is the first real general-purpose beta release. exp-125 completed the unsigned numeric and stdlib breadth precursor scope, exp-124 is the last tagged experimental alpha language contract before beta, and exp-123 is the last tagged experimental documentation/tooling contract before beta. 1.0.0-beta includes direct u32 and u64 value flow, decimal suffixed literals 42u32 / 42u64, same-type unsigned arithmetic/comparison, unsigned print/format/parse-result runtime lanes, and matching staged stdlib helper parity alongside the previously promoted project/package, collection, composite-data, docs, and diagnostics surface. exp-121 broadens unary enum payload variants to current known non-recursive struct types while keeping the same-payload-type-per-enum rule when payload variants are present and reusing existing immutable enum flow and match payload binding behavior. The earlier exp-120 broadens direct struct field declarations to the current promoted fixed immutable array family over i32, i64, f64, bool, and string. The earlier exp-118 broadens fixed immutable arrays with one connected string element lane alongside the earlier exp-117 direct scalar array family i32, i64, f64, and bool. The earlier exp-119 keeps the exp-118 language surface unchanged while refreshing the earlier benchmark/ publication baseline around five kernels: math-loop, branch-loop, parse-loop, array-index-loop, and string-eq-loop. The earlier exp-114 promotes same-type mutable whole-value local reassignment for already-supported non-array composite value families. The earlier exp-113 promotes direct mutable bool, i64, and f64 locals, and the earlier exp-112 promotes immutable bool locals. The earlier exp-111 broadens the concrete std.io facade with one connected stdin helper package over the already promoted std.io.read_stdin_result, std.string.parse_*_result, and the exp-109 bridge surface. The earlier v2.0.0-beta.1 tag name is historical and is not a beta maturity claim.

Base release: Slovo v0

Date started: 2026-05-16

1. Purpose

Slovo v1 grows the v0 language kernel without weakening the project rule that made v0 reliable:

A feature is supported only when Slovo docs and Glagol behavior agree across surface syntax, typed-core meaning, lowering behavior, formatter behavior, diagnostics, examples, and tests.

This file is a living post-v0 contract. A section is compiler-supported only when it is marked promoted, has fixtures in examples/supported/ and examples/formatter/, is implemented in Glagol, and is covered by tests.

Current v1 release surface and explicit experimental targets:

  • struct value flow through immutable locals, parameters, returns, calls returning structs, and field access through stored struct values

  • option/result value flow through immutable locals, parameters, calls returning option/result values, and tag observation with is_some, is_none, is_ok, and is_err, plus explicit trap-based i32 payload extraction with unwrap_some, unwrap_ok, and unwrap_err

  • array value flow for fixed-size arrays over direct scalar i32, i64, f64, bool, fixed-size string, direct known enum, and current known non-recursive struct element families through immutable locals, parameters, returns, calls returning arrays, and runtime-checked dynamic indexing with i32 index expressions

  • runtime string support through direct immutable source string literals, immutable and whole-value mutable string locals, string parameters, string returns, calls returning strings, string equality, string byte length, and legacy compiler/runtime compatibility aliases (print_string value) and (string_len value)

  • local binding surface through immutable let plus same-type mutable var / set flows for direct bool, i64, f64, string, current concrete vec families, current concrete option/result families, current known struct values, and current enum values, while fixed arrays remain immutable

  • legacy compiler/runtime compatibility alias (print_bool value)

  • v1 tooling contracts for slovo.diagnostic machine diagnostics, slovo.artifact-manifest output manifests, and LLVM span/source-map direction

  • v1.3 project mode for flat local projects with slovo.toml, explicit local imports, explicit export lists, deterministic module ordering, multi-file diagnostics, and project artifact-manifest fields, once the matching Glagol v1.3 gates pass

  • v1.4 source-level match for existing (option i32), (option i64), (option f64), (option bool), (option string), and (result i32 i32) values, with exhaustive arms, immutable arm payload bindings, arm-local expression bodies, common arm result types, formatter layout, and named diagnostics, once the matching Glagol v1.4 gates pass

  • v1.5 standard-runtime alpha names std.io.print_i32, std.io.print_string, std.io.print_bool, and std.string.len as compiler-known source-level names over the existing runtime behavior, with legacy print_i32, print_string, print_bool, and string_len names remaining compatibility aliases, once the matching Glagol v1.5 gates pass

  • v1.6 memory and unsafe design slice: lexical unsafe remains the only unsafe boundary; alloc, dealloc, load, store, ptr_add, unchecked_index, reinterpret, and ffi_call are compiler-known reserved unsafe heads that require UnsafeRequired in safe code and UnsupportedUnsafeOperation inside lexical unsafe until a future release defines execution semantics

  • v1.7 developer experience hardening: tooling-only contracts for glagol new, glagol fmt --check, glagol fmt --write, glagol doc, and a local release-gate script, without adding source language syntax, semantics, LSP, stable debug metadata, or stable source maps

  • v2.0.0-beta.1 experimental integration/readiness release: the accumulated v1.1-v1.7 surface is supported for small real flat local projects through glagol new, check, fmt --check/--write, test, build, doc, artifact manifests, JSON diagnostics, and the release-gate script

  • 1.0.0-beta.8 concrete type alias target: top-level (type Alias TargetType) declarations name existing supported concrete target types and are resolved before typed-core lowering, backend layout, ABI decisions, and runtime behavior; no generic aliases, parameterized aliases, alias exports/imports/re-exports, cross-module alias visibility, maps/sets, or runtime changes are included, once the matching Glagol gates pass

  • 1.0.0-beta.9 collection alias unification and generic reservation target: existing concrete vector, option, and result source facades may use module-local concrete aliases internally while exported helper behavior and cross-module types remain concrete; executable generics, maps, sets, traits, inference, monomorphization, iterators, stable ABI/layout, and runtime changes remain out of scope, once the matching Glagol gates pass

  • 1.0.0-beta.10 developer-experience API discovery target: the generated docs/language/STDLIB_API.md catalog lists exact exported helper signatures from lib/std/*.slo, normalizes module-local concrete aliases to public concrete types, and omits non-exported helpers and (type ...) aliases; glagol symbols emits deterministic editor-facing source metadata for files, projects, and workspaces; this is beta API discovery only, not executable generics, maps, sets, runtime changes, LSP/watch, or a stable 1.0.0 standard-library freeze

  • 1.0.0-beta.11 local package API documentation target: glagol doc <file|project|workspace> -o <dir> includes deterministic exported/public API sections for local packages and modules with exact exported function signatures, exported struct fields, exported enum variants/payload types, non-export filtering, and module-local alias normalization; this remains beta API discovery only, not a stable Markdown schema, stable stdlib/API compatibility freeze, LSP/watch contract, SARIF/daemon protocol, diagnostics schema policy, executable generics, maps/sets, re-exports, globs, hierarchical modules, or registry semantics

  • 1.0.0-beta.12 concrete vector query and prefix parity target: source-authored std.vec_i64 gains count_of, starts_with, without_prefix, ends_with, and without_suffix; source-authored std.vec_f64 gains count_of; this is helper parity over the current concrete vector runtime names only, not a source-language/runtime change, executable generics, maps/sets, iterators, mutable vectors, slice/view APIs, new runtime names, ABI/layout stability, performance claims, or a stable stdlib API freeze

  • 1.0.0-beta.13 diagnostic catalog and schema policy target: docs/language/DIAGNOSTICS.md documents the existing slovo.diagnostic version 1 beta policy, S-expression/JSON relationship, required and optional fields, JSON-line discipline, source-less diagnostics, artifact-manifest diagnostic metadata, compatibility/migration classes, and current golden diagnostic code catalog; this is docs/tooling policy only, not a source-language/runtime change, LSP/watch contract, SARIF/daemon protocol, stable Markdown schema, or stable 1.0.0 diagnostics freeze

  • 1.0.0-beta.14 benchmark suite catalog and metadata target: benchmarks/README.md documents the existing benchmark suite inventory and root suite-list commands: python3 benchmarks/runner.py --suite-list and python3 benchmarks/runner.py --suite-list --json; benchmark timing remains local-machine evidence only, and suite-list JSON is beta tooling metadata only, not a stable public schema; this is docs/tooling metadata only, not new benchmark kernels, timing publication, performance thresholds, source-language/runtime/stdlib/API changes, diagnostic-output changes, or ABI/layout changes

  • 1.0.0-beta.15 reserved generic collection boundary hardening target: COLLECTIONS.md documents the current concrete collection and value-family boundary by linking to the generated STDLIB_API.md catalog for exact helper signatures, recording design pressure from duplicated concrete vector/option/result families, defining promotion prerequisites for executable generics, generic aliases, maps, sets, iterators, mutable vectors, and slice/view APIs, and treating current unsupported diagnostics as boundaries; this is docs/design and compiler-boundary hardening only, not a source-language, runtime, stdlib/API, diagnostic output shape, diagnostic code, diagnostic schema, diagnostic span, expected/found value, hint, benchmark metadata schema, ABI/layout, performance-claim, or stable stdlib/API change; affected reserved-boundary messages are reworded from beta.9-specific text to current-beta wording

  • 1.0.0-beta.16 string scanning and token boundary target: std.string.byte_at_result, std.string.slice_result, std.string.starts_with, and std.string.ends_with provide byte-oriented scanning helpers over the current NUL-terminated runtime string representation; invalid indexes and ranges return err 1, substring allocation failure may follow the existing string allocation trap policy, and this target does not add Unicode/grapheme/display-width semantics, JSON parsing, object/array parsing, tokenizer objects, language slice/view syntax, mutable strings, stable ABI/layout, performance claims, or a stable stdlib/API freeze

  • 1.0.0-beta.17 JSON primitive scalar parsing target: std.json.parse_bool_value_result, std.json.parse_i32_value_result, std.json.parse_u32_value_result, std.json.parse_i64_value_result, std.json.parse_u64_value_result, std.json.parse_f64_value_result, and std.json.parse_null_value_result consume one already-isolated primitive scalar token and return concrete (result ... i32) values; full JSON document parsing, string/object/array parsing, tokenizers, recursive JsonValue, Unicode escape handling, stable ABI/layout, performance claims, and stable stdlib/API freeze remain out of scope

  • 1.0.0-beta.18 JSON string token parsing target: std.json.parse_string_value_result : (string) -> (result string i32) consumes one already-isolated ASCII JSON string token with exact quotes and no leading/trailing whitespace, decodes simple JSON escapes, returns err 1 for ordinary parse failure, and rejects raw control bytes, bad escapes, unterminated/trailing bytes, raw non-ASCII, and all \uXXXX escapes for this slice; full JSON document parsing, object/array parsing, tokenizer APIs, recursive JsonValue, Unicode escape decoding/normalization, embedded NUL policy, stable ABI/layout, performance claims, and stable stdlib/API freeze remain out of scope

  • 1.0.0-beta.19 test discovery and user-project conformance target: glagol test --list <file|project|workspace> and legacy glagol --run-tests --list <file> list checked/discovered tests without executing test bodies; list mode preserves current test ordering, honors --filter <substring>, and remains beta tooling rather than a stable schema. This target does not add source-language syntax, runtime helper names, JSON expansion, parallel test execution, retries, tags/groups, coverage/event streams, stable artifact-manifest or Markdown schemas, LSP/watch behavior, SARIF/daemon protocols, package registries, semver solving, or performance claims

  • exp-1 owned runtime strings: compiler-known std.string.concat accepts two string values and returns an immutable runtime-owned string; existing string equality, length, printing, locals, parameters, returns, and calls work over both literal-backed and runtime-owned strings

  • exp-2 collections alpha plus exp-94 vec-i64 baseline, exp-99 vec-string baseline, exp-103 vec-f64 baseline, and exp-104 vec-bool baseline: concrete growable vector types (vec i32), (vec i64), (vec f64), (vec bool), and (vec string), compiler-known std.vec.i32.empty, std.vec.i32.append, std.vec.i32.len, std.vec.i32.index, compiler-known std.vec.i64.empty, std.vec.i64.append, std.vec.i64.len, and std.vec.i64.index, compiler-known std.vec.f64.empty, std.vec.f64.append, std.vec.f64.len, and std.vec.f64.index, compiler-known std.vec.bool.empty, std.vec.bool.append, std.vec.bool.len, and std.vec.bool.index, compiler-known std.vec.string.empty, std.vec.string.append, std.vec.string.len, and std.vec.string.index, vector equality with = on same-family operands, and immutable vector flow through locals, parameters, returns, calls, and top-level tests

  • exp-3 standard IO and host environment: compiler-known std.io.eprint, std.process.argc, std.process.arg, std.env.get, std.fs.read_text, and std.fs.write_text with stage-specific runtime traps and integer write status

  • exp-4 user enum alpha: payloadless user-defined enum declarations, zero-argument qualified variant constructors, immutable local, parameter, return, and call flow, same-enum equality, and exhaustive payloadless enum match

  • exp-16 unary i32 enum payloads alpha: user-defined enum variants may be payloadless or carry one i32 payload; qualified constructors pass zero or one argument accordingly; enum match arms bind exactly one immutable arm-local payload name for payload variants; same-enum equality compares tag plus payload for payload variants and tag for payloadless variants

  • exp-17 project enum imports alpha: project/workspace module export lists may include top-level enum names, import lists may import exported enum names, and imported enum types preserve exactly the exp-4 payloadless plus exp-16 unary i32 payload surface

  • exp-18 enum struct fields alpha: struct field declarations may use current user-defined enum type names directly, struct construction may initialize those fields with payloadless or unary i32 enum values, and field access may flow into same-enum equality or exhaustive enum match

  • exp-19 primitive struct fields alpha: struct field declarations may use direct bool and immutable string field types alongside direct i32 and exp-18 enum fields; field access may flow into existing bool predicate positions, string equality, and std.string.len

  • exp-112 immutable bool locals alpha: direct immutable bool locals declared with let, initialized from already promoted bool expressions, and reusable in existing predicate, return, call, test, and main positions

  • exp-113 mutable scalar locals alpha: direct mutable bool, i64, and f64 locals declared with var, plus same-type set reassignment from already promoted scalar expressions

  • exp-114 mutable composite locals alpha: same-type mutable whole-value reassignment with var / set for string, current concrete vec families, current concrete option/result families, current known struct values, and current enum values

  • exp-20 f64 numeric primitive alpha: direct f64 parameters, returns, immutable locals, calls, decimal literals, same-type f64 arithmetic/comparison, and std.io.print_f64

  • exp-21 i64 numeric primitive alpha: direct i64 parameters, returns, immutable locals, calls, explicit signed decimal i64 literal atoms, same-type i64 arithmetic/comparison, and std.io.print_i64

  • exp-22 numeric widening conversions alpha: explicit std.num.i32_to_i64 : (i32) -> i64, std.num.i32_to_f64 : (i32) -> f64, and std.num.i64_to_f64 : (i64) -> f64 calls over the existing numeric primitives

  • exp-23 checked i64-to-i32 conversion alpha: exactly one checked narrowing standard-runtime call, std.num.i64_to_i32_result : (i64) -> (result i32 i32), returning ok for signed i32 range values and err 1 for out-of-range values

  • exp-24 integer to string alpha: exactly two integer formatting standard-runtime calls, std.num.i32_to_string : (i32) -> string and std.num.i64_to_string : (i64) -> string, returning decimal signed ASCII strings with - only for negative values and no leading +

  • exp-25 string parse i64 result alpha: exactly one string parse standard-runtime call, std.string.parse_i64_result : (string) -> (result i64 i32), returning ok value for in-range ASCII signed decimal i64 text and err 1 for parse failure or out-of-range input

  • exp-125 current Slovo-side unsigned target: direct u32/u64 parameters, returns, immutable locals, calls, decimal suffixed literals 42u32 / 42u64, same-type unsigned arithmetic/comparison, std.io.print_u32, std.io.print_u64, std.num.u32_to_string, std.num.u64_to_string, std.string.parse_u32_result, std.string.parse_u64_result, and matching staged source-helper parity across std.result, std.option, std.string, std.num, std.io, std.env, std.fs, std.process, and std.cli

  • exp-26 f64 to string alpha: exactly one finite f64 formatting standard-runtime call, std.num.f64_to_string : (f64) -> string, returning finite decimal ASCII text for promoted finite f64 inputs

  • exp-27 checked f64 to i32 result alpha: exactly one checked f64 to i32 result standard-runtime call, std.num.f64_to_i32_result : (f64) -> (result i32 i32), returning ok value only for finite, exactly integral inputs inside the signed i32 range and err 1 for non-finite, fractional, or out-of-range input

  • exp-28 string parse f64 result alpha: exactly one string parse standard-runtime call, std.string.parse_f64_result : (string) -> (result f64 i32), returning ok value for complete finite ASCII decimal f64 text and err 1 for ordinary parse failure, non-finite text, trailing or leading unsupported characters, or out-of-domain input

  • exp-29 numeric struct fields alpha: direct immutable struct field declarations whose field types are exactly i64 or f64, alongside already supported direct i32, bool, immutable string, and current enum fields; accessed fields may flow into existing same-type numeric arithmetic/comparison and existing numeric print/format helpers

  • exp-120 fixed array struct fields alpha: direct immutable struct field declarations whose field types are exactly the current promoted fixed-array families (array i32 N), (array i64 N), (array f64 N), (array bool N), and (array string N) with positive literal lengths; field access returns the declared array type and may flow into existing checked index

  • exp-121 non-recursive struct enum payloads alpha: unary enum payload variants may use current known non-recursive struct types, payload variants in one enum still share the same payload type when payload variants are present, and bound payload values reuse existing field access behavior

  • exp-30 standard library source layout alpha: establish std/ as the source home for staged standard library modules and examples, including narrow source-authored std/math.slo helpers, without automatic standard-library import/search, replacing compiler-known std.* calls, stable APIs, manifest schema changes, or beta maturity

  • exp-31 checked f64 to i64 result alpha: exactly one checked f64 to i64 result standard-runtime call, std.num.f64_to_i64_result : (f64) -> (result i64 i32), returning ok value only for finite, exactly integral inputs inside the signed i64 range and err 1 for non-finite, fractional, or out-of-range input

  • exp-32 standard math source helpers alpha: staged std/math.slo includes source-authored abs_i64, min_i64, max_i64, clamp_i64, square_i64, abs_f64, min_f64, max_f64, and clamp_f64 alongside the existing i32 helpers and square_f64, without automatic standard-library import/search or new compiler-known runtime names

  • exp-33 standard result source helpers alpha: staged std/result.slo includes concrete is_err_* and unwrap_err_* helpers for the already promoted result families, plus unwrap_or_i32, unwrap_or_i64, unwrap_or_string, and unwrap_or_f64, without automatic standard-library import/search or new compiler-known runtime names

  • exp-34 string parse bool result alpha: exactly one string parse standard-runtime call, std.string.parse_bool_result : (string) -> (result bool i32), returning ok true for exactly true, ok false for exactly false, and err 1 for empty input, uppercase/mixed-case text, leading/trailing whitespace, numeric text, or any other text

  • exp-35 standard result bool source helpers alpha: staged std/result.slo includes is_ok_bool, is_err_bool, unwrap_ok_bool, unwrap_err_bool, and unwrap_or_bool for (result bool i32), without automatic standard-library import/search, compiler-known runtime names, generic result helpers, or stable ABI/layout claims

  • exp-36 standard option source helpers alpha: staged std/option.slo includes is_some_i32, is_none_i32, unwrap_some_i32, and unwrap_or_i32 for (option i32), without automatic standard-library import/search, compiler-known runtime names, generic option helpers, option payloads beyond i32, or stable ABI/layout claims

  • exp-37 standard time source facade alpha: staged std/time.slo includes monotonic_ms and sleep_ms_zero wrappers over the already released exp-8 std.time.* calls, without automatic standard-library import/search, compiler-loaded standard-library source, compiler-known runtime names, wall-clock/calendar/timezone APIs, high-resolution timers, async timers, cancellation, scheduling guarantees, or stable ABI/layout claims

  • exp-38 standard host source facades alpha: staged std/random.slo, std/env.slo, and std/fs.slo add narrow source wrappers over already released random, environment, and text filesystem calls, without automatic standard-library import/search, compiler-loaded standard-library source, compiler-known runtime names, random seed/range/bytes/float/UUID/crypto APIs, environment mutation/enumeration, binary/directory/streaming/async filesystem APIs, rich host error ADTs, or stable ABI/layout claims

  • exp-39 standard math extensions and benchmark scaffold alpha: staged std/math.slo adds source-authored neg, cube, zero/positive/negative predicates, and inclusive in_range helpers for i32, i64, and finite f64, while the matching Glagol benchmark scaffold remains local timing evidence only

  • exp-44 standard library source search alpha: project-mode source may explicitly import (import std.math (...)), resolving to repo-root std/math.slo with its own export list; still no automatic std imports, workspace/package std imports, registry behavior, std.slo aggregator, broad standard-library APIs, stable ABI/layout, or beta maturity

  • exp-45 standard result and option source search alpha: project-mode source may explicitly import (import std.result (...)) and (import std.option (...)), resolving to repo-root std/result.slo and std/option.slo with their own export lists; still no automatic std imports, workspace/package std imports, generic result/option helpers, registry behavior, broad standard-library APIs, stable ABI/layout, or beta maturity

  • exp-46 workspace standard source search alpha: workspace packages may explicitly import standard source modules such as (import std.option (...)), using the same repo-root standard source lookup; still no automatic std imports, workspace dependency syntax for std, installed stdlib paths, registry behavior, stable ABI/layout, or beta maturity

  • exp-47 standard host facade source search alpha: project-mode source may explicitly import std.time, std.random, std.env, and std.fs, resolving to staged repo-root source facades with their own export lists; still no automatic std imports, installed stdlib paths, broad host APIs, stable ABI/layout, or beta maturity

  • exp-48 standard core facade source search alpha: project-mode source may explicitly import std.string and std.num, resolving to staged repo-root source facades with their own export lists; still no automatic std imports, installed stdlib paths, generic parse/format APIs, broad numeric casts, stable ABI/layout, or beta maturity

  • exp-49 standard IO facade source search alpha: project-mode source may explicitly import std.io, resolving to the staged repo-root source facade with its own export list; still no automatic std imports, installed stdlib paths, broad IO APIs, formatted output APIs, stable ABI/layout, or beta maturity

  • exp-50 installed standard library discovery alpha: explicit standard-source imports may resolve staged std/*.slo files from an installed share/slovo/std toolchain layout; still no automatic std imports, package registry behavior, lockfiles, package std dependencies, stable install layout guarantees, broad standard-library APIs, stable ABI/layout, or beta maturity

  • exp-51 standard library path list alpha: SLOVO_STD_PATH may name an ordered OS path list of standard-library roots; still no automatic std imports, package registry behavior, lockfiles, semantic version solving, stable package manager behavior, broad standard-library APIs, stable ABI/layout, or beta maturity

  • exp-52 standard process facade source search alpha: project-mode source may explicitly import std.process, resolving to the staged repo-root source facade with its own export list; still no automatic std imports, package registry behavior, process spawning, exit/status control, current-directory APIs, signal handling, stable ABI/layout, or beta maturity

  • exp-53 standard CLI source facade alpha: project-mode source may explicitly import std.cli, resolving to the staged repo-root source facade with its own export list; the facade composes std.process and std.string; still no automatic std imports, package registry behavior, shell parsing, option/flag parsing, subcommands, environment-backed configuration, stable CLI framework APIs, stable ABI/layout, or beta maturity

  • exp-54 standard CLI typed arguments alpha: staged std.cli adds arg_i64_result, arg_i64_or_zero, arg_f64_result, arg_f64_or_zero, arg_bool_result, and arg_bool_or_false

  • exp-55 result f64 bool source flow alpha: source may construct and match the concrete (result f64 i32) and (result bool i32) families directly; still no generic results, broad payload families, generic result combinators, stable ABI/layout, or beta maturity

  • exp-56 integer remainder alpha: % is supported for same-width i32 and i64 operands, and std.math adds concrete remainder/even/odd helpers; still no floating-point remainder, modulo semantics beyond signed integer remainder, bit operations, generic math, stable ABI/layout, or beta maturity

  • exp-57 integer bitwise alpha: bit_and, bit_or, and bit_xor are supported for same-width i32 and i64 operands, and std.math adds concrete bitwise wrappers; still no shifts, bit-not, unsigned arithmetic, bit-width-specific integer families, generic math, stable ABI/layout, or beta maturity

  • exp-58 boolean logic alpha: and and or are short-circuiting boolean forms, and not negates a boolean value; still no truthiness, variadic boolean operators, pattern guards, macro expansion, stable ABI/layout, or beta maturity

  • exp-119 benchmark/publication refresh alpha: no language-surface change over exp-118; current benchmark/publication evidence widens from three kernels to five by adding array-index-loop and string-eq-loop, while keeping local-machine-only framing and no threshold claim

  • exp-122 composite data benchmark/publication refresh alpha: no language-surface change over exp-121; current benchmark/publication evidence target widens from five kernels to seven by adding array-struct-field-loop and enum-struct-payload-loop, while keeping local-machine-only framing and no threshold claim

  • exp-120 fixed array struct fields alpha: current promoted fixed immutable arrays may also appear as direct struct fields with immutable struct flow and checked indexing after field access, without adding array mutation, field mutation, nested arrays, or beta maturity

  • exp-121 non-recursive struct enum payloads alpha: current known non-recursive struct types may also appear as unary enum payload variants with immutable enum flow and match payload binding exposing existing field access behavior, without adding direct array/vec/option/result payloads, equality requirements for struct-payload enums, mutation, or beta maturity

  • exp-59 benchmark/publication alpha: no language-surface change over exp-58; an earlier benchmark/publication baseline was refreshed against the paired Glagol hosted-build optimization

  • exp-5 local packages/workspaces: explicit workspace members, package name/version metadata, local path dependencies, package-qualified imports, deterministic package graph ordering, and artifact-manifest package graph recording

  • exp-6 C FFI scalar imports alpha: top-level imported C function declarations with i32 parameters, i32 or internal unit returns, lexical (unsafe ...) at imported C call sites, explicit local C source linking, and artifact-manifest foreign-import metadata

  • exp-7 test selection and test-run metadata alpha: glagol test <file.slo|project> --filter <substring>, legacy glagol --run-tests --filter <substring> <file.slo>, deterministic display-name substring filtering, skipped accounting, zero-match success, and additive test-report manifest metadata

  • exp-8 host time and sleep alpha: compiler-known std.time.monotonic_ms: () -> i32 and std.time.sleep_ms: (i32) -> unit, non-negative host monotonic elapsed milliseconds with implementation-owned epoch, non-negative millisecond sleep with 0 valid, exact negative-duration trap text, deterministic sleep_ms 0 test-runner behavior, and conservative monotonic_ms structural or non-negative host-value test-runner support

  • exp-9 reliability, performance, and ecosystem hardening: released hardening-only experimental contract over the exp-8 baseline, with no source syntax, type-system, standard-runtime, manifest-schema, ABI/layout, package, runtime-capability, public-performance, or beta-maturity expansion

  • exp-10 result-based host errors alpha: concrete (result string i32), additive std.process.arg_result, std.env.get_result, std.fs.read_text_result, and std.fs.write_text_result, ordinary host failure as err 1, and exp-3 calls unchanged

  • exp-11 basic randomness alpha: exactly one compiler-known standard-runtime operation, std.random.i32: () -> i32, returning a non-negative implementation-owned pseudo-random or host-random i32 for basic CLI use only

  • exp-12 standard input result alpha: exactly one compiler-known standard-runtime operation, std.io.read_stdin_result: () -> (result string i32), reading remaining stdin as text and returning ok text, with ordinary EOF as ok "" and ordinary host/input failure as err 1

  • exp-13 string parse i32 result alpha: exactly one compiler-known standard-runtime operation, std.string.parse_i32_result: (string) -> (result i32 i32), parsing an entire ASCII decimal signed i32 string with optional leading -, success as ok value, and ordinary parse failure as err 1

  • exp-14 standard runtime conformance alignment: released experimental alignment over the exp-13 surface, adding STANDARD_RUNTIME.md, byte-identical exp-8 time/sleep fixtures, explicit fixture inventory and byte-alignment gates, and no new source syntax, type forms, runtime APIs, std.* names, manifest schema version, ABI/layout promise, runtime headers/libraries, or beta maturity

  • exp-15 result helper standard names alpha: compiler-known source-level std.result.is_ok, std.result.is_err, std.result.unwrap_ok, and std.result.unwrap_err for only the already supported (result i32 i32), (result i64 i32), (result string i32), and exp-28 returned (result f64 i32) families, plus exp-34 returned (result bool i32), with legacy unqualified helper names retained as compatibility syntax

v1 scope-freeze decisions are also part of this contract. They clarify what remains outside v1 rather than adding language features:

  • struct field mutation and whole-struct value mutation remain deferred beyond v1 unless a later explicit promotion updates this spec, examples, diagnostics, and Glagol tests
  • option/result mapping, equality, printing, non-i32 payloads and extraction, nested option/result values, arrays or structs containing option/results, enum payloads beyond exp-16 unary i32 variants, exp-116 unary direct scalar/string variants, and exp-121 unary current known non-recursive struct variants, enum import behavior beyond exp-17 explicit local export/import lists, enum values in containers or nested structs beyond exp-18 direct fields, generic payloads, string containers beyond exp-19 direct struct fields and exp-118 fixed immutable arrays, and user-catchable exceptions remain deferred unless explicitly promoted later; exp-10 promotes only the concrete (result string i32) family and does not broaden general option/result support
  • bool printing is promoted in v1.2 through legacy compiler/runtime compatibility alias print_bool
  • unit remains an internal builtin result type for supported unit-producing body forms; print_unit, user-declared unit, and stored unit values remain unsupported in v1.2
  • runtime printing remains limited to legacy compatibility aliases print_i32, print_string, and print_bool plus v1.5 std.io.print_i32, std.io.print_string, and std.io.print_bool, plus exp-20 std.io.print_f64 and exp-21 std.io.print_i64; broader standard-runtime printing remains deferred
  • lexical unsafe remains the only accepted unsafe boundary; pointer types, allocation, deallocation, load, store, pointer arithmetic, reinterpretation, unchecked indexing, raw memory execution, and FFI remain deferred
  • stable ABI and stable layout promises remain deferred; v1.6 keeps memory model direction staged toward safe values by default, future affine ownership, and explicit unsafe regions
  • exp-1 does not change the v1 stable ABI/layout deferral; runtime-owned string representation, allocator behavior, cleanup timing, and C symbols remain implementation-owned
  • exp-3 does not change the v1 stable ABI/layout deferral; host helper symbols, path handling, process/environment shims, and runtime string storage remain implementation-owned
  • exp-4 does not change the v1 stable ABI/layout deferral; enum runtime representation, discriminant values, helper symbols, reflection, and conversions remain implementation-owned
  • exp-5 does not add remote registries, version solving, package publishing, package generics, package re-exports, or cross-package ABI stability
  • exp-6 does not stabilize pointer types, allocation/deallocation, raw unsafe head execution, ownership/lifetime rules, C exports, callbacks, headers, libraries, broad linker configuration, ABI, or layout
  • exp-7 does not add source language syntax, LSP, debug metadata, source maps, SARIF, watch/daemon protocols, documentation comments, lint categories, benchmarks, or richer test-runner features beyond the filtered alpha
  • exp-8 does not add source language syntax, threads, tasks, channels, async, cancellation, actors, shared memory, data-race freedom, scheduling guarantees, timers, wall-clock/calendar/timezone APIs, high-resolution timers, signal handling, stable ABI/layout, or stable runtime helper symbols
  • exp-10 does not change exp-3 host calls or add general host error ADTs, platform-specific codes, error messages, result string Error, broader host APIs, manifest schema versions, stable ABI/layout, or beta maturity
  • exp-11 does not add seed APIs, cryptographic or security promises, bytes APIs, ranges or bounds arguments, floats, random strings, UUIDs, stable helper ABI/layout, randomness-specific manifest fields, or beta maturity
  • exp-12 does not add trap-based std.io.read_stdin, line iteration, prompt APIs, terminal mode, binary stdin, streaming, async, encoding or Unicode promises beyond existing string bytes, stable helper ABI/layout, manifest schema changes, or beta maturity
  • exp-13 does not add trap-based std.string.parse_i32, parsing floats, bools, strings, or bytes, whitespace/locale/base-prefix/underscore/plus-sign parsing, generic parse APIs, parse error messages or richer codes, Unicode digit parsing, string indexing or slicing, tokenizer/scanner APIs, stdin line APIs, stable helper ABI/layout, manifest schema changes, or beta maturity
  • exp-15 does not add std.result.map, std.result.unwrap_or, std.result.and_then, option helper standard names, new payload families, generic result support, user-defined error payloads, enum payloads, runtime ABI/layout claims, manifest schema changes, or beta maturity
  • exp-33 does not add generic std.result.map, generic std.result.unwrap_or, std.result.and_then, option helper standard names, new result payload families, automatic std imports, compiler-loaded std/ source, runtime ABI/layout claims, manifest schema changes, or beta maturity
  • exp-34 does not add generic parse APIs, trap-based parse, bool parsing beyond exactly complete ASCII lowercase true and false, string/bytes parse, whitespace trimming, case-insensitive parsing, locale/Unicode boolean parsing, numeric boolean parsing, rich parse errors, source-authored std/result.slo bool wrappers, automatic std imports, compiler-loaded std source, runtime ABI/layout claims, manifest schema changes, or beta maturity
  • exp-35 does not add source-authored generic result helpers, std.result.map, generic std.result.unwrap_or, std.result.and_then, option helper names, broad result payload families, automatic std imports, compiler-loaded std source, source constructors for (result bool i32), general source match over (result bool i32) beyond compiler-supported fixture flow, runtime ABI/layout claims, manifest schema changes, or beta maturity
  • exp-36 does not add automatic std imports, repo-root std/ search, compiler-loaded std source, new compiler-known std.* runtime names, generic option helpers, option payload families beyond (option i32), option mapping/chaining helpers, stable standard-library APIs, runtime ABI/layout claims, manifest schema changes, or beta maturity
  • exp-37 does not add automatic std imports, repo-root std/ search, compiler-loaded std source, new compiler-known std.* runtime names, wall-clock/calendar/timezone APIs, high-resolution timers, async timers, cancellation, scheduling guarantees, stable standard-library APIs, runtime ABI/layout claims, manifest schema changes, or beta maturity
  • exp-38 does not add automatic std imports, repo-root std search, compiler-loaded std source, new compiler-known std.* runtime names, random seed/range/bytes/float/UUID/crypto APIs, environment mutation/ enumeration, binary/directory/streaming/async filesystem APIs, rich host error ADTs, runtime ABI/layout claims, manifest schema changes, or beta maturity
  • exp-39 does not add automatic std imports, repo-root std search, compiler-loaded std source, new compiler-known std.* runtime names, trigonometry, sqrt, pow, logarithms, modulo, bit operations, generic math, overloads, traits, mixed numeric arithmetic, optimizer guarantees, benchmark thresholds, runtime ABI/layout claims, manifest schema changes, or beta maturity
  • exp-20 does not add f32, i64/u64/u32/u16/u8/i16/i8, char, bytes, decimal, numeric casts, implicit promotion, mixed i32/f64 arithmetic, generic numeric operators, f64 arrays/vectors/options/results/enum payloads/ struct fields, mutable f64 locals, parse_f64, random floats, broader math library calls, stable NaN/infinity/rounding semantics, stable print formatting beyond newline-terminated output, stable ABI/layout, manifest schema changes, or beta maturity
  • exp-21 does not add f32, unsigned integers, narrower integer widths beyond the existing i32, char, bytes, decimal, numeric casts, implicit promotion, mixed i32/i64/f64 arithmetic, generic numeric operators, i64 arrays/vectors/options/results/enum payloads/struct fields, mutable i64 locals, random i64, broader math library calls, stable divide-by-zero or overflow diagnostics, stable ABI/layout, manifest schema changes, or beta maturity
  • exp-22 does not add implicit numeric promotion, mixed numeric arithmetic or comparison, narrowing or checked numeric conversions, cast syntax, f32, unsigned or narrower integer families, numeric parse/format APIs, stable floating rounding/formatting guarantees, stable ABI/layout, manifest schema changes, or beta maturity
  • exp-23 does not add implicit numeric promotion, cast syntax, std.num.cast, checked cast generics, mixed numeric operators, any narrowing conversion other than std.num.i64_to_i32_result, f64 conversions, unsigned or narrower integer families, numeric parse/format APIs, stable ABI/layout, manifest schema changes, or beta maturity
  • exp-24 does not add f64 formatting, parse APIs beyond the released i32/i64 result calls, locale/base/radix/grouping/padding controls, generic format/display traits, implicit conversions, stable standard-library implementation source, stable ABI/layout/ownership, manifest schema changes, or beta maturity
  • exp-25 does not add f64 parse, generic parse, leading +, whitespace trimming, underscores, base/radix prefixes, locale-aware parsing, Unicode digit parsing, rich parse errors, stable helper ABI/layout/ownership, manifest schema changes, or beta maturity
  • exp-26 does not add f32, f64 parse, generic format/display/ interpolation APIs, locale/base/radix/grouping/padding/precision controls, stable NaN/infinity text, implicit conversion, stable helper ABI/layout/ ownership, manifest schema changes, or beta maturity
  • exp-27 does not add unchecked f64 to i32, casts or cast syntax, generic cast_checked, f32, unsigned or narrower integer families, additional numeric conversion families, f64 parse, mixed numeric arithmetic, numeric containers, stable helper ABI/layout/ownership, manifest schema changes, or beta maturity
  • exp-28 does not add generic parse, bool/string/bytes parse, locale parsing, Unicode digit parsing, underscores, rich parse errors, stable helper ABI/layout/ownership, result genericity, f64 containers, mixed numeric arithmetic, manifest schema changes, or beta maturity

2. Compatibility Baseline

All Slovo v0 supported fixtures remain valid unless a future section explicitly defines a migration. Migration-level changes must follow MIGRATION_POLICY.md.

The v0 baseline includes:

  • modules
  • functions
  • top-level tests
  • i32 parameters and returns
  • direct (option i32) and (result i32 i32) constructor returns
  • local i32 let and var
  • set
  • +, =, and <
  • user calls
  • print_i32
  • value-producing if
  • first-pass while
  • first-pass structs with immediate field access
  • first-pass fixed i32 arrays and literal indexing
  • first-pass option/result constructors
  • lexical unsafe blocks for otherwise supported safe forms

3. v1 Release Gate

Slovo v1 is releasable only when:

  • every supported v1 feature is specified in this file
  • every supported v1 feature has a fixture under examples/supported/
  • formatter fixtures exist for every supported v1 surface form
  • Glagol keeps a golden machine-diagnostic fixture inventory for every current explicitly rejected v1 boundary
  • Glagol keeps textual lowering-inspector golden fixtures for every promoted v1 feature family named in section 9.5
  • speculative examples remain clearly separated from supported fixtures
  • Glagol implements every supported v1 form or rejects source-reachable unsupported forms with structured diagnostics
  • stable LLVM debug metadata, DWARF emission, and source-map files remain deferred; textual lowering-inspector fixtures are sufficient for v1
  • future features add diagnostic and lowering-inspector coverage before promotion
  • Slovo and Glagol roadmaps agree on support status
  • v0 compatibility fixtures still pass

4. Proposed v1 Priority Order

v1 should complete existing v0 value families before adding unrelated syntax.

Recommended order:

  1. Struct value flow
  2. Option/result value flow and observation
  3. Array value flow and dynamic indexing
  4. Runtime string contract
  5. Tooling contract improvements

The first accepted v1 slice is struct value flow. The second accepted v1 slice is option/result value flow and tag observation. The option/result payload access extension promotes explicit trap-based i32 extraction forms. The third accepted v1 slice is array value flow and dynamic indexing for fixed-size direct scalar arrays. The fourth accepted v1 slice is direct runtime string-literal printing through print_string. The fifth accepted v1 slice is the tooling contract for versioned machine diagnostics, textual artifact manifests, and LLVM/source-span direction. The v1.2 practical runtime values release extends the string slice conservatively and promotes print_bool without changing the v1.1 single-file CLI/toolchain assumptions. The v1.3 project-mode release adds flat local projects and explicit local modules without adding packages, dependencies, registries, version solving, workspaces, macros, public ABI, cross-package visibility, incremental builds, watch/LSP, path escapes, or generated code. The v1.4 core-language release promotes only source-level match for the existing (option i32), (option i64), (option f64), (option bool), (option string), and (result i32 i32) families without adding user-defined enums/ADTs, generic payloads, mutation, vectors, broad numeric expansion, ownership, or layout/ABI promises. The v1.5 standard library alpha promotes only compiler-known std.* source names for the existing print and string-length runtime behavior, without adding imports, packages, new data types, IO breadth, allocation, Unicode length semantics, or ABI promises. The v1.6 memory and unsafe design slice reserves raw unsafe operation heads for UnsafeRequired and UnsupportedUnsafeOperation gates without promoting raw-memory execution. The v1.7 developer experience hardening release adds only tooling contracts for scaffolding, formatter check/write modes, deterministic Markdown documentation generation, and a local release-gate script. v2.0.0-beta.1 promotes the integrated v1.1-v1.7 workflow as experimental-ready for small flat local projects without adding new source language syntax or semantics. The later 1.0.0-beta release is the first real general-purpose beta milestone. The released compiler-supported experimental steps are exp-1 owned runtime strings, exp-2 collections alpha, exp-3 host IO/environment, exp-4 payloadless user enums, exp-5 local packages/workspaces, exp-6 C FFI scalar imports alpha, exp-7 test selection/test-run metadata alpha, exp-8 host time/sleep alpha, exp-9 hardening, exp-10 result-based host errors, exp-11 basic randomness, and exp-12 standard input result alpha, and exp-13 string parse i32 result alpha. The current released conformance-alignment stage is exp-14 Standard Runtime Conformance Alignment over the exp-13 surface; it seeds documentation, fixture, and release-gate conformance without adding source syntax, type forms, runtime APIs, std.* names, manifest schema versions, ABI/layout promises, runtime headers/libraries, or beta maturity. exp-15 promotes only preferred std.result.* helper names for already supported concrete result families. These stages do not promote generic vectors, broader collections, broad host error ADTs, broad parsing, result mapping/chaining or generic result helpers, registries, version solving, package publishing, generics, user-visible deallocation, broad FFI, LSP, debug metadata, source maps, or stable ABI/layout promises.

Unsafe raw memory, FFI, pointers, allocation, unchecked indexing, and stable ABI/layout promises are no longer open v1 execution decisions. They remain deferred unless an explicit later promotion changes this file.

4.1 v1.3 Project Mode And Modules

Status: frozen v1.3 Slovo-side contract. Implementation support requires the matching Glagol v1.3 gates.

Project mode is selected only when glagol check, glagol test, or glagol build receives a project root containing slovo.toml or the manifest file itself. Passing one .slo file keeps the v1.2 single-file behavior unchanged.

The manifest is named exactly slovo.toml:

[project]
name = "example"
source_root = "src"
entry = "main"

project.name is required and must be an ASCII lowercase package-shaped identifier using a-z, 0-9, and -, starting with a-z. project.source_root is optional and defaults to src; it must be a relative path under the project root. project.entry is optional and defaults to main; it must be a flat module identifier. Unknown manifest sections or keys are diagnostics. Path escapes from the project root or source root remain outside v1.3.

v1.3 project modules are immediate .slo children of the source root. The module name is flat, the file stem must match the module declaration, and the project module set is every immediate .slo file in the source root.

The module declaration may include an explicit export list:

(module math (export add_one Point))

The only import form is:

(import math (add_one Point))

Import forms appear after the module declaration and before local struct, fn, and test declarations. Imported names are unqualified top-level names inside the importing module. v1.3 has no import aliases, glob imports, qualified access, or re-exports.

Only exported top-level fn and struct declarations are importable in the v1.3 baseline. The later exp-17 experimental contract extends the same export/import mechanism to top-level enum names in project and workspace modules. Top-level tests, local bindings, parameters, fields, module names as values, imported names, builtins, legacy compiler/runtime aliases, compiler-known standard-runtime names, generated declarations, and macro-expanded declarations are not exportable or importable.

Name resolution is local declarations, then explicit imported names, then builtins, legacy aliases, and compiler-known standard-runtime names. v1.3 rejects duplicate local names, duplicate import-list names, duplicate export-list names, and local/import collisions as DuplicateName. Importing the same unqualified name from two different modules is AmbiguousName at the later import name span; v1.3 does not defer that case to a later use-site.

Project operations are deterministic: source files are sorted lexicographically by UTF-8 byte order; graph validation uses topological order with lexicographic tie breaking; tests run by deterministic module order and source order within each module; artifact manifests list source files, modules, diagnostics, imports, and outputs deterministically.

Required project diagnostics are:

  • DuplicateName
  • MissingImport
  • ImportCycle
  • AmbiguousName
  • Visibility

Source-reachable multi-file diagnostics must include file identity, byte spans, line/column spans, and related spans for cross-file context. Project artifact manifests remain slovo.artifact-manifest version 1 and record project root, manifest path, source root, project name, entry module, modules, import edges, test counts when applicable, diagnostics counts, and build outputs.

v1.3 explicitly defers packages, dependencies, remote registries, version solving, lockfiles, workspaces, hierarchical modules, import aliases, glob imports, qualified access, re-exports, macros, public ABI, cross-package visibility, incremental builds, watch mode, LSP, SARIF, path escapes, generated code, project formatting, build profiles, cross-compilation, object output, library output, header output, stable debug metadata, DWARF, and standalone source-map files.

4.2 v1.4 Core Language Expansion

Status: frozen v1.4 Slovo-side contract. Implementation support requires the matching Glagol v1.4 gates.

v1.4 promotes source-level match for already-supported option/result values:

(match value
  ((some payload)
    payload)
  ((none)
    0))

(match value
  ((ok payload)
    payload)
  ((err code)
    code))

The only promoted match subject types are (option i32), (option i64), (option f64), (option bool), (option string), and (result i32 i32). An option match must cover exactly some and none; a result match must cover exactly ok and err. Duplicate arms are diagnostics. Arm order is preserved and does not change semantics.

The only promoted patterns are (some binding), (none), (ok binding), and (err binding). Payload bindings are immutable and scoped to the selected arm body only. A payload binding may not collide with a name visible at the match site or with a local introduced in the same arm body. Identical binding names in different arms are allowed because arm scopes are disjoint.

Each arm body contains one or more expressions. Non-final arm expressions are evaluated in source order, and the final expression is the arm value. v1.4 does not add a general (block ...) expression; match arms are the only new nested body context.

The match expression type is the common final-expression type of all arms. Arm type mismatches are diagnostics. The subject is evaluated once, only the selected arm body is evaluated, and matching does not use the trap-based unwrap_* runtime path.

Required match diagnostics are:

  • MatchSubjectTypeMismatch
  • UnsupportedMatchPayloadType
  • NonExhaustiveMatch
  • DuplicateMatchArm
  • MalformedMatchPattern
  • MatchArmTypeMismatch
  • MatchBindingCollision
  • UnsupportedMatchMutation
  • UnsupportedMatchContainer

Existing tag observers and unwrap_* forms remain supported, but new examples prefer match for payload-dependent option/result control flow.

The normative v1.4 release contract is .llm/V1_4_CORE_LANGUAGE_EXPANSION.md.

4.3 v1.5 Standard Library Alpha

Status: frozen v1.5 Slovo-side contract. Implementation support requires the matching Glagol v1.5 gates.

v1.5 promotes a conservative source-level standard-runtime namespace over existing v1.2 runtime behavior:

(std.io.print_i32 value)
(std.io.print_string value)
(std.io.print_bool value)
(std.string.len value)

These names are compiler-known v1.5 standard-runtime names. They do not require imports, do not name user modules, do not create package dependencies, and are not stable C ABI symbols.

The exact promoted signatures are:

  • std.io.print_i32: exactly one i32, returns builtin unit, same stdout behavior as legacy print_i32
  • std.io.print_string: exactly one string, returns builtin unit, same stdout behavior and string-literal constraints as legacy print_string
  • std.io.print_bool: exactly one bool, returns builtin unit, same stdout behavior as legacy print_bool
  • std.string.len: exactly one string, returns i32, same decoded-byte count semantics as legacy string_len

Existing legacy intrinsic names print_i32, print_string, print_bool, and string_len remain compatibility aliases. New examples prefer std.* names.

The promoted std.* names are reserved from user function/export shadowing. Unknown or unpromoted std.* calls must produce a structured diagnostic; the suggested code is UnsupportedStandardLibraryCall. Arity and type mismatches for promoted std.* calls should use the existing arity/type diagnostics where applicable.

v1.5 explicitly defers std.io.print_unit, file IO, environment variables, process arguments, time, vectors/collections, allocation, user-defined standard modules, imports/packages, overloading, generic APIs, Unicode length semantics, and ABI/layout promises.

The normative v1.5 release contract is .llm/V1_5_STANDARD_LIBRARY_ALPHA.md.

4.4 v1.7 Developer Experience Hardening

Status: frozen v1.7 Slovo-side contract. Implementation support requires the matching Glagol v1.7 gates.

v1.7 adds tooling contracts only. It does not add source language syntax, type-system behavior, runtime behavior, standard-runtime names, package management, dependency management, LSP support, stable debug metadata, DWARF, or stable source-map files.

glagol new <project-dir> [--name <name>] scaffolds a valid v1.3-style project with slovo.toml, src/main.slo, and a small testable main module using only already-supported language forms. It must fail without overwriting non-empty target directories.

glagol fmt <file.slo> remains stdout formatting. glagol fmt --check <file-or-project> checks canonical formatting without writing files. glagol fmt --write <file-or-project> writes canonical formatting for one file or for all immediate .slo project source modules in deterministic v1.3 module order. --check and --write are mutually exclusive.

glagol doc <file-or-project> -o <dir> generates deterministic Markdown documentation from current source structure: modules, imports/exports, structs, functions, and tests. It is a documentation generator, not a semantic reflection API, and it does not expose stable typed-core, debug metadata, source-map, ABI, layout, runtime reflection, or compiler-internal contracts.

As of 1.0.0-beta.11, glagol doc <file|project|workspace> -o <dir> also includes deterministic exported/public API sections for local packages and modules. These sections render exact exported function signatures, exported struct fields, and exported enum variants with payload types. They omit non-exported functions, structs, enums, tests, and aliases from the public API surface and normalize module-local concrete aliases before rendering public types.

glagol symbols <file.slo|project|workspace> emits deterministic machine-readable S-expression metadata using the slovo.symbols schema. It reports module paths, package labels when available, imports, exports, module-local type aliases, structs, enums, functions, tests, and source spans/ranges. It is an editor-integration building block, not an LSP server, watch protocol, semantic reflection API, debug metadata, source-map contract, ABI/layout promise, or stable compiler-internal contract.

The repository must provide a local release-gate script or documented command entry point that runs the full v1 release gate for the matching Slovo and Glagol release without network, tag, push, or release-publication side effects.

The normative v1.7 release contract is .llm/V1_7_DEVELOPER_EXPERIENCE_HARDENING.md.

4.4.1 Post-Beta Tooling Additions

1.0.0-beta.1 adds tooling-only conveniences after the 1.0.0-beta language baseline. These commands do not change source syntax or typed-core semantics.

glagol run <file.slo|project> builds through the same hosted native path as glagol build, writes an executable under .slovo/build by default, executes it, forwards stdout/stderr, and exits with the program exit status. -o <binary> may override the generated executable path.

glagol clean <file.slo|project> removes the generated .slovo/build directory for the given source file directory or project root. It does not remove custom -o build outputs.

glagol new <project-dir> --template binary|library|workspace supports three scaffold shapes. binary is the default project with src/main.slo. library creates a checkable/testable project with src/lib.slo. workspace creates a local two-package workspace using the existing [workspace], [package], and local path dependency rules.

scripts/install.sh installs the beta toolchain layout under a configurable prefix:

<prefix>/bin/glagol
<prefix>/share/slovo/std/*.slo
<prefix>/share/slovo/runtime/runtime.c

Installed glagol must discover the standard-library sources and runtime C input relative to its executable. SLOVO_STD_PATH remains the standard-library source override. SLOVO_RUNTIME_C and GLAGOL_RUNTIME_C may override the runtime C input for native builds.

4.4.2 Runtime Resource Foundation Additions

1.0.0-beta.2 adds the first beta resource-handle foundation for read-only text files. It does not change source syntax.

std.fs.open_text_read_result <path> has signature (string) -> (result i32 i32). Success returns ok handle, where handle is a positive opaque process-local i32. Ordinary open failure or handle-table exhaustion returns err 1.

std.fs.read_open_text_result <handle> has signature (i32) -> (result string i32). Success reads remaining text from the open handle and returns ok text. Invalid, closed, or failed reads return err 1.

std.fs.close_result <handle> has signature (i32) -> (result i32 i32). Success closes the handle and returns ok 0. Invalid, already closed, or failed close operations return err 1.

The same 1.0.0-beta.2 runtime foundation adds narrow filesystem status and mutation calls:

std.fs.exists: (string) -> bool
std.fs.is_file: (string) -> bool
std.fs.is_dir: (string) -> bool
std.fs.remove_file_result: (string) -> (result i32 i32)
std.fs.create_dir_result: (string) -> (result i32 i32)

exists, is_file, and is_dir collapse ordinary metadata failures to false. remove_file_result removes one file and create_dir_result creates one directory; both return ok 0 on success and err 1 on ordinary host failure.

Resource handles are beta values. They are not host file descriptors, stable ABI values, transferable capabilities, or ownership-checked affine values. Writable handles, binary IO, directory handles, directory enumeration, recursive filesystem operations, process handles, sockets, async/event-loop resources, rich host-error ADTs, platform-specific error codes, finalizers, destructors, and automatic cleanup remain deferred.

4.4.3 Post-Beta Package And Workspace Discipline Additions

The package/workspace discipline slice keeps the existing closed local workspace model from exp-5 and adds one beta manifest key:

[workspace]
members = ["packages/app", "packages/tool"]
default_package = "app"

default_package is optional. When absent, glagol build and glagol run continue to require exactly one workspace package whose configured entry module exists. When present, the named package is the selected build/run entry package. The named package must be a workspace package, and build/run require that package to contain its configured entry module.

Workspace member paths are normalized under the workspace root before package loading. Duplicate normalized member paths are invalid, even if they were spelled differently in the manifest.

glagol doc <workspace> -o <dir> documents the workspace graph in addition to module structure. The generated index.md includes deterministic lists of workspace members, packages, and local package dependency edges before the module sections.

This slice does not add remote registries, lockfiles, semantic-version solving, package publishing, archive formats, optional/dev/target dependencies, feature flags, package build scripts, or stable package ABI/layout promises.

1.0.0-beta.11 extends the generated local-package documentation surface, but not the package model itself. glagol doc <file|project|workspace> -o <dir> includes deterministic exported/public API sections for local modules and workspace packages:

  • exported functions are rendered with exact parameter and return types
  • exported structs are rendered with exported field names and field types
  • exported enums are rendered with exported variant names and payload types
  • non-exported functions, structs, enums, tests, and (type ...) aliases are excluded from the public API sections
  • module-local concrete aliases are normalized to their concrete public target types before rendering

The generated Markdown remains a beta documentation format. This does not define a stable Markdown schema, stable stdlib/API compatibility freeze, LSP/watch behavior, SARIF or daemon protocols, diagnostics schema policy, executable generics, maps/sets, re-exports, glob imports, hierarchical modules, registry semantics, runtime behavior, or stable ABI/layout.

4.4.4 Post-Beta Networking Foundation

Status: released in 1.0.0-beta.6.

The 1.0.0-beta.6 networking foundation stages blocking loopback TCP only. It does not change source syntax.

The source facade is lib/std/net.slo, imported explicitly as std.net:

std.net.tcp_connect_loopback_result: (i32) -> (result i32 i32)
std.net.tcp_listen_loopback_result: (i32) -> (result i32 i32)
std.net.tcp_bound_port_result: (i32) -> (result i32 i32)
std.net.tcp_accept_result: (i32) -> (result i32 i32)
std.net.tcp_read_all_result: (i32) -> (result string i32)
std.net.tcp_write_text_result: (i32 string) -> (result i32 i32)
std.net.tcp_close_result: (i32) -> (result i32 i32)

Successful connect/listen/accept operations return ok handle, where handle is a positive opaque process-local i32. Successful tcp_bound_port_result returns the bound loopback TCP port. Successful tcp_write_text_result and tcp_close_result return ok 0. Ordinary host failures return err 1.

The source facade also provides tcp_write_text_ok and tcp_close_ok, both ordinary source helpers over the result-returning operations.

This release is not a general networking contract. DNS, TLS, UDP, Unix-domain sockets, non-loopback binding, async IO, event loops, readiness polling, timeouts, buffering policy, HTTP frameworks, platform-specific error codes, rich host-error ADTs, stable runtime helper symbols, stable socket ABI/layout, automatic cleanup, and affine ownership guarantees remain deferred.

4.4.5 Post-Beta Serialization Foundation

Status: released in 1.0.0-beta.7.

The 1.0.0-beta.7 serialization foundation stages compact JSON text construction only. It does not change source syntax.

The source facade is lib/std/json.slo, imported explicitly as std.json. It exposes:

std.json.quote_string: (string) -> string
std.json.null_value: () -> string
std.json.bool_value: (bool) -> string
std.json.i32_value/u32_value/i64_value/u64_value/f64_value
std.json.parse_string_value_result: (string) -> (result string i32)
std.json.parse_bool_value_result: (string) -> (result bool i32)
std.json.parse_i32_value_result/parse_u32_value_result/parse_i64_value_result/parse_u64_value_result/parse_f64_value_result
std.json.parse_null_value_result: (string) -> (result bool i32)
std.json.field_string/field_bool/field_i32/field_u32/field_i64/field_u64/field_f64/field_null
std.json.array0/array1/array2/array3
std.json.object0/object1/object2/object3

quote_string is backed by a compiler-known runtime helper so JSON string escaping is deterministic even before Slovo has source-visible byte or character iteration. It returns a complete compact JSON string literal, including surrounding quotes. The source helpers compose already-encoded JSON fragments with compact comma/colon separators.

The Slovo-facing 1.0.0-beta.17 JSON foundation adds primitive scalar token parse facades only: exact boolean and numeric primitive token conversion through concrete (result ... i32) values, plus parse_null_value_result returning ok true only for exact null and err 1 otherwise. Numeric and boolean parse helpers consume one isolated JSON primitive token: no leading/trailing whitespace, no leading +, no leading-zero integer form except 0, and no non-finite f64 values.

The 1.0.0-beta.18 JSON foundation adds parse_string_value_result for one already-isolated ASCII JSON string token. The token must start and end with quotes and contain no leading or trailing whitespace. It decodes the simple JSON escapes \", \\, \/, \b, \f, \n, \r, and \t. It rejects raw control bytes, bad escapes, unterminated or trailing bytes, raw non-ASCII, and all \uXXXX escapes for this slice.

This is not a complete JSON or serialization contract. JSON parsing beyond the single ASCII string-token helper, object/array parsing, recursive JSON values, maps/sets, generic collections, tokenizer objects, streaming decoders or encoders, schema validation, Unicode escape decoding or normalization, embedded NUL policy, stable text encoding policy beyond the current null-terminated runtime string ABI, stable runtime helper symbols, and stable standard-library API guarantees remain deferred.

4.4.6 Post-Beta Concrete Type Alias Foundation

Status: released in 1.0.0-beta.8 with matching Glagol parser, checker, formatter, diagnostics, fixture, documentation, and promotion gates.

1.0.0-beta.8 promotes transparent aliases for existing concrete type forms:

(type JsonText string)
(type Scores (vec i32))
(type MaybeName (option string))
(type ReadResult (result string i32))

The declaration form is exactly (type Alias TargetType) at top level. Alias must be a single user type name. TargetType must resolve to an already supported concrete Slovo type: direct scalar and string types, current fixed array families, current concrete vec families, current concrete option/result families, current known struct names, or current enum names where that type is already legal in the use position.

Aliases are transparent. Using Alias in a type position is equivalent to using its resolved target type. The resolved target controls value flow, operators, constructors, match, field access, imports of functions that use the type, lowering, runtime behavior, and diagnostics. The alias does not create a nominal type, wrapper, cast, runtime tag, layout name, hosted symbol, or C ABI boundary.

Alias declarations are module-local. They may be used by later declarations in the same module and by exported functions or structs after normalization, but the alias name itself is not exportable, importable, or re-exportable. A module that imports a function whose signature used a local alias sees the normalized concrete target type, not the alias name.

Name resolution for type positions checks local concrete aliases alongside local struct and enum type names before applying builtin/concrete type forms. Duplicate alias, struct, enum, function, import-list, export-list, local, or parameter names remain diagnostics under the existing duplicate-name policy. Aliases must not shadow builtins, compiler-known standard-runtime names, or reserved unsafe heads.

Formatter output keeps aliases as one-line top-level declarations:

(type JsonText string)

An alias target that is already a parenthesized concrete type form stays inline, for example (type JsonItems (vec string)). Comments are allowed around the top-level alias declaration under the existing full-line comment rules, not inside the declaration form.

Required diagnostics include malformed alias declarations, duplicate alias names, unknown target types, unsupported target types, cyclic aliases, parameterized alias attempts, exported aliases, imported aliases, and cross-module alias references. An implementation may use precise diagnostic codes, but it must not silently treat an alias as string, i32, or any other fallback type after a failed resolution.

This target explicitly does not add generic aliases, parameterized aliases, alias type parameters, higher-kinded aliases, alias re-exports, cross-module alias imports, import aliases, glob imports, maps/sets, alias-driven overloads, implicit casts, new runtime helpers, standard-runtime names, stable ABI/layout promises, or a stable standard-library API freeze.

4.4.7 Post-Beta Collection Alias Unification And Generic Reservation

Status: released in 1.0.0-beta.9 as a Slovo stdlib/docs contract update on top of the beta.8 alias semantics.

1.0.0-beta.9 applies beta.8 concrete aliases to the source-authored collection/value-family facades where they remove repeated concrete type spellings:

  • std.vec_i32, std.vec_i64, std.vec_f64, std.vec_bool, and std.vec_string use one module-local alias for their concrete vector family.
  • std.option and std.result use module-local aliases for the current concrete option/result helper families.

These aliases are not public standard-library API names. They are normalized to their concrete targets for imports, typed-core lowering, backend layout, ABI decisions, runtime behavior, and generated cross-module signatures. Current vectors, options, and results remain concrete families such as (vec bool), (option string), and (result u64 i32).

This target reserves generic and collection-unification spelling space through diagnostics and documentation only. It does not add executable generics, generic aliases, parameterized aliases, maps, sets, traits, inference, monomorphization, iterators, new runtime helpers, stable ABI/layout promises, or a stable standard-library API freeze.

4.4.8 Post-Beta Local Package API Documentation

Status: released in 1.0.0-beta.11 as a documentation/API-discovery update on top of the beta.10 discovery lane.

1.0.0-beta.11 extends glagol doc <file|project|workspace> -o <dir> so the generated Markdown includes deterministic exported/public API sections for local source files, projects, packages, and workspaces. The public API surface is derived from explicit module exports and local package boundaries.

The public API sections include:

  • exact exported function signatures, including parameter names, parameter types, and return types
  • exported struct field names and field types
  • exported enum variant names and payload types, including payloadless variants and current single-payload variants
  • deterministic ordering that follows the existing module/package documentation ordering

Non-exported functions, structs, enums, tests, and (type ...) aliases are not part of the public API sections. A declaration can still appear in other source-structure summaries when those summaries already exist, but it must not be presented as exported/public API unless the module export list exposes it.

Module-local concrete aliases are normalized before public rendering. Public docs show concrete target types such as (vec i32), (option string), and (result u64 i32) rather than private alias names introduced by the documented module. This mirrors beta.10 lib/std catalog behavior for local packages and modules.

This is not a stable documentation schema. It does not freeze Markdown headings, anchors, file names, machine parsing contracts, stable stdlib/API compatibility freeze, LSP/watch behavior, SARIF or daemon protocols, diagnostics schema policy, executable generics, maps/sets, re-exports, glob imports, hierarchical modules, registry semantics, runtime behavior, package ABI, or layout.

4.4.9 Post-Beta Concrete Vector Query And Prefix Parity

Status: released in 1.0.0-beta.12 as a source-authored stdlib/helper parity update on the existing concrete vector surface.

1.0.0-beta.12 closes narrow helper gaps in the concrete vector facades:

  • std.vec_i64 exports count_of, starts_with, without_prefix, ends_with, and without_suffix.
  • std.vec_f64 exports count_of.

The helpers are ordinary Slovo source helpers. They build on the existing compiler-known concrete vector runtime names, equality, len, at, and already staged source helpers such as take and drop. They do not add new source-language syntax, typed-core forms, runtime calls, compiler-known stdlib names, ABI/layout commitments, or performance guarantees.

The helper semantics follow the existing concrete vector family conventions: count_of(values,target) returns the number of elements equal to target; starts_with(values,prefix) and ends_with(values,suffix) accept empty, exact, and shorter matching vectors and reject longer or mismatched vectors; without_prefix and without_suffix return the original vector when the prefix/suffix does not match and return the remaining vector when it does.

This target explicitly does not add executable generics, generic vector dispatch, maps, sets, iterators, mutable vectors, slice/view APIs, new runtime names, stable ABI/layout promises, performance claims, or a stable stdlib API freeze.

4.4.10 Post-Beta Diagnostic Catalog And Schema Policy

Status: released in 1.0.0-beta.13 as a docs/tooling policy update for the existing diagnostic surface.

1.0.0-beta.13 adds docs/language/DIAGNOSTICS.md as the central beta policy for slovo.diagnostic version 1. The document records the S-expression and JSON encodings, source-attached and source-less diagnostic field rules, severity/source/range/related-span semantics, JSON-line discipline, artifact-manifest diagnostic metadata, diagnostic compatibility classes, and the current golden diagnostic code catalog.

The source language, typed core, runtime, standard library, compiler-known runtime names, ABI/layout behavior, CLI behavior, and diagnostic output shape are unchanged by this target. Human-readable diagnostic prose remains beta-flexible; schema names, versions, machine fields, diagnostic codes, source span/range semantics, JSON-line discipline, and golden fixture shape change only intentionally through the documented migration policy.

This target explicitly does not add LSP/watch behavior, SARIF output, daemon protocols, stable Markdown schema, stable 1.0.0 diagnostics freeze, source-map/debug-metadata contracts, localized diagnostic text, automated machine fix-its, or a compiler-emitted diagnostic catalog artifact.

4.4.11 Post-Beta Benchmark Suite Catalog And Metadata Gate

Status: released in 1.0.0-beta.14 as a docs/tooling metadata update for the existing benchmark suite.

1.0.0-beta.14 adds benchmarks/README.md as the top-level benchmark suite catalog. The catalog records the current suite inventory, base/hot-loop checksum metadata, local evidence policy, and explicit exclusions.

The root suite-list commands are documented as:

python3 benchmarks/runner.py --suite-list
python3 benchmarks/runner.py --suite-list --json

The non-JSON listing is local review output. The JSON listing is beta tooling metadata for local gates and adapters. The field set is intentionally not a stable public schema in this release.

The source language, typed core, runtime, standard library, public API surface, compiler diagnostics, diagnostic output shape, compiler-known runtime names, ABI/layout behavior, and optimizer contract are unchanged by this target. Benchmark timings remain local-machine evidence only and no timing numbers are published by the release contract.

This target explicitly does not add benchmark kernels, implementation language slots, timing publication, performance thresholds, cross-machine performance claims, a stable benchmark JSON schema, source-language/runtime/stdlib/API changes, diagnostic-output changes, or ABI/layout guarantees.

4.4.12 Post-Beta Reserved Generic Collection Boundary Hardening And Collection Ledger

Status: released in 1.0.0-beta.15 as a docs/design ledger and compiler-boundary hardening update for the existing concrete collection and value-family surface.

1.0.0-beta.15 adds docs/language/COLLECTIONS.md as the public collection ledger. The ledger links to the generated docs/language/STDLIB_API.md catalog for exact exported standard-library helper signatures instead of duplicating generated counts.

The ledger inventories the current concrete vector, option, result, and related option/result-returning facade surfaces. It records design pressure from duplicated concrete vector/option/result helper families and defines prerequisites before executable generics, generic aliases, maps, sets, iterators, mutable vectors, or slice/view APIs can be promoted.

Current unsupported diagnostics are documented as boundaries of the existing beta surface. This target does not add, remove, rename, or reclassify diagnostic codes and does not change the slovo.diagnostic schema, diagnostic output shape, golden fixture shape, or human-readable diagnostic prose policy. It does intentionally reword affected reserved-boundary messages from beta.9-specific text to current-beta wording while preserving diagnostic codes, schema, spans, expected/found values, hints, and output shape.

The source language, typed core, runtime, standard library, public API surface, benchmark metadata schema, compiler-known runtime names, ABI/layout behavior, optimizer contract, and performance claims are unchanged by this target. This target explicitly does not add executable generics, generic aliases, parameterized aliases, maps, sets, generic stdlib dispatch, iterators, mutable vectors, slice/view APIs, new runtime names, or a stable stdlib/API freeze.

4.4.13 Post-Beta String Scanning And Token Boundary Foundation

Status: released in 1.0.0-beta.16 as a byte-oriented string scanning and token-boundary foundation over the existing runtime string representation.

1.0.0-beta.16 adds these std.string helpers:

  • byte_at_result ((value string) (index i32)) -> (result i32 i32)
  • slice_result ((value string) (start i32) (count i32)) -> (result string i32)
  • starts_with ((value string) (prefix string)) -> bool
  • ends_with ((value string) (suffix string)) -> bool

The helpers operate on bytes before the trailing NUL in the current NUL-terminated runtime string representation. byte_at_result returns ok with the byte value as i32 for valid zero-based byte indexes and returns err 1 for invalid indexes. slice_result returns ok with a runtime-owned string for valid byte ranges and returns err 1 for invalid ranges. Allocation failure while creating the substring may follow the existing string allocation trap policy.

starts_with and ends_with compare byte prefixes and suffixes. Empty prefixes and empty suffixes match. No helper performs Unicode normalization, grapheme segmentation, display-width measurement, locale-sensitive matching, or case-folding.

This target does not add full JSON parsing, object/array parsing, tokenizer or scanner objects, language slice/view syntax or borrowed substring views, mutable strings, string containers, stable runtime ABI/layout, performance claims, or a stable standard-library/API freeze.

4.5 v2.0.0-beta.1 Experimental Integration Readiness

Status: current experimental Slovo-side release contract, released 2026-05-17. Implementation support requires the matching Glagol experimental gate.

v2.0.0-beta.1 is an experimental integration/readiness release based on v1.7. It makes the accumulated v1.1-v1.7 surface supported for small real flat local projects using glagol new, glagol check, glagol fmt --check, glagol fmt --write, glagol test, glagol build, glagol doc, artifact manifests, JSON diagnostics, and the release-gate script.

The experimental language surface is exactly the gate-proven v1.1-v1.7 surface: i32, bool, builtin internal unit, tests, locals, if, while, structs, fixed direct scalar and fixed string arrays with checked indexing, string value flow, option/result values and the exact v1.4 match slice, standard-runtime alpha names, and the v1.6 lexical unsafe boundary with reserved unsafe heads.

Basic IO is limited to std.io.print_i32, std.io.print_string, std.io.print_bool, and std.string.len. File IO, environment variables, process arguments, time, broader runtime IO, vectors, growable collections, stable ABI/layout, FFI, raw-memory execution, LSP, stable debug metadata, stable source-map files, and package registries remain future post-beta work.

Vectors and other growable collections are not required for this experimental release unless they are separately implemented and gate-proven in Glagol. Fixed direct scalar arrays with checked indexing satisfy the experimental gate because this release is an integration milestone, while growable collections require allocation, ownership/lifetime, mutation, capacity, diagnostics, lowering, runtime tests, and docs that remain future post-beta work.

The normative experimental release contract is .llm/V2_0_0_BETA_1_RELEASE_CONTRACT.md.

4.6 exp-1 Owned Runtime Strings

Status: current experimental compiler-supported contract after matching Glagol exp-1 gates.

exp-1 promotes exactly one new standard-runtime string operation:

(std.string.concat left right)

The signature is:

std.string.concat: (string, string) -> string

The result is an immutable runtime-owned string whose decoded byte sequence is the left operand followed by the right operand. Existing string equality, std.string.len, std.io.print_string, string locals, string parameters, string returns, and calls returning string apply to both literal-backed strings and runtime-owned strings.

std.string.concat is compiler-known. It requires no import, does not name a user module, does not create a package dependency, and is not a stable C ABI symbol. No legacy string_concat alias is introduced.

The compiler/runtime owns cleanup for runtime-owned strings. Cleanup timing, allocator choice, runtime helper names, object layout, and pointer representation are not source-visible and are not stable ABI/layout promises. Safe Slovo code cannot manually free, retain, borrow, or mutate a string.

Allocation failure traps with:

slovo runtime error: string allocation failed

The message is written to stderr with a trailing newline and the process exits with code 1.

The exact std.string.concat name is reserved from user function, export, import, local, and parameter shadowing. Unknown or unpromoted std.* calls continue to use structured standard-library diagnostics.

exp-1 explicitly defers mutable strings, string containers, string indexing, string slicing, interpolation, formatting APIs, user-visible deallocation, file IO, packages, generics, growable collections, raw-memory execution, FFI, and stable ABI/layout promises.

The normative exp-1 contract is .llm/EXP_1_OWNED_RUNTIME_STRINGS.md.

4.7 exp-2 Collections Alpha

Status: current experimental compiler-supported contract after matching Glagol exp-103 gates.

exp-2 promotes one concrete growable vector type, and exp-94 extends the slice with exactly one additional concrete growable vector type. exp-99 extends the same slice with one more concrete growable vector type, and exp-103 extends it again with one more concrete growable vector type:

(vec i32)
(vec f64)
(vec i64)
(vec string)

Together the slice promotes exactly sixteen compiler-known standard-runtime operations:

std.vec.i32.empty: () -> (vec i32)
std.vec.i32.append: ((vec i32), i32) -> (vec i32)
std.vec.i32.len: ((vec i32)) -> i32
std.vec.i32.index: ((vec i32), i32) -> i32
std.vec.f64.empty: () -> (vec f64)
std.vec.f64.append: ((vec f64), f64) -> (vec f64)
std.vec.f64.len: ((vec f64)) -> i32
std.vec.f64.index: ((vec f64), i32) -> f64
std.vec.i64.empty: () -> (vec i64)
std.vec.i64.append: ((vec i64), i64) -> (vec i64)
std.vec.i64.len: ((vec i64)) -> i32
std.vec.i64.index: ((vec i64), i32) -> i64
std.vec.string.empty: () -> (vec string)
std.vec.string.append: ((vec string), string) -> (vec string)
std.vec.string.len: ((vec string)) -> i32
std.vec.string.index: ((vec string), i32) -> string

The source call forms are:

(std.vec.i32.empty)
(std.vec.i32.append values value)
(std.vec.i32.len values)
(std.vec.i32.index values index)
(std.vec.f64.empty)
(std.vec.f64.append values value)
(std.vec.f64.len values)
(std.vec.f64.index values index)
(std.vec.i64.empty)
(std.vec.i64.append values value)
(std.vec.i64.len values)
(std.vec.i64.index values index)
(std.vec.string.empty)
(std.vec.string.append values value)
(std.vec.string.len values)
(std.vec.string.index values index)

An exp-2 (vec i32), exp-94 (vec i64), exp-99 (vec string), and exp-103 (vec f64) are immutable runtime-owned vectors. They may flow through immutable let locals, parameters, returns, calls returning the same vector family, and top-level tests. std.vec.i32.append returns a new immutable runtime-owned vector containing the input vector's elements followed by the appended i32; it must not mutate the input vector. std.vec.i64.append returns a new immutable runtime-owned vector containing the input vector's elements followed by the appended i64; it must not mutate the input vector. std.vec.f64.append returns a new immutable runtime-owned vector containing the input vector's elements followed by the appended f64; it must not mutate the input vector. std.vec.string.append returns a new immutable runtime-owned vector containing the input vector's elements followed by the appended string; it must not mutate the input vector. std.vec.i32.len, std.vec.i64.len, std.vec.f64.len, and std.vec.string.len return vector length as i32. std.vec.i32.index returns an i32 element, std.vec.i64.index returns an i64 element, std.vec.f64.index returns an f64 element, and std.vec.string.index returns a string element, after the same runtime bounds check equivalent to 0 <= index && index < len.

Vector equality uses = with either two (vec i32) operands, two (vec i64) operands, two (vec f64) operands, or two (vec string) operands, returns bool, and compares length and element values in order. It is not pointer identity, allocation identity, capacity equality, or layout equality.

Allocation failure traps with:

slovo runtime error: vector allocation failed

Index failure traps with:

slovo runtime error: vector index out of bounds

Both messages are written to stderr with a trailing newline and exit the process with code 1.

The std.vec.i32.*, std.vec.i64.*, std.vec.f64.*, std.vec.bool.*, and std.vec.string.* names are compiler-known. They require no import, do not name user modules, do not create package dependencies, and are not stable C ABI symbols or stable runtime helper symbols. The exact promoted names are reserved from user function, export, import, local, and parameter shadowing.

The latest released Slovo-side concrete collection helper target is 1.0.0-beta.12, Concrete Vector Query And Prefix Parity. It broadens std/vec_i64.slo with count_of, starts_with, without_prefix, ends_with, and without_suffix, and broadens std/vec_f64.slo with count_of. The helper lanes stay source-authored, recursive, immutable, and limited to the already promoted concrete vector runtime names. They do not widen the promoted collection runtime surface or add new compiler-known names.

The collections alpha slice explicitly defers generic vectors, vector element types other than i32, i64, f64, bool, and string, vector mutation, mutable vector operations beyond whole-value var/set already promoted for current concrete vectors, vector literals besides empty/append construction, a push alias, nested vectors, vectors in arrays, vectors in structs, vectors in options, vectors in results, iterators, slices/views, maps, sets, user-visible deallocation, new runtime names, stable ABI/layout/helper-symbol promises, performance claims, package expansion, stable stdlib API freeze, and IO expansion.

The collection fixture targets are:

examples/supported/vec-i32.slo
examples/formatter/vec-i32.slo
examples/supported/vec-bool.slo
examples/formatter/vec-bool.slo
examples/supported/vec-i64.slo
examples/formatter/vec-i64.slo
examples/supported/vec-string.slo
examples/formatter/vec-string.slo

They are current compiler-supported fixtures.

The normative contracts are .llm/EXP_2_COLLECTIONS_ALPHA.md and .llm/EXP_94_STANDARD_VEC_I64_BASELINE_ALPHA.md plus .llm/EXP_99_STANDARD_VEC_STRING_BASELINE_ALPHA.md.

4.8 exp-3 Standard IO And Host Environment

Status: current experimental compiler-supported contract after matching Glagol exp-3 gates.

exp-3 promotes exactly six compiler-known host functions:

std.io.eprint: (string) -> unit
std.process.argc: () -> i32
std.process.arg: (i32) -> string
std.env.get: (string) -> string
std.fs.read_text: (string) -> string
std.fs.write_text: (string string) -> i32

The source call forms are:

(std.io.eprint value)
(std.process.argc)
(std.process.arg index)
(std.env.get name)
(std.fs.read_text path)
(std.fs.write_text path text)

std.io.eprint writes the string to stderr without appending a newline and returns builtin unit. std.process.argc returns the process argument count as i32. std.process.arg uses zero-based indexing and returns a string. Out-of-range argument access traps with:

slovo runtime error: process argument index out of bounds

std.env.get returns the environment variable value as string; a missing variable returns the empty string in exp-3.

std.fs.read_text reads a whole text file and returns string. Host read failure traps with:

slovo runtime error: file read failed

std.fs.write_text writes a whole string to a path and returns 0 on success or 1 on host failure.

The trap messages are written to stderr with a trailing newline and exit with code 1. Strings returned by process, environment, and file APIs are immutable runtime-provided strings. exp-3 does not promise whether host strings are copied, borrowed from host process storage, or allocated by private runtime helpers; source code cannot observe storage identity or cleanup timing. File read allocation failure is reported through the exp-3 file-read trap in this stage.

The promoted names are compiler-known. They require no import, do not name user modules, do not create package dependencies, and are not stable C ABI symbols or stable runtime helper symbols. The exact promoted names are reserved from user function, export, import, local, and parameter shadowing.

exp-3 explicitly defers networking, async IO, binary file APIs, directory traversal, terminal control, platform abstraction, general host error ADTs, result string Error, package interaction, stdin full read or line iteration, randomness, time, stable ABI/layout, and stable runtime helper symbols.

The exp-3 fixtures are:

examples/supported/host-io.slo
examples/formatter/host-io.slo

They are current compiler-supported fixtures.

The normative exp-3 contract is .llm/EXP_3_STANDARD_IO_HOST_ENV.md.

4.9 exp-4 User Data Types And Polymorphism

Status: current experimental compiler-supported contract after matching Glagol exp-4 gates.

exp-4 promotes payloadless user-defined enum declarations only:

(enum Name VariantA VariantB)

An enum declaration must have at least one variant. Variant values are constructed through zero-argument qualified calls:

(Name.VariantA)

An exp-4 enum value may flow through immutable let locals, parameters, returns, calls returning the enum type, equality with =, and top-level tests. Enum equality is defined only for two values of the same enum type and compares variant identity.

match supports enum subjects with exhaustive payloadless variant arms:

(match value
  ((Name.VariantA)
    body...)
  ((Name.VariantB)
    body...))

Every variant of the subject enum must appear exactly once. Enum match arms have one or more expression bodies, and the final expression of each arm must share a common result type, following the existing option/result match rule.

The runtime/backend representation is compiler-owned. exp-4 makes no stable layout, discriminant value, ABI, helper-symbol, reflection, or conversion to i32 promise.

exp-4 explicitly defers payload variants, tuple variants, record variants, generic enums, generic functions, type aliases, traits, interfaces, protocols, methods, derives, variant payload binding, wildcard patterns, rest patterns, guards, nested patterns, enum values in arrays, enum values in struct fields, enum values in options, enum values in results, enum values in vectors, enum mutation, enum printing, enum ordering, enum hashing, reflection, explicit discriminants, enum constructors with arguments, unqualified variant constructors, stable ABI/layout, stable helper symbols, and moving option/result to ordinary standard-library types.

The exp-4 fixtures are:

examples/supported/enum-basic.slo
examples/formatter/enum-basic.slo

They are current compiler-supported fixtures.

The normative exp-4 contract is .llm/EXP_4_USER_ADTS_ALPHA.md.

4.9.1 exp-16 Unary I32 Enum Payloads Alpha

Status: released experimental Slovo contract. Matching Glagol exp-16 gates are required before broader compiler-support claims.

exp-16 extends user-defined enum declarations to allow payloadless variants and unary i32 payload variants in the same enum:

(enum Reading
  Missing
  (Value i32)
  (Offset i32))

Payloadless variants continue to use zero-argument qualified constructors:

(Reading.Missing)

Payload variants use qualified constructors with exactly one i32 argument:

(Reading.Value value)

Enum values may flow through immutable locals, parameters, returns, calls, top-level tests, and main.

match supports exhaustive arms for both payloadless and unary payload variants:

(match reading
  ((Reading.Missing)
    0)
  ((Reading.Value payload)
    payload))

Payload variants require exactly one binding in match arms. Payloadless variants take no binding. Payload bindings are immutable names scoped only to the selected arm body.

Enum equality is defined only for two values of the same enum type. Payload variants compare by tag and payload value. Payloadless variants compare by tag.

The runtime/backend representation is compiler-owned. exp-16 makes no stable layout, discriminant value, ABI, helper-symbol, reflection, printing, hashing, ordering, or conversion to i32 promise.

exp-16 explicitly defers payload types other than i32, multiple payloads, record variants, tuple variants beyond one i32, string/bool/struct/enum payloads, generic enums, generic functions, type aliases, traits, methods, derives, wildcard/rest/nested enum patterns, pattern guards, enum payload mutation, enum values inside arrays/structs/options/results/vectors, enum printing/ordering/hash/reflection/discriminants/stable ABI/layout, moving option/result to ordinary standard-library types, manifest schema changes, runtime ABI/layout claims, and beta maturity.

The exp-16 fixtures are:

examples/supported/enum-payload-i32.slo
examples/formatter/enum-payload-i32.slo

The normative exp-16 contract is .llm/EXP_16_UNARY_I32_ENUM_PAYLOADS_ALPHA.md.

4.9.2 exp-17 Project Enum Imports Alpha

Status: released experimental Slovo contract. Matching Glagol exp-17 gates are required before broader compiler-support claims.

exp-17 extends explicit project and workspace module boundaries so export lists may include top-level enum names:

(module readings (export Reading))

Import lists may import those exported enum names:

(import readings (Reading))

In exp-5 workspace packages, the existing package-qualified module import form may also import exported enum names from direct local dependencies:

(import sensors.readings (Reading))

Imported enum types may be used in function signatures, immutable local type annotations, calls/returns, same-enum equality, exhaustive enum matches, and qualified constructors.

The enum surface is exactly the exp-4 payloadless enum surface plus the exp-16 unary i32 payload enum surface. No other payload types, generic enums, containers, mutation, printing, ordering, hashing, reflection, stable ABI/layout, manifest schema changes, registry/package-manager behavior, or beta maturity are added.

The exp-17 project fixture is:

examples/projects/enum-imports/slovo.toml
examples/projects/enum-imports/src/readings.slo
examples/projects/enum-imports/src/main.slo

No formatter project fixture is defined because the current Slovo formatter fixture convention is single-file fixtures under examples/formatter/, not whole project directories.

The normative exp-17 contract is .llm/EXP_17_PROJECT_ENUM_IMPORTS_ALPHA.md.

4.9.3 exp-18 Enum Struct Fields Alpha

Status: released experimental Slovo contract. Matching Glagol exp-18 gates are required before broader compiler-support claims.

exp-18 extends struct field declarations so field types may be current user-defined enum type names:

(enum Status Ready Blocked)

(enum Reading
  Missing
  (Value i32))

(struct TaggedReading
  (status Status)
  (reading Reading))

Struct construction uses the existing field initializer form, with enum values provided through the already promoted qualified enum constructors:

(TaggedReading (status (Status.Ready)) (reading (Reading.Value payload)))

Field access through an enum-typed field returns the declared enum type:

(. tagged reading)

That field access expression may be used in same-enum equality and exhaustive enum match:

(= (. tagged status) (Status.Ready))

(match (. tagged reading)
  ((Reading.Missing)
    0)
  ((Reading.Value payload)
    payload))

The enum field surface is exactly the exp-4 payloadless enum surface plus the exp-16 unary i32 payload enum surface. Enum-typed struct fields may flow through struct construction, immutable struct locals, struct parameters, struct returns, calls returning structs, field access, top-level tests, and main.

exp-18 does not add enum payload types other than i32, multiple payloads, record variants, tuple variants beyond one i32, enum values inside arrays, options, results, or vectors, arrays/options/results/vectors containing enum-typed structs, nested structs, struct mutation, enum mutation, printing, ordering, hashing, reflection, import aliases/globs/re-exports, manifest schema changes, package-manager behavior, stable ABI/layout, generics, or beta maturity.

The exp-18 fixtures are:

examples/supported/enum-struct-fields.slo
examples/formatter/enum-struct-fields.slo

The normative exp-18 contract is .llm/EXP_18_ENUM_STRUCT_FIELDS_ALPHA.md.

4.9.4 exp-19 Primitive Struct Fields Alpha

Status: released experimental Slovo contract. Matching Glagol exp-19 gates are required before broader compiler-support claims.

exp-19 extends struct field declarations so field types may be direct bool and immutable string, alongside already supported direct i32 and exp-18 enum fields:

(struct PrimitiveRecord
  (id i32)
  (active bool)
  (label string))

Struct construction uses the existing field initializer form:

(PrimitiveRecord (id id) (active (= id 7)) (label label))

Field access through a primitive field returns the declared primitive type:

(. record active)
(. record label)

Those field access expressions may be used in existing operations for the declared type:

(if (. record active) (. record id) 0)
(= (. record label) "alpha")
(std.string.len (. record label))

The primitive field surface is exactly direct i32, direct bool, and immutable direct string. Primitive-typed struct fields may flow through struct construction, immutable struct locals, struct parameters, struct returns, calls returning structs, field access, top-level tests, and main.

exp-19 does not add arrays, vectors, options, or results containing primitive-field structs, primitive fields inside containers, nested structs, struct mutation, mutable string locals, string assignment, string mutation, ownership/cleanup guarantees beyond existing string behavior, broader string operations, printing beyond existing legacy and v1.5 calls, package/import widening, manifest schema changes, stable ABI/layout, generics, methods, traits, or beta maturity.

The exp-19 fixtures are:

examples/supported/primitive-struct-fields.slo
examples/formatter/primitive-struct-fields.slo

The normative exp-19 contract is .llm/EXP_19_PRIMITIVE_STRUCT_FIELDS_ALPHA.md.

4.9.4a exp-112 Immutable Bool Locals Alpha

Status: released experimental Slovo contract. Matching Glagol exp-112 gates are required before broader compiler-support claims.

exp-112 broadens local bindings with direct immutable bool locals:

(let flag bool true)

The promoted surface is:

  • immutable let locals declared as bool
  • local initializers from already promoted bool literals, parameters, calls returning bool, and if expressions returning bool
  • local references in existing predicate, return, call, top-level test, and main positions

Mutable bool locals remain unsupported; exp-112 does not broaden var or set.

The exp-112 fixtures are:

examples/supported/local-variables.slo
examples/formatter/local-variables.slo
examples/projects/std-import-io/

The supported/formatter local-variables fixture keeps the earlier i32 local surface and now also includes direct immutable bool locals. The current std-import-io explicit import fixture uses bool locals in its stdin bool fallback helper path once the compiler accepts that local family.

exp-112 does not add mutable bool locals, bool assignment, new boolean operators, broader local-type widening, automatic imports, compiler-known runtime names, manifest schema changes, stable ABI/layout, or beta maturity.

The normative exp-112 contract is .llm/EXP_112_IMMUTABLE_BOOL_LOCALS_ALPHA.md.

4.9.4b exp-113 Mutable Scalar Locals Alpha

Status: released experimental Slovo contract. Matching Glagol exp-113 gates are required before broader compiler-support claims.

exp-113 broadens local bindings with mutable scalar var/set flows:

(var total i64 40i64)
(set total (+ total 2i64))

The promoted surface is:

  • mutable var locals declared as bool, i64, or f64
  • set reassignment from already promoted same-type scalar expressions for those declared local types
  • use in ordinary function bodies, top-level tests, and main

The exp-113 fixtures are:

examples/supported/local-variables.slo
examples/formatter/local-variables.slo

The supported/formatter local-variables fixture retains the earlier i32 local surface and exp-112 immutable bool locals, and now also covers mutable bool, i64, and f64 local var/set flows.

exp-113 does not add mutable string locals, vector mutation, option/result mutation, struct or enum mutation, mixed-type assignment, automatic imports, compiler-known runtime names, manifest schema changes, stable ABI/layout, or beta maturity.

The normative exp-113 contract is .llm/EXP_113_MUTABLE_SCALAR_LOCALS_ALPHA.md.

4.9.4c exp-114 Mutable Composite Locals Alpha

Status: released experimental Slovo contract. Matching Glagol exp-114 gates are required before broader compiler-support claims.

exp-114 broadens local bindings with mutable whole-value composite var/set flows:

(var label string "oak")
(set label "slovo")

The promoted surface is:

  • mutable var locals declared as string
  • mutable var locals declared as the current concrete vec families: (vec i32), (vec i64), (vec f64), (vec bool), and (vec string)
  • mutable var locals declared as the current concrete option families: (option i32), (option i64), (option f64), (option bool), and (option string)
  • mutable var locals declared as the current concrete result families: (result i32 i32), (result i64 i32), (result f64 i32), (result bool i32), and (result string i32)
  • mutable var locals declared as current known struct value types
  • mutable var locals declared as current enum value types
  • set reassignment from already promoted expressions of the exact same local type
  • use in ordinary function bodies, top-level tests, and main

The reassignment is whole-value only. Existing field access, vec indexing, option/result observers and payload extraction, equality, and enum/option/ result match continue to operate after the reassignment.

The exp-114 fixtures are:

examples/supported/composite-locals.slo
examples/formatter/composite-locals.slo

The supported/formatter composite-locals fixture covers same-type mutable whole-value local reassignment for strings, the current concrete vec families, the current concrete option/result families, current known struct values, and current enum values.

exp-114 does not add mutable arrays, array mutation, field mutation, vector element mutation, option/result payload mutation, enum payload mutation, mixed-type assignment, automatic imports, compiler-known runtime names, manifest schema changes, stable ABI/layout, or beta maturity.

The normative exp-114 contract is .llm/EXP_114_MUTABLE_COMPOSITE_LOCALS_ALPHA.md.

4.9.5 exp-20 F64 Numeric Primitive Alpha

Status: released experimental Slovo contract. Matching Glagol exp-20 gates are required before broader compiler-support claims.

exp-20 introduces direct f64 as the first non-i32 numeric primitive:

(fn half ((value f64)) -> f64
  (/ value 2.0))

The promoted direct f64 surface is:

  • f64 function parameters and returns
  • immutable let locals declared as f64
  • calls passing and returning f64
  • decimal f64 literals in f64 contexts
  • same-type f64 +, -, *, and /
  • same-type f64 =, <, >, <=, and >=
  • std.io.print_f64
  • top-level tests and main bodies; main still returns i32

std.io.print_f64 accepts exactly one f64, returns builtin unit, and prints an implementation-owned finite f64 textual representation plus a newline. Source-level NaN and infinity literals are unsupported in exp-20. exp-20 does not stabilize exact printed digits beyond newline-terminated output.

All promoted arithmetic and comparison is same-type f64. exp-20 does not add mixed i32/f64 arithmetic, numeric casts, implicit promotion, overloaded operators, or generic numeric abstractions.

The exp-20 fixtures are:

examples/supported/f64-numeric-primitive.slo
examples/formatter/f64-numeric-primitive.slo

The normative exp-20 contract is .llm/EXP_20_F64_NUMERIC_PRIMITIVE_ALPHA.md.

4.9.6 exp-22 Numeric Widening Conversions Alpha

Status: released experimental alpha Slovo contract. Matching Glagol exp-22 gates are required before broader compiler-support claims.

exp-22 promotes exactly three explicit compiler-known standard-runtime calls over the current i32, i64, and f64 numeric primitives:

  • std.num.i32_to_i64 : (i32) -> i64
  • std.num.i32_to_f64 : (i32) -> f64
  • std.num.i64_to_f64 : (i64) -> f64

The promoted calls are ordinary source calls and can feed same-type arithmetic or comparison after conversion. exp-22 does not introduce implicit promotion, mixed numeric arithmetic/comparison, narrowing or checked conversions, cast syntax, f32, unsigned or narrower integer families, numeric parse/format APIs, stable ABI/layout, manifest schema changes, or beta maturity.

The exp-22 fixtures are byte-identical:

examples/supported/numeric-widening-conversions.slo
examples/formatter/numeric-widening-conversions.slo

The normative exp-22 contract is .llm/EXP_22_NUMERIC_WIDENING_CONVERSIONS_ALPHA.md.

4.9.7 exp-23 Checked I64-To-I32 Conversion Alpha

Status: released experimental alpha Slovo contract. Matching Glagol exp-23 gates are required before broader compiler-support claims.

exp-23 promotes exactly one checked narrowing compiler-known standard-runtime call:

  • std.num.i64_to_i32_result : (i64) -> (result i32 i32)

The promoted call is an ordinary source call. It returns ok value when the signed i64 input is within the signed i32 range -2147483648 through 2147483647, and returns err 1 when the input is outside that range. Range failure does not trap.

The returned (result i32 i32) value uses the existing result helper surface. exp-23 does not introduce implicit promotion, mixed numeric arithmetic/comparison, cast syntax, std.num.cast, checked cast generics, any other narrowing conversion, f64 conversions, unsigned or narrower integer families, numeric parse/format APIs, stable ABI/layout, manifest schema changes, or beta maturity.

The exp-23 fixtures are byte-identical:

examples/supported/checked-i64-to-i32-conversion.slo
examples/formatter/checked-i64-to-i32-conversion.slo

The normative exp-23 contract is .llm/EXP_23_CHECKED_I64_TO_I32_CONVERSION_ALPHA.md.

4.9.8 exp-24 Integer To String Alpha

Status: released experimental alpha Slovo contract. Matching Glagol exp-24 gates are required before broader compiler-support claims.

exp-24 promotes exactly two integer formatting compiler-known standard-runtime calls:

  • std.num.i32_to_string : (i32) -> string
  • std.num.i64_to_string : (i64) -> string

The promoted calls are ordinary source calls. Each returns the decimal signed ASCII string for the input value. Negative values include a leading -; non-negative values have no leading +.

Returned strings use the existing string surface: string equality, std.string.len, immutable locals, function returns, calls, and std.io.print_string. The implementation is compiler/runtime-backed for now and may later move into Slovo std source once the language can host it.

exp-24 does not introduce f64 formatting, parse APIs beyond the released i32/i64 result calls, locale/base/radix, grouping, or padding controls, generic format/display traits, implicit conversions, stable standard-library implementation source, stable helper ABI/layout/ownership, manifest schema changes, or beta maturity.

The exp-24 fixtures are byte-identical:

examples/supported/integer-to-string.slo
examples/formatter/integer-to-string.slo

The normative exp-24 contract is .llm/EXP_24_INTEGER_TO_STRING_ALPHA.md.

4.9.9 exp-25 String Parse I64 Result Alpha

Status: released experimental alpha Slovo contract. Matching Glagol exp-25 gates are required before broader compiler-support claims.

exp-25 promotes exactly one string parse compiler-known standard-runtime call:

  • std.string.parse_i64_result : (string) -> (result i64 i32)

The promoted call parses the entire input string as a non-empty ASCII signed decimal i64. Accepted input has an optional leading -, one or more ASCII digits, and a numeric value in the signed i64 range. Success returns ok value; ordinary parse failure and out-of-range input return err 1.

The empty string, a lone -, any leading +, whitespace, non-digits, underscores, base/radix prefixes, suffixes, locale-specific digits or separators, Unicode digits, trailing bytes, and out-of-range values all return err 1. Ordinary parse failure and range failure do not trap.

exp-25 extends the supported concrete result families to include (result i64 i32) for result observation, extraction, direct matching, and fixture value flow. It does not add generic results, stable result ABI/layout, or result helper behavior beyond the explicitly supported concrete family.

The exp-25 fixtures are byte-identical:

examples/supported/string-parse-i64-result.slo
examples/formatter/string-parse-i64-result.slo

The normative exp-25 contract is .llm/EXP_25_STRING_PARSE_I64_RESULT_ALPHA.md.

4.9.10 exp-26 F64 To String Alpha

Status: released experimental alpha Slovo contract. Matching Glagol exp-26 gates are required before broader compiler-support claims.

exp-26 promotes exactly one finite f64 formatting compiler-known standard-runtime call:

  • std.num.f64_to_string : (f64) -> string

The promoted call returns finite decimal ASCII text for promoted finite f64 inputs. The exp-26 fixture values are 0.0, 3.5, -1.5, and 10.0.

This slice does not define f32, f64 parse, generic format/display/ interpolation APIs, locale/base/radix/grouping/padding/precision controls, stable NaN/infinity text, implicit conversion, stable helper ABI/layout/ ownership, manifest schema changes, or beta maturity.

The exp-26 fixtures are byte-identical:

examples/supported/f64-to-string.slo
examples/formatter/f64-to-string.slo

The normative exp-26 contract is .llm/EXP_26_F64_TO_STRING_ALPHA.md.

4.9.11 exp-27 Checked F64 To I32 Result Alpha

Status: released experimental alpha Slovo contract. Matching Glagol exp-27 gates are required before broader compiler-support claims.

exp-27 promotes exactly one checked f64 to i32 result compiler-known standard-runtime call:

  • std.num.f64_to_i32_result : (f64) -> (result i32 i32)

The promoted call returns ok value only when the input is finite, exactly integral, and within the signed i32 range -2147483648 through 2147483647. It returns err 1 for non-finite, fractional, or out-of-range input. Ordinary conversion failure does not trap.

The exp-27 fixture values are 0.0 -> ok 0, -12.0 -> ok -12, 3.5 -> err 1, and 2147483648.0 -> err 1.

This slice does not define unchecked f64 to i32, casts or cast syntax, generic cast_checked, f32, unsigned or narrower integer families, additional numeric conversion families, f64 parse, mixed numeric arithmetic, numeric containers, stable helper ABI/layout/ownership, manifest schema changes, or beta maturity.

The exp-27 fixtures are byte-identical:

examples/supported/f64-to-i32-result.slo
examples/formatter/f64-to-i32-result.slo

The normative exp-27 contract is .llm/EXP_27_F64_TO_I32_RESULT_ALPHA.md.

4.9.12 exp-28 String Parse F64 Result Alpha

Status: released experimental alpha Slovo contract. Matching Glagol exp-28 gates are required before broader compiler-support claims.

exp-28 promotes exactly one string parse compiler-known standard-runtime call:

  • std.string.parse_f64_result : (string) -> (result f64 i32)

The promoted call parses the entire input string as finite ASCII decimal f64 text. Accepted fixture input has an optional leading -, one or more ASCII digits before a decimal point, a decimal point ., one or more ASCII digits after the decimal point, and a finite value representable as f64. Success returns ok value.

Ordinary parse failure, non-finite text, leading or trailing unsupported characters, and out-of-domain input return err 1. Ordinary parse failure and domain failure do not trap.

The exp-28 fixture values are 12.5 -> ok 12.5, -0.25 -> ok -0.25, abc -> err 1, and nan -> err 1.

This slice does not define generic parse, bool/string/bytes parse, locale parsing, Unicode digit parsing, underscores, rich parse errors, stable helper ABI/layout/ownership, result genericity, f64 containers, mixed numeric arithmetic, manifest schema changes, or beta maturity.

The exp-28 fixtures are byte-identical:

examples/supported/string-parse-f64-result.slo
examples/formatter/string-parse-f64-result.slo

The normative exp-28 contract is .llm/EXP_28_STRING_PARSE_F64_RESULT_ALPHA.md.

4.9.13 exp-29 Numeric Struct Fields Alpha

Status: released experimental alpha Slovo contract. Matching Glagol exp-29 gates are required before broader compiler-support claims.

exp-29 promotes direct immutable struct field declarations whose field types are exactly i64 or f64, alongside the already supported direct i32, bool, immutable string, and current enum fields.

Struct constructors may initialize i64 fields from i64 values and explicit signed decimal i64 literal atoms. They may initialize f64 fields from finite f64 values and finite decimal f64 literals. The exp-20 finite-only policy remains in force; non-finite f64 literals are not promoted.

Immutable struct values carrying numeric fields may flow through locals, parameters, returns, and calls. Field access returns the declared i64 or f64 type. Accessed fields may be used with existing same-type arithmetic/comparison and existing numeric print/format helpers where already supported.

This slice does not define struct field mutation, nested structs, arrays/vectors/options/results as fields, enum payload widening, numeric containers, f32, unsigned or narrower integer families, mixed numeric arithmetic, implicit conversions, new parse/format APIs, generic structs, methods, traits, stable ABI/layout/ownership, manifest schema changes, FFI layout claims, or beta maturity.

The exp-29 fixtures are byte-identical:

examples/supported/numeric-struct-fields.slo
examples/formatter/numeric-struct-fields.slo

The normative exp-29 contract is .llm/EXP_29_NUMERIC_STRUCT_FIELDS_ALPHA.md.

4.9.14 exp-30 Standard Library Source Layout Alpha

Status: released experimental alpha Slovo contract. Matching Glagol exp-30 gates are required before broader compiler-support claims.

exp-30 establishes std/ as the Slovo source home for staged standard library modules and examples:

std/README.md
std/io.slo
std/string.slo
std/num.slo
std/result.slo
std/math.slo

The source files use current valid Slovo where practical. Because current project import support does not promote a repo-root std/ search path, the staged files use plain flat module declarations such as (module math).

std/math.slo contains narrow source-authored helpers expressible with the current language: abs_i32, min_i32, max_i32, clamp_i32, square_i32, and square_f64. The other staged modules may wrap already promoted compiler-known standard-runtime calls with short module-local names.

This slice does not define automatic standard-library imports, replacement of compiler-known std.* calls with source implementations, new compiler-known std.* operation names, generics, traits, overloads, module/package registry changes, stable standard-library APIs, stable ABI/layout/ownership, manifest schema changes, broad math, trigonometry, pow, sqrt, f32, unsigned or narrower integers, mixed numeric arithmetic, numeric containers, or beta maturity.

The exp-30 formatter example is:

examples/formatter/std-source-layout-alpha.slo

The normative exp-30 contract is .llm/EXP_30_STANDARD_LIBRARY_SOURCE_LAYOUT_ALPHA.md.

4.9.15 exp-31 Checked F64 To I64 Result Alpha

Status: released experimental alpha Slovo contract. Matching Glagol exp-31 gates are required before broader compiler-support claims.

exp-31 promotes exactly one checked f64 to i64 result compiler-known standard-runtime call:

  • std.num.f64_to_i64_result : (f64) -> (result i64 i32)

The promoted call returns ok value only when the input is finite, exactly integral, and within the signed i64 range -9223372036854775808 through 9223372036854775807. It returns err 1 for non-finite, fractional, or out-of-range input. Ordinary conversion failure does not trap.

The exp-31 fixture values are 0.0 -> ok 0i64, -12.0 -> ok -12i64, 3.5 -> err 1, and 9223372036854776000.0 -> err 1. The out-of-range value is the formatter-stable spelling of the accepted exact positive out-of-range literal 9223372036854775808.0; detailed edge behavior around the f64/i64 limits is implementation-owned Glagol test coverage rather than a larger Slovo fixture matrix.

This slice does not define unchecked casts, unchecked f64 to i64, casts or cast syntax, generic cast_checked, f32, unsigned or narrower integer families, additional numeric conversion families, mixed numeric arithmetic, broad math APIs, numeric containers, stable helper ABI/layout/ownership, manifest schema changes, or beta maturity.

The exp-31 fixtures are byte-identical:

examples/supported/f64-to-i64-result.slo
examples/formatter/f64-to-i64-result.slo

The normative exp-31 contract is .llm/EXP_31_CHECKED_F64_TO_I64_RESULT_ALPHA.md.

4.9.16 exp-32 Standard Math Source Helpers Alpha

Status: released experimental alpha Slovo contract. Matching Glagol exp-32 source-check and formatter gates are required before broader compiler-support claims.

exp-32 extends staged std/math.slo with narrow source-authored helpers over existing numeric primitives. The existing exp-30 helpers remain:

  • abs_i32 : (i32) -> i32
  • min_i32 : (i32, i32) -> i32
  • max_i32 : (i32, i32) -> i32
  • clamp_i32 : (i32, i32, i32) -> i32
  • square_i32 : (i32) -> i32
  • square_f64 : (f64) -> f64

exp-32 adds:

  • abs_i64 : (i64) -> i64
  • min_i64 : (i64, i64) -> i64
  • max_i64 : (i64, i64) -> i64
  • clamp_i64 : (i64, i64, i64) -> i64
  • square_i64 : (i64) -> i64
  • abs_f64 : (f64) -> f64
  • min_f64 : (f64, f64) -> f64
  • max_f64 : (f64, f64) -> f64
  • clamp_f64 : (f64, f64, f64) -> f64

These are ordinary Slovo source functions using existing same-type arithmetic and comparison, if, literals, calls, and explicit signatures. clamp_* is defined as max(low, min(value, high)) in source and does not reorder or validate bounds.

Current Slovo promotes two ways to use these helpers. Projects may keep the earlier local-copy pattern and import a local math.slo, or, as of exp-44, may explicitly import the repo-root standard module with (import std.math (...)). exp-44 does not make the helpers implicit.

This slice does not define new compiler-known std.* operation names, standard-runtime catalog entries, replacement of compiler-known std.* calls with source implementations, broad math, trigonometry, sqrt, pow, f32, unsigned or narrower integers, generic math, overloads, traits, mixed numeric arithmetic, numeric containers, stable standard-library APIs, stable ABI/layout/ownership, manifest schema changes, or beta maturity.

The exp-32 source fixture is:

std/math.slo

The normative exp-32 contract is .llm/EXP_32_STANDARD_MATH_SOURCE_HELPERS_ALPHA.md.

4.9.16a exp-44 Standard Library Source Search Alpha

Status: released experimental alpha Slovo contract. Matching Glagol exp-44 project-mode gates are required before broader compiler-support claims.

exp-44 promotes the first explicit standard-library source import address:

(import std.math (abs_i32 square_i32 abs_i64 square_i64 abs_f64 square_f64))

The external import name std.math resolves to the staged repo-root source file std/math.slo. The source file still declares the flat module (module math ...), but now carries an explicit export list for the promoted math helper names.

The exp-44 fixture is:

examples/projects/std-import-math/

This slice does not define automatic standard-library imports, a std.slo aggregator, aliases, glob imports, qualified member access, workspace/package standard-library imports, package registry behavior, broad standard-library APIs, stable standard-library APIs, stable ABI/layout/ownership, optimizer guarantees, benchmark thresholds, or beta maturity.

The normative exp-44 contract is .llm/EXP_44_STANDARD_LIBRARY_SOURCE_SEARCH_ALPHA.md.

4.9.17 exp-33 Standard Result Source Helpers Alpha

Status: released experimental alpha Slovo contract. Matching Glagol exp-33 source-check and formatter gates are required before broader compiler-support claims.

exp-33 extends staged std/result.slo with narrow source-authored helpers for already promoted concrete result families. The existing i32 wrappers remain:

  • is_ok_i32 : ((result i32 i32)) -> bool
  • is_err_i32 : ((result i32 i32)) -> bool
  • unwrap_ok_i32 : ((result i32 i32)) -> i32
  • unwrap_err_i32 : ((result i32 i32)) -> i32

exp-33 fills out concrete err wrappers:

  • is_err_i64 : ((result i64 i32)) -> bool
  • unwrap_err_i64 : ((result i64 i32)) -> i32
  • is_err_string : ((result string i32)) -> bool
  • unwrap_err_string : ((result string i32)) -> i32
  • is_err_f64 : ((result f64 i32)) -> bool
  • unwrap_err_f64 : ((result f64 i32)) -> i32

exp-33 also adds concrete fallback helpers:

  • unwrap_or_i32 : ((result i32 i32), i32) -> i32
  • unwrap_or_i64 : ((result i64 i32), i64) -> i64
  • unwrap_or_string : ((result string i32), string) -> string
  • unwrap_or_f64 : ((result f64 i32), f64) -> f64

These are ordinary Slovo source functions using existing std.result.is_ok, std.result.is_err, std.result.unwrap_ok, std.result.unwrap_err, if, parameters, and explicit signatures. Each unwrap_or_* helper returns the ok payload when the result is ok and returns the supplied fallback otherwise. unwrap_or_string uses the existing (result string i32) match shape to return the payload or fallback without requiring string-valued if. exp-74 later broadens the same staged module with concrete source constructors ok_i32, err_i32, ok_i64, err_i64, ok_string, err_string, ok_f64, err_f64, ok_bool, and err_bool. exp-109 later adds the concrete bridge helpers ok_or_none_i32, ok_or_none_i64, ok_or_none_string, ok_or_none_f64, and ok_or_none_bool.

At exp-33, Slovo did not yet promote automatic std imports, a repo-root std/ search path, or compiler-loaded standard library source. exp-45 later promotes the explicit std.result source-search path while keeping automatic imports deferred.

This slice does not define new compiler-known std.* operation names, standard-runtime catalog entries, replacement of compiler-known std.* calls with source implementations, generic std.result.map, generic std.result.unwrap_or, std.result.and_then, option helper names, new result payload families, generic result helpers, stable standard-library APIs, stable ABI/layout/ownership, manifest schema changes, or beta maturity.

The exp-33 source fixture is:

std/result.slo

The normative exp-33 contract is .llm/EXP_33_STANDARD_RESULT_SOURCE_HELPERS_ALPHA.md.

4.9.18 exp-34 String Parse Bool Result Alpha

Status: released experimental alpha Slovo contract. Matching Glagol exp-34 gates are required before broader compiler-support claims.

exp-34 promotes exactly one string parse compiler-known standard-runtime call:

  • std.string.parse_bool_result : (string) -> (result bool i32)

The promoted call parses the entire input string as exactly one ASCII lowercase boolean token. Accepted input is exactly true or false. Success returns ok true for true and ok false for false.

Ordinary parse failure returns err 1. The empty string, uppercase or mixed-case text, leading or trailing whitespace, numeric text, locale-specific text, Unicode lookalikes, suffixes, prefixes, and any other text all return err 1. Ordinary parse failure does not trap.

exp-34 extends the supported concrete result families only as needed for the returned (result bool i32) parse value and existing compiler-known result observation/extraction. It does not add source-authored std/result.slo bool wrappers, generic results, stable result ABI/layout, or result helper behavior beyond the explicitly supported concrete family.

The exp-34 fixtures are byte-identical:

examples/supported/string-parse-bool-result.slo
examples/formatter/string-parse-bool-result.slo

The normative exp-34 contract is .llm/EXP_34_STRING_PARSE_BOOL_RESULT_ALPHA.md.

4.9.19 exp-35 Standard Result Bool Source Helpers Alpha

Status: released experimental alpha Slovo contract. Matching Glagol exp-35 source-check and formatter gates are required before broader compiler-support claims.

exp-35 extends staged std/result.slo with the next conservative source-authored concrete result helper slice for the exp-34 returned (result bool i32) family:

  • is_ok_bool : ((result bool i32)) -> bool
  • is_err_bool : ((result bool i32)) -> bool
  • unwrap_ok_bool : ((result bool i32)) -> bool
  • unwrap_err_bool : ((result bool i32)) -> i32
  • unwrap_or_bool : ((result bool i32), bool) -> bool

These are ordinary Slovo source functions using existing compiler-supported std.result.is_ok, std.result.is_err, std.result.unwrap_ok, std.result.unwrap_err, if, parameters, and explicit signatures. unwrap_or_bool returns the ok payload when the result is ok and returns the supplied fallback otherwise.

At exp-35, Slovo did not yet promote automatic std imports, a repo-root std/ search path, or compiler-loaded standard library source. exp-45 later promotes the explicit std.result source-search path while keeping automatic imports deferred.

This slice does not define new compiler-known std.* operation names, standard-runtime catalog entries, replacement of compiler-known std.* calls with source implementations, source-authored generic result helpers, generic std.result.map, generic std.result.unwrap_or, std.result.and_then, option helper names, broad result payload families, source constructors for (result bool i32), general source match over (result bool i32) beyond compiler-supported fixture flow, stable standard-library APIs, stable ABI/layout/ownership, manifest schema changes, or beta maturity.

The exp-35 source fixture is:

std/result.slo

The normative exp-35 contract is .llm/EXP_35_STANDARD_RESULT_BOOL_SOURCE_HELPERS_ALPHA.md.

4.9.20 exp-36 Standard Option Source Helpers Alpha

Status: released experimental alpha Slovo contract. Matching Glagol exp-36 source-check and formatter gates are required before broader compiler-support claims.

exp-36 adds staged std/option.slo with a conservative source-authored helper slice for the already supported (option i32) family:

  • is_some_i32 : ((option i32)) -> bool
  • is_none_i32 : ((option i32)) -> bool
  • unwrap_some_i32 : ((option i32)) -> i32
  • unwrap_or_i32 : ((option i32), i32) -> i32

exp-75 later adds some_i32 : (i32) -> (option i32) and none_i32 : () -> (option i32). exp-95 broadens the same staged module and the same conservative option slice to concrete (option i64) with:

  • some_i64 : (i64) -> (option i64)
  • none_i64 : () -> (option i64)
  • is_some_i64 : ((option i64)) -> bool
  • is_none_i64 : ((option i64)) -> bool
  • unwrap_some_i64 : ((option i64)) -> i64
  • unwrap_or_i64 : ((option i64), i64) -> i64

exp-100 broadens the same staged module again to concrete (option string) with:

  • some_string : (string) -> (option string)
  • none_string : () -> (option string)
  • is_some_string : ((option string)) -> bool
  • is_none_string : ((option string)) -> bool
  • unwrap_some_string : ((option string)) -> string
  • unwrap_or_string : ((option string), string) -> string

exp-102 broadens the same staged module again to concrete (option f64) and (option bool) with:

  • some_f64 : (f64) -> (option f64)
  • none_f64 : () -> (option f64)
  • is_some_f64 : ((option f64)) -> bool
  • is_none_f64 : ((option f64)) -> bool
  • unwrap_some_f64 : ((option f64)) -> f64
  • unwrap_or_f64 : ((option f64), f64) -> f64
  • some_bool : (bool) -> (option bool)
  • none_bool : () -> (option bool)
  • is_some_bool : ((option bool)) -> bool
  • is_none_bool : ((option bool)) -> bool
  • unwrap_some_bool : ((option bool)) -> bool
  • unwrap_or_bool : ((option bool), bool) -> bool

exp-109 later adds concrete option-to-result bridge helpers for all current concrete option families:

  • some_or_err_i32 : ((option i32), i32) -> (result i32 i32)
  • some_or_err_i64 : ((option i64), i32) -> (result i64 i32)
  • some_or_err_f64 : ((option f64), i32) -> (result f64 i32)
  • some_or_err_bool : ((option bool), i32) -> (result bool i32)
  • some_or_err_string : ((option string), i32) -> (result string i32)

These are ordinary Slovo source functions using existing compiler-supported is_some, is_none, unwrap_some, ok, err, if, parameters, and explicit signatures. unwrap_or_i32 returns the some payload when present and returns the supplied fallback for none. Each some_or_err_* helper returns ok with the option payload when present and returns err err_code for none.

Current Slovo keeps standard-library organization as flat staged std/*.slo facades. exp-45 later promotes explicit std.option source search for this module. A future std.slo aggregator/reexport layer, inspired by Zig's facade/reexport approach, remains deferred until broader standard-library source organization is promoted.

This slice does not define new compiler-known std.* operation names, standard-runtime catalog entries, automatic std imports, repo-root std/ search, compiler-loaded standard-library source, replacement of compiler-known calls with source implementations, generic option helpers, option payload families beyond (option i32), (option i64), (option f64), (option bool), and (option string), stable standard-library APIs, stable ABI/layout/ownership, manifest schema changes, or beta maturity.

The exp-36 source fixture is:

std/option.slo

The normative exp-36 contract is .llm/EXP_36_STANDARD_OPTION_SOURCE_HELPERS_ALPHA.md.

4.9.20a exp-45 Standard Result And Option Source Search Alpha

Status: released experimental alpha Slovo contract. Matching Glagol exp-45 project-mode gates are required before broader compiler-support claims.

exp-45 extends explicit standard-library source search to result and option helpers:

(import std.result (unwrap_or_i32 is_ok_bool unwrap_or_bool))
(import std.option (is_some_i32 unwrap_or_i32))

The external import names resolve to staged repo-root source files:

std/result.slo
std/option.slo

Both files keep flat module declarations, (module result ...) and (module option ...), and now carry explicit export lists for their promoted helper names.

The exp-45 fixtures are:

examples/projects/std-import-result/
examples/projects/std-import-option/

This slice does not define automatic standard-library imports, a std.slo aggregator, aliases, glob imports, qualified member access, workspace/package standard-library imports, package registry behavior, generic result helpers, generic option helpers, broad standard-library APIs, stable ABI/layout/ ownership, optimizer guarantees, benchmark thresholds, or beta maturity.

The normative exp-45 contract is .llm/EXP_45_STANDARD_RESULT_OPTION_SOURCE_SEARCH_ALPHA.md.

4.9.20b exp-46 Workspace Standard Source Search Alpha

Status: released experimental alpha Slovo contract. Matching Glagol exp-46 workspace gates are required before broader compiler-support claims.

exp-46 extends explicit standard-library source search from single projects to workspace packages. Package source may import a staged standard module without declaring a package dependency:

(import std.option (is_some_i32 unwrap_or_i32))

The exp-46 fixture is:

examples/workspaces/std-import-option/

This slice does not define automatic standard-library imports, workspace dependency syntax for std, package registry behavior, installed toolchain stdlib paths, a std.slo aggregator, generic option helpers, broad standard-library APIs, stable ABI/layout/ownership, optimizer guarantees, benchmark thresholds, or beta maturity.

The normative exp-46 contract is .llm/EXP_46_WORKSPACE_STANDARD_SOURCE_SEARCH_ALPHA.md.

4.9.20c exp-47 Standard Host Facade Source Search Alpha

Status: released experimental alpha Slovo contract. Matching Glagol exp-47 project-mode gates are required before broader compiler-support claims.

exp-47 extends explicit standard-library source search to the host facade modules staged in exp-37 and exp-38:

(import std.time (monotonic_ms sleep_ms_zero))
(import std.random (random_i32 random_i32_non_negative))
(import std.env (get get_result))
(import std.fs (read_text read_text_result write_text_status write_text_result))

The external import names resolve to staged repo-root source files:

std/time.slo
std/random.slo
std/env.slo
std/fs.slo

The files keep flat module declarations, (module time ...), (module random ...), (module env ...), and (module fs ...), and now carry explicit export lists for their promoted facade names.

The exp-47 fixtures are:

examples/projects/std-import-time/
examples/projects/std-import-random/
examples/projects/std-import-env/
examples/projects/std-import-fs/

This slice does not define automatic standard-library imports, a std.slo aggregator, aliases, glob imports, qualified member access, workspace dependency syntax for std, package registry behavior, installed toolchain stdlib paths, broad host APIs, wall-clock/calendar/timezone APIs, high-resolution timers, random ranges/seeds/bytes/floats/UUIDs, environment mutation/enumeration, binary/directory/streaming/async filesystem APIs, rich host error ADTs, stable ABI/layout/ownership, optimizer guarantees, benchmark thresholds, or beta maturity.

The normative exp-47 contract is .llm/EXP_47_STANDARD_HOST_FACADE_SOURCE_SEARCH_ALPHA.md.

4.9.20d exp-48 Standard Core Facade Source Search Alpha

Status: released experimental alpha Slovo contract. Matching Glagol exp-48 project-mode gates are required before broader compiler-support claims.

exp-48 extends explicit standard-library source search to the pure core facade modules:

(import std.string (len concat parse_i32_result parse_i64_result parse_f64_result parse_bool_result))
(import std.num (i32_to_i64 i32_to_f64 i64_to_f64 i64_to_i32_result f64_to_i32_result f64_to_i64_result i32_to_string i64_to_string f64_to_string))

The external import names resolve to staged repo-root source files:

std/string.slo
std/num.slo

The files keep flat module declarations, (module string ...) and (module num ...), and now carry explicit export lists for their promoted facade names.

The exp-48 fixtures are:

examples/projects/std-import-string/
examples/projects/std-import-num/

This slice does not define automatic standard-library imports, a std.slo aggregator, aliases, glob imports, qualified member access, package registry behavior, installed toolchain stdlib paths, generic parse/format APIs, string indexing/slicing/tokenization, mutable strings, string containers, broad numeric casts, unsigned or narrower integer families, mixed numeric arithmetic, decimal/char/byte types, stable ABI/layout/ownership, optimizer guarantees, benchmark thresholds, or beta maturity.

The normative exp-48 contract is .llm/EXP_48_STANDARD_CORE_FACADE_SOURCE_SEARCH_ALPHA.md.

4.9.20e exp-49 Standard IO Facade Source Search Alpha

Status: released experimental alpha Slovo contract. Matching Glagol exp-49 project-mode gates are required before broader compiler-support claims.

exp-49 extends explicit standard-library source search to the staged IO facade module:

(import std.io (print_i32_zero print_i64_zero print_f64_zero print_string_zero print_bool_zero))

The external import name resolves to the staged repo-root source file:

std/io.slo

The file keeps its flat module declaration, (module io ...), and now carries an explicit export list for its promoted facade names.

The exp-49 fixture is:

examples/projects/std-import-io/

Later staged-source expansions keep the same std/io.slo module path. exp-73 adds print_i32_value, print_i64_value, print_f64_value, print_string_value, and print_bool_value as source-authored print wrappers that preserve the printed value. exp-111 adds a connected stdin helper package: read_stdin_result, read_stdin_option, read_stdin_or, read_stdin_i32_result, read_stdin_i32_option, read_stdin_i32_or_zero, read_stdin_i32_or, read_stdin_i64_result, read_stdin_i64_option, read_stdin_i64_or_zero, read_stdin_i64_or, read_stdin_f64_result, read_stdin_f64_option, read_stdin_f64_or_zero, read_stdin_f64_or, read_stdin_bool_result, read_stdin_bool_option, read_stdin_bool_or_false, and read_stdin_bool_or. These later helpers remain ordinary source over the promoted std.io.read_stdin_result runtime lane, the concrete std.string.parse_*_result helpers, and the exp-109 std.result.ok_or_none_* bridge helpers, and do not add new runtime names.

This slice does not define automatic standard-library imports, a std.slo aggregator, aliases, glob imports, qualified member access, package registry behavior, installed toolchain stdlib paths, new compiler-known IO names, formatted output APIs, stdin expansion, terminal control, stream abstractions, async IO, stable stdout/stderr buffering semantics beyond existing runtime behavior, stable ABI/layout/ownership, optimizer guarantees, benchmark thresholds, or beta maturity.

The normative exp-49 contract is .llm/EXP_49_STANDARD_IO_FACADE_SOURCE_SEARCH_ALPHA.md.

4.9.20f exp-50 Installed Standard Library Discovery Alpha

Status: released experimental alpha Slovo contract. Matching Glagol exp-50 installed-discovery gates are required before broader toolchain-support claims.

exp-50 extends explicit standard-library source search to installed toolchain layouts. Project and workspace source still imports staged standard modules explicitly:

(import std.math (abs_i32))

The staged source modules remain flat files under std/*.slo. A compiler may discover those files from an installed standard-library directory such as:

share/slovo/std

This slice does not define automatic standard-library imports, a std.slo aggregator, aliases, glob imports, qualified member access, package registry behavior, lockfiles, package std dependencies, a stable package manager, stable install layout guarantees beyond this alpha discovery candidate, new compiler-known runtime names, broad standard-library APIs, stable ABI/layout/ownership, optimizer guarantees, benchmark thresholds, or beta maturity.

The normative exp-50 contract is .llm/EXP_50_INSTALLED_STANDARD_LIBRARY_DISCOVERY_ALPHA.md.

4.9.20g exp-51 Standard Library Path List Alpha

Status: released experimental alpha Slovo contract. Matching Glagol exp-51 path-list gates are required before broader package-resolution claims.

exp-51 refines explicit standard-library source search by allowing SLOVO_STD_PATH to name an ordered OS path list of standard-library roots. A tool resolves a requested std.<module> import from the first listed root that contains the corresponding module file.

This slice supports partial override roots during standard-library development. It does not define automatic standard-library imports, a std.slo aggregator, aliases, glob imports, qualified member access, package registry behavior, lockfiles, package std dependencies, semantic version solving, stable package manager behavior, broad standard-library APIs, stable ABI/layout/ownership, optimizer guarantees, benchmark thresholds, or beta maturity.

The normative exp-51 contract is .llm/EXP_51_STANDARD_LIBRARY_PATH_LIST_ALPHA.md.

4.9.20h exp-52 Standard Process Facade Source Search Alpha

Status: released experimental alpha Slovo contract. Matching Glagol exp-52 project-mode gates are required before broader compiler-support claims.

exp-52 extends explicit standard-library source search to the staged process facade module:

(import std.process (argc arg arg_result has_arg))

The external import name resolves to the staged repo-root source file:

std/process.slo

The file keeps its flat module declaration, (module process ...), and exports wrappers over existing std.process.argc, std.process.arg, and std.process.arg_result, plus the source-authored has_arg helper.

The exp-52 fixture is:

examples/projects/std-import-process/

This slice does not define automatic standard-library imports, a std.slo aggregator, aliases, glob imports, qualified member access, package registry behavior, lockfiles, package std dependencies, new compiler-known process runtime names, process spawning, exit/status control, current-directory APIs, signal handling, stable ABI/layout/ownership, optimizer guarantees, benchmark thresholds, or beta maturity.

The normative exp-52 contract is .llm/EXP_52_STANDARD_PROCESS_FACADE_SOURCE_SEARCH_ALPHA.md.

4.9.20i exp-53 Standard CLI Source Facade Alpha

Status: released experimental alpha Slovo contract. Matching Glagol exp-53 project-mode gates are required before broader compiler-support claims.

exp-53 extends explicit standard-library source search to the staged CLI facade module:

(import std.cli (arg_text_result arg_i32_result arg_i32_or_zero))

The external import name resolves to the staged repo-root source file:

std/cli.slo

The file keeps its flat module declaration, (module cli ...), imports std.process and std.string as ordinary standard source modules, and exports arg_text_result, arg_i32_result, and arg_i32_or_zero.

The exp-53 fixture is:

examples/projects/std-import-cli/

This slice does not define automatic standard-library imports, a std.slo aggregator, aliases, glob imports, qualified member access, package registry behavior, lockfiles, package std dependencies, new compiler-known runtime names, shell parsing, option/flag parsing, subcommands, environment-backed configuration, stable CLI framework APIs, stable ABI/layout/ownership, optimizer guarantees, benchmark thresholds, or beta maturity.

The normative exp-53 contract is .llm/EXP_53_STANDARD_CLI_SOURCE_FACADE_ALPHA.md.

4.9.20j exp-54 Standard CLI Typed Arguments Alpha

Status: released experimental alpha Slovo contract. Matching Glagol exp-54 project-mode gates are required before broader compiler-support claims.

exp-54 extends the staged CLI facade helper list:

(import std.cli (arg_text_result arg_i32_result arg_i32_or_zero arg_i64_result arg_i64_or_zero arg_f64_result arg_f64_or_zero arg_bool_result arg_bool_or_false))

The external import name still resolves to:

std/cli.slo

The file remains ordinary source and continues to import std.process and std.string. It adds typed result and fallback helpers for the current i32, i64, f64, and bool parse-result families.

The exp-54 fixture remains:

examples/projects/std-import-cli/

This slice does not define automatic standard-library imports, a std.slo aggregator, aliases, glob imports, qualified member access, package registry behavior, lockfiles, package std dependencies, new compiler-known runtime names, shell parsing, option/flag parsing, subcommands, environment-backed configuration, stable CLI framework APIs, stable ABI/layout/ownership, optimizer guarantees, benchmark thresholds, or beta maturity.

The normative exp-54 contract is .llm/EXP_54_STANDARD_CLI_TYPED_ARGUMENTS_ALPHA.md.

4.9.20k exp-55 Result F64 Bool Source Flow Alpha

Status: released experimental alpha Slovo contract. Matching Glagol exp-55 checker, formatter, test-runner, and LLVM gates are required before broader compiler-support claims.

exp-55 promotes source constructors for:

(ok f64 i32 1.5)
(err f64 i32 1)
(ok bool i32 true)
(err bool i32 1)

Source match may bind the f64 or bool ok payload and the i32 err payload for those concrete result families:

(match value
  ((ok payload)
    payload)
  ((err code)
    fallback))

The exp-55 fixture is:

examples/supported/result-f64-bool-match.slo

This slice does not define generic result types, result payload families beyond the already promoted concrete families, generic map/and_then, exception handling, stable ABI/layout/ownership, optimizer guarantees, benchmark thresholds, or beta maturity.

The normative exp-55 contract is .llm/EXP_55_RESULT_F64_BOOL_SOURCE_FLOW_ALPHA.md.

4.9.20l exp-56 Integer Remainder Alpha

Status: released experimental alpha Slovo contract. Matching Glagol exp-56 parser, checker, formatter, test-runner, LLVM, and standard-source gates are required before broader compiler-support claims.

exp-56 promotes the % binary operator for same-width signed integer operands:

(% 17 5)
(% -17 5)
(% 42i64 5i64)
(% -17i64 5i64)

The result type is i32 for i32 operands and i64 for i64 operands. The sign behavior follows signed remainder semantics: the remainder carries the dividend sign for negative dividends. Remainder by zero is a test-runner runtime error and remains an invalid program behavior for hosted code, just like division by zero in the current numeric slice.

exp-56 also extends std/math.slo with source-authored helpers:

rem_i32, is_even_i32, is_odd_i32
rem_i64, is_even_i64, is_odd_i64

The exp-56 fixture is:

examples/supported/integer-remainder.slo
examples/formatter/integer-remainder.slo

This slice does not define floating-point remainder, Euclidean modulo, unsigned arithmetic, bit operations, generic math, mixed numeric arithmetic, stable ABI/layout/ownership, optimizer guarantees, benchmark thresholds, or beta maturity.

The normative exp-56 contract is .llm/EXP_56_INTEGER_REMAINDER_ALPHA.md.

4.9.20m exp-57 Integer Bitwise Alpha

Status: released experimental alpha Slovo contract. Matching Glagol exp-57 parser, checker, formatter, test-runner, LLVM, and standard-source gates are required before broader compiler-support claims.

exp-57 promotes explicit bitwise binary heads for same-width signed integer operands:

(bit_and 6 3)
(bit_or 4 2)
(bit_xor 7 3)
(bit_and 6i64 3i64)
(bit_or 4i64 2i64)
(bit_xor 7i64 3i64)

The result type is i32 for i32 operands and i64 for i64 operands. The heads are intentionally named forms rather than symbolic operators so they remain clear in the S-expression surface.

exp-57 also extends std/math.slo with source-authored helpers:

bit_and_i32, bit_or_i32, bit_xor_i32
bit_and_i64, bit_or_i64, bit_xor_i64

The exp-57 fixtures are:

examples/supported/integer-bitwise.slo
examples/formatter/integer-bitwise.slo

This slice does not define shifts, bit-not, unsigned arithmetic, bit-width-specific integer families, floating-point bitwise operations, generic math, mixed numeric arithmetic, stable ABI/layout/ownership, optimizer guarantees, benchmark thresholds, or beta maturity.

The normative exp-57 contract is .llm/EXP_57_INTEGER_BITWISE_ALPHA.md.

4.9.20n exp-58 Boolean Logic Alpha

Status: released experimental alpha Slovo contract. Matching Glagol exp-58 parser, formatter, checker, test-runner, LLVM, and fixture gates are required before broader compiler-support claims.

exp-58 promotes boolean logic forms:

(and left right)
(or left right)
(not value)

and and or short-circuit and are specified as source forms lowered through existing if semantics:

  • (and left right) evaluates right only when left is true.
  • (or left right) evaluates right only when left is false.
  • (not value) returns false for true input and true for false input.

The exp-58 fixtures are:

examples/supported/boolean-logic.slo
examples/formatter/boolean-logic.slo

This slice does not define truthiness, variadic boolean operators, pattern guards, macro expansion, stable ABI/layout/ownership, optimizer guarantees, benchmark thresholds, or beta maturity.

The normative exp-58 contract is .llm/EXP_58_BOOLEAN_LOGIC_ALPHA.md.

4.9.20p exp-119 Benchmark Suite Extension And Whitepaper Refresh Alpha

Status: released experimental alpha Slovo contract. Matching Glagol exp-119 benchmark-suite extension, publication refresh, and verification gates are required before broader compiler-support claims.

exp-119 does not add new source syntax or new type forms. It keeps the exp-118 language surface unchanged while widening the current benchmark/ publication baseline from three kernels to five:

  • math-loop
  • branch-loop
  • parse-loop
  • array-index-loop
  • string-eq-loop

The exp-119 publication fixtures are:

docs/SLOVO_WHITEPAPER.md
docs/SLOVO_WHITEPAPER.pdf
docs/SLOVO_MANIFEST.pdf
WHITEPAPER.pdf

This slice does not define language-surface changes, standard-library API changes, compiler-known runtime names, optimizer guarantees, benchmark thresholds, cross-machine performance claims, stable ABI/layout/ownership, or beta maturity.

The normative exp-119 contract is .llm/EXP_119_BENCHMARK_SUITE_EXTENSION_AND_WHITEPAPER_REFRESH_ALPHA.md.

4.9.20r exp-121 Non-Recursive Struct Enum Payloads Alpha

Status: released experimental alpha Slovo contract. Matching Glagol exp-121 gates are required before broader compiler-support claims.

exp-121 promotes unary enum payload variants whose payload type is a current known non-recursive struct type. Where payload variants are present in one enum, those payload variants still share the same payload type.

Qualified constructors may build those enum values from matching struct-valued expressions. Immutable enum values carrying those payloads may flow through locals, parameters, returns, calls, tests, and main. Exhaustive match continues to bind exactly one immutable payload name per payload arm, and the bound struct payload reuses existing field access behavior, including checked indexing through array-bearing struct fields where already promoted by exp-120.

This slice does not define enum equality requirements for struct-payload enums, direct array/vec/option/result payloads, multiple payload fields, recursive/cyclic payloads, mutation, generics, stable ABI/layout/ownership claims, or beta maturity.

The exp-121 fixtures are:

examples/supported/enum-payload-structs.slo
examples/formatter/enum-payload-structs.slo

The normative exp-121 contract is .llm/EXP_121_NON_RECURSIVE_STRUCT_ENUM_PAYLOADS_ALPHA.md.

4.9.20t exp-123 Owned Vector Benchmark Suite Extension And Whitepaper Refresh Alpha

Status: released experimental alpha Slovo contract. Matching Glagol exp-123 benchmark-suite extension, publication refresh, and verification gates are required before broader compiler-support claims.

exp-123 does not add new source syntax or new type forms. It keeps the exp-121 language surface unchanged while widening the current benchmark/ publication baseline from seven kernels to nine:

  • math-loop
  • branch-loop
  • parse-loop
  • array-index-loop
  • string-eq-loop
  • array-struct-field-loop
  • enum-struct-payload-loop
  • vec-i32-index-loop
  • vec-string-eq-loop

The two additional kernels are publication evidence for the already promoted runtime-owned vector lanes over i32 and string.

The exp-123 publication fixtures are:

docs/SLOVO_WHITEPAPER.md
docs/SLOVO_WHITEPAPER.pdf
docs/SLOVO_MANIFEST.pdf
WHITEPAPER.pdf

This slice does not define language-surface changes, standard-library API changes, compiler-known runtime names, optimizer guarantees, benchmark thresholds, cross-machine performance claims, stable ABI/layout/ownership, or beta maturity.

The normative exp-123 contract is .llm/EXP_123_OWNED_VECTOR_BENCHMARK_SUITE_EXTENSION_AND_WHITEPAPER_REFRESH_ALPHA.md.

4.9.20s exp-122 Composite Data Benchmark Suite Extension And Whitepaper Refresh Alpha

Status: released experimental alpha Slovo contract. Matching Glagol exp-122 benchmark-suite extension, publication refresh, and verification gates are required before broader compiler-support claims.

exp-122 does not add new source syntax or new type forms. It keeps the exp-121 language surface unchanged while widening the current benchmark/ publication baseline from five kernels to seven:

  • math-loop
  • branch-loop
  • parse-loop
  • array-index-loop
  • string-eq-loop
  • array-struct-field-loop
  • enum-struct-payload-loop

The two additional kernels are composite-data publication evidence for the already promoted exp-120 fixed-array struct-field surface and exp-121 unary non-recursive struct enum payload surface.

The exp-122 publication fixtures are:

docs/SLOVO_WHITEPAPER.md
docs/SLOVO_WHITEPAPER.pdf
docs/SLOVO_MANIFEST.pdf
WHITEPAPER.pdf

This slice does not define language-surface changes, standard-library API changes, compiler-known runtime names, optimizer guarantees, benchmark thresholds, cross-machine performance claims, stable ABI/layout/ownership, or beta maturity.

The normative exp-122 contract is .llm/EXP_122_COMPOSITE_DATA_BENCHMARK_SUITE_EXTENSION_AND_WHITEPAPER_REFRESH_ALPHA.md.

4.9.20q exp-120 Fixed Array Struct Fields Alpha

Status: released experimental alpha Slovo contract. Matching Glagol exp-120 gates are required before broader compiler-support claims.

exp-120 promotes direct immutable struct field declarations whose field types are exactly the current promoted fixed immutable array families:

  • (array i32 N)
  • (array i64 N)
  • (array f64 N)
  • (array bool N)
  • (array string N)

where N is a positive literal length.

Struct constructors may initialize those fields from matching fixed-array expressions. Immutable struct values carrying those fields may flow through locals, parameters, returns, and calls. Field access returns the declared fixed-array type, and the existing checked index form may consume that field access result with i32 index expressions.

This slice does not define zero-length arrays, mutable arrays, element mutation, field mutation, array equality, array printing, nested arrays, arrays of unsupported element kinds, slices, generics, stable ABI/layout/ownership claims, or beta maturity.

The exp-120 fixtures are:

examples/supported/array-struct-fields.slo
examples/formatter/array-struct-fields.slo

The normative exp-120 contract is .llm/EXP_120_FIXED_ARRAY_STRUCT_FIELDS_ALPHA.md.

4.9.20o exp-59 Hosted Build Optimization And Benchmark Publication Alpha

Status: released experimental alpha Slovo contract. Matching Glagol exp-59 hosted-build, publication, and verification gates are required before broader compiler-support claims.

exp-59 does not add new source syntax or new type forms. It keeps the exp-58 language surface unchanged while recording the paired Glagol hosted-build optimization and an earlier benchmark/publication baseline.

The exp-59 publication fixtures are:

docs/SLOVO_WHITEPAPER.md
docs/SLOVO_WHITEPAPER.pdf
docs/SLOVO_MANIFEST.pdf
WHITEPAPER.pdf

This slice does not define language-surface changes, standard-library API changes, optimizer guarantees, benchmark thresholds, cross-machine performance claims, stable ABI/layout/ownership, or beta maturity.

The normative exp-59 contract is .llm/EXP_59_HOSTED_BUILD_OPTIMIZATION_AND_BENCHMARK_PUBLICATION_ALPHA.md.

4.9.21 exp-37 Standard Time Source Facade Alpha

Status: released experimental alpha Slovo contract. Matching Glagol exp-37 source-check and formatter gates are required before broader compiler-support claims.

exp-37 adds staged std/time.slo with a conservative source facade over the already released exp-8 time calls:

  • monotonic_ms : () -> i32
  • sleep_ms_zero : () -> i32

monotonic_ms returns std.time.monotonic_ms. sleep_ms_zero calls std.time.sleep_ms 0 and then returns 0. The integer-returning sleep wrapper is intentionally narrow and zero-duration because user-defined unit-return functions are not generally supported today and positive-duration timing assertions remain deferred.

Current Slovo keeps standard-library organization as flat staged std/*.slo facades. A future std.slo aggregator/reexport layer, inspired by Zig's flat standard facade discipline, waits until Slovo has promoted import/search semantics for standard-library source.

This slice does not define new compiler-known std.* operation names, standard-runtime catalog entries, automatic std imports, repo-root std/ search, compiler-loaded standard-library source, replacement of compiler-known calls with source implementations, wall-clock/calendar/timezone APIs, high-resolution timers, async timers, cancellation, scheduling guarantees, stable standard-library APIs, stable ABI/layout/ownership, manifest schema changes, or beta maturity.

The exp-37 source fixture is:

std/time.slo

The normative exp-37 contract is .llm/EXP_37_STANDARD_TIME_SOURCE_FACADE_ALPHA.md.

4.9.22 exp-38 Standard Host Source Facades Alpha

Status: released experimental alpha Slovo contract. Matching Glagol exp-38 source-check and formatter gates are required before broader compiler-support claims.

exp-38 adds staged host source facades over already released random, environment, and text filesystem calls:

  • std/random.slo
  • std/env.slo
  • std/fs.slo

The source facade functions are:

  • random_i32 : () -> i32
  • random_i32_non_negative : () -> bool
  • get : (string) -> string
  • get_result : (string) -> (result string i32)
  • read_text : (string) -> string
  • read_text_result : (string) -> (result string i32)
  • write_text_status : (string, string) -> i32
  • write_text_result : (string, string) -> (result i32 i32)

Current Slovo keeps standard-library organization as flat staged std/*.slo facades. A future std.slo aggregator/reexport layer, inspired by Zig's flat standard facade discipline, waits until Slovo has promoted import/search semantics for standard-library source.

This slice does not define new compiler-known std.* operation names, standard-runtime catalog entries, automatic std imports, repo-root std/ search, compiler-loaded standard-library source, replacement of compiler-known calls with source implementations, seed/range/bytes/float/ UUID/crypto random APIs, environment mutation/enumeration, platform-specific error codes, rich host error ADTs, binary file APIs, directory traversal, streaming file IO, async file IO, richer filesystem metadata APIs, stable standard-library APIs, stable ABI/layout/ownership, manifest schema changes, or beta maturity.

The normative exp-38 contract is .llm/EXP_38_STANDARD_HOST_SOURCE_FACADES_ALPHA.md.

4.9.23 exp-39 Standard Math Extensions And Benchmark Scaffold Alpha

Status: released experimental alpha Slovo contract. Matching Glagol exp-39 source-check, formatter, benchmark scaffold, and promotion gates are required before broader compiler-support claims.

exp-39 extends staged std/math.slo with ordinary source-authored helpers over existing numeric primitives. The exp-32 abs, min, max, clamp, and square helper families remain.

exp-39 adds these helper families for i32, i64, and finite f64:

  • neg_* : (T) -> T
  • cube_* : (T) -> T
  • is_zero_* : (T) -> bool
  • is_positive_* : (T) -> bool
  • is_negative_* : (T) -> bool
  • in_range_* : (T, T, T) -> bool

The concrete promoted names are neg_i32, cube_i32, is_zero_i32, is_positive_i32, is_negative_i32, in_range_i32, neg_i64, cube_i64, is_zero_i64, is_positive_i64, is_negative_i64, in_range_i64, neg_f64, cube_f64, is_zero_f64, is_positive_f64, is_negative_f64, and in_range_f64.

These are ordinary Slovo source functions using existing same-type arithmetic and comparison, if, literals, calls, and explicit signatures. cube_* is defined in terms of multiplication through square_*. in_range_* is inclusive and returns false when the lower bound check fails; it does not validate or reorder bounds.

The matching Glagol benchmarks/math-loop/ scaffold is tooling evidence only. It compares local Slovo executable timing against C, Rust, and Python on the same machine with a shared deterministic checksum. It does not define a Slovo semantic feature, optimizer guarantee, or public performance threshold.

This slice does not define new compiler-known std.* operation names, standard-runtime catalog entries, automatic std imports, repo-root std/ search, compiler-loaded standard-library source, replacement of compiler-known calls with source implementations, trigonometry, sqrt, pow, logarithms, modulo, bit operations, unsigned or narrower integers, f32, generic math, overloads, traits, mixed numeric arithmetic, numeric containers, stable standard-library APIs, stable ABI/layout/ownership, optimizer guarantees, benchmark thresholds, manifest schema changes, or beta maturity.

The exp-39 source fixture is:

std/math.slo

The normative exp-39 contract is .llm/EXP_39_STANDARD_MATH_EXTENSIONS_AND_BENCHMARK_SCAFFOLD_ALPHA.md.

4.10 exp-5 Local Packages And Workspaces

Status: current experimental compiler-supported contract after matching Glagol exp-5 gates.

exp-5 promotes only a closed local package/workspace hygiene slice:

  • workspace slovo.toml manifests with explicit local members
  • package slovo.toml manifests with package name/version metadata
  • local path dependencies between workspace packages
  • package-qualified imports for dependency modules
  • deterministic package graph ordering
  • artifact-manifest recording of the local package graph

The minimal exp-5 fixture is:

examples/workspaces/exp-5-local/

exp-5 explicitly defers remote registries, version solving, broad lockfiles, build scripts, generated code, package publishing, semver compatibility, package-level generics, package re-exports, package archives, optional/dev/ target dependencies, registry authentication, and cross-package ABI stability.

The normative exp-5 contract is .llm/EXP_5_LOCAL_PACKAGES_ALPHA.md.

4.11 exp-6 C FFI Scalar Imports Alpha

Status: current experimental compiler-supported contract after matching Glagol exp-6 gates.

exp-6 promotes only top-level imported C function declarations with i32 parameters and i32 or internal unit returns:

(import_c c_add ((lhs i32) (rhs i32)) -> i32)

Calls to imported C functions must occur inside lexical (unsafe ...). Hosted builds use explicit local C source link inputs for the fixture, and artifact manifests record source module, import name, C symbol name, ordered parameter types, return type, link inputs, and an experimental fixture ABI marker.

The minimal exp-6 fixture is:

examples/ffi/exp-6-c-add/

exp-6 explicitly defers pointer types, allocation/deallocation, raw unsafe head execution, ownership/lifetime rules, C exports, callbacks, headers, libraries, broad linker configuration, foreign globals, foreign structs, unions, enums, stable ABI, and stable layout.

The normative exp-6 contract is .llm/EXP_6_C_FFI_SCALAR_IMPORTS_ALPHA.md.

4.12 exp-7 Test Selection And Test-Run Metadata Alpha

Status: current experimental compiler-supported contract after matching Glagol exp-7 gates.

exp-7 promotes only test selection and richer test-run metadata:

glagol test <file.slo|project> --filter <substring>
glagol --run-tests --filter <substring> <file.slo>

Filtering is a deterministic, case-sensitive substring match against decoded test display names. Selected tests execute in existing order. Non-selected tests are skipped before evaluation and counted as skipped. Zero matches is a successful run. Test reports and artifact manifests expose total discovered, selected, passed, failed, skipped, and optional filter metadata.

exp-7 explicitly defers LSP, editor protocols, debug metadata, source maps, SARIF, watch/daemon protocols, documentation comments, lint categories, benchmarks, test tags/groups/retries/sharding/parallelism, and new source language syntax.

The normative exp-7 contract is .llm/EXP_7_TEST_SELECTION_ALPHA.md.

4.13 exp-8 Host Time And Sleep Alpha

Status: released experimental compiler-supported contract after matching Slovo and Glagol exp-8 gates, 2026-05-18.

exp-8 promotes exactly two compiler-known standard-runtime operations:

std.time.monotonic_ms: () -> i32
std.time.sleep_ms: (i32) -> unit

The source call forms are ordinary calls:

(std.time.monotonic_ms)
(std.time.sleep_ms ms)

std.time.monotonic_ms returns host monotonic elapsed time in milliseconds as a non-negative i32. The epoch is implementation-owned and is not wall-clock time. If host monotonic time is unavailable, the implementation may trap with:

slovo runtime error: monotonic time unavailable

std.time.sleep_ms accepts a non-negative i32 duration in milliseconds and returns builtin unit. 0 is valid and is a no-op/yield-style sleep. Negative runtime values trap with:

slovo runtime error: sleep_ms negative duration

If a non-negative host sleep fails, the implementation may trap with:

slovo runtime error: sleep failed

The promoted names are compiler-known. They require no import, do not name user modules, do not create package dependencies, and are not stable C ABI symbols or stable runtime helper symbols. The exact promoted names are reserved from user function, export, import, local, and parameter shadowing.

The exp-8 test-runner contract is intentionally narrow: sleep_ms 0 is deterministic and returns unit; positive sleeps are not required in conformance tests; monotonic_ms tests are structural or assert only that an executed host value is non-negative. exp-8 tests must not assert elapsed-time precision, wall-clock correspondence, scheduling behavior, or high-resolution timing.

Artifact manifests record std.time.monotonic_ms and std.time.sleep_ms usage only if existing manifest patterns already record standard-runtime usage metadata. Otherwise exp-8 defers extra time-specific manifest metadata.

exp-8 explicitly defers threads, tasks, channels, async, cancellation, actors, shared memory, data-race freedom, scheduling guarantees, timers, wall-clock time, calendar dates, time zones, high-resolution timers, signal handling, source language syntax, stable ABI/layout, and stable runtime helper symbols.

The normative exp-8 release contract is .llm/EXP_8_HOST_TIME_SLEEP_ALPHA.md.

4.14 exp-9 Reliability Performance And Ecosystem Hardening

Status: released experimental compiler-supported contract after matching Slovo and Glagol exp-9 gates, 2026-05-18.

exp-9 is a hardening-only target over the released exp-8 baseline. It accepts no new source syntax, type-system behavior, standard-runtime names, manifest schema version, runtime capabilities, package features, ABI/layout promises, public performance thresholds, or beta maturity claim.

The exp-9 release requires compatibility inventory and migration notes for v2.0.0-beta.1 and exp-1 through exp-8, property/fuzz-style parser, formatter, diagnostic, project-graph, and runtime API coverage where feasible, source-reachable panic audit and disposition, benchmark fixtures or documented benchmark smoke, and release review confirming no accidental language or stable-ABI expansion.

The normative exp-9 release contract is .llm/EXP_9_RELIABILITY_PERFORMANCE_ECOSYSTEM_HARDENING.md.

4.15 exp-10 Result-Based Host Errors Alpha

Status: released experimental compiler-supported contract after matching Slovo and Glagol exp-10 gates, 2026-05-18. exp-10 is not a beta maturity claim.

exp-10 promotes exactly one new concrete result family:

(result string i32)

This family mirrors the existing (result i32 i32) support as narrowly as possible: immutable locals, parameters, returns, calls returning result values, is_ok, is_err, unwrap_ok, unwrap_err, exhaustive match arms, and formatter support. It does not promote generic result types.

exp-10 promotes exactly four additive compiler-known host calls:

std.process.arg_result: (i32) -> (result string i32)
std.env.get_result: (string) -> (result string i32)
std.fs.read_text_result: (string) -> (result string i32)
std.fs.write_text_result: (string string) -> (result i32 i32)

The only ordinary host failure code promised by exp-10 is err 1. std.fs.write_text_result returns ok 0 on success and err 1 on ordinary host write failure. The string-returning calls return ok with an immutable runtime-provided string on success and err 1 on ordinary host failure.

The exp-3 calls remain unchanged. std.process.arg, std.env.get, std.fs.read_text, and std.fs.write_text keep their exp-3 trap, empty-string, and integer-status behavior.

exp-10 fixtures are:

examples/supported/host-io-result.slo
examples/formatter/host-io-result.slo

Artifact manifests record exp-10 standard-runtime usage only if existing manifest patterns already record standard-runtime usage metadata. Otherwise no exp-10-specific manifest field or schema version change is promoted.

exp-10 explicitly defers result string Error, general host error ADTs, platform-specific error codes, error messages, result equality, result printing, mapping, nested results, result containers, new host API families, stable ABI/layout/helper symbols, and beta maturity.

The normative exp-10 release contract is .llm/EXP_10_RESULT_BASED_HOST_ERRORS_ALPHA.md.

4.16 exp-11 Basic Randomness Alpha

Status: released experimental compiler-supported contract after matching Glagol exp-11 gates passed. exp-11 is not a beta maturity claim.

exp-11 promotes exactly one compiler-known standard-runtime operation:

std.random.i32: () -> i32

Source call form:

(std.random.i32)

std.random.i32 returns a non-negative implementation-owned pseudo-random or host-random i32 suitable only for basic command-line program use. No seed API, distribution, entropy source, sequence stability, cross-platform reproducibility, or cryptographic/security suitability is promised.

If the runtime cannot produce a value, it must trap with the exact message:

slovo runtime error: random i32 unavailable

The test runner must be deterministic enough for Glagol tests. It may return an implementation-owned non-negative sample or sequence, and fixtures may assert only structural properties such as non-negativity.

exp-11 release fixtures are:

examples/supported/random.slo
examples/formatter/random.slo

Artifact manifests record exp-11 standard-runtime usage only if existing manifest patterns already record standard-runtime usage metadata. Otherwise no randomness-specific manifest field or schema version change is promoted.

exp-11 explicitly defers seed APIs, crypto/security promises, bytes APIs, ranges or bounds arguments, floats, random strings, UUIDs, broader std.random.* names, randomness-specific manifest fields, stable ABI/layout/helper symbols, and beta maturity.

The normative exp-11 release contract is .llm/EXP_11_BASIC_RANDOMNESS_ALPHA.md.

4.17 exp-12 Standard Input Result Alpha

Status: released experimental compiler-supported contract after matching Glagol exp-12 gates passed, 2026-05-18. exp-12 is not a beta maturity claim.

exp-12 promotes exactly one compiler-known standard-runtime operation:

std.io.read_stdin_result: () -> (result string i32)

Source call form:

(std.io.read_stdin_result)

std.io.read_stdin_result reads the remaining standard input as text and returns (ok string i32 text) on success. Ordinary EOF with no bytes is success with the empty string. Ordinary host/input failure returns (err string i32 1). The only ordinary failure code promised by exp-12 is err 1.

The test runner must be deterministic enough for Glagol tests. It may return an implementation-owned fixed input string as ok, including the empty string.

exp-12 release fixtures are:

examples/supported/stdin-result.slo
examples/formatter/stdin-result.slo

Existing exp-3 and exp-10 host calls stay unchanged. Artifact manifests record exp-12 standard-runtime usage only if existing manifest patterns already record standard-runtime usage metadata. Otherwise no stdin-specific manifest field or schema version change is promoted.

exp-12 explicitly defers trap-based std.io.read_stdin, line iteration, prompt APIs, terminal mode, binary stdin, streaming, async, encoding or Unicode promises beyond existing string bytes, stable ABI/layout/helper symbols, manifest schema changes, and beta maturity.

The normative exp-12 release contract is .llm/EXP_12_STDIN_RESULT_ALPHA.md.

4.18 exp-13 String Parse I32 Result Alpha

Status: released experimental compiler-supported contract after matching Glagol exp-13 gates passed, 2026-05-18. exp-13 is not a beta maturity claim.

exp-13 promotes exactly one compiler-known standard-runtime operation:

std.string.parse_i32_result: (string) -> (result i32 i32)

Source call form:

(std.string.parse_i32_result text)

std.string.parse_i32_result parses the entire input string as ASCII decimal signed i32. Accepted input has an optional leading -, followed by at least one ASCII digit 0 through 9, with no other leading, trailing, embedded, or non-ASCII digit bytes. The numeric value must be in the signed i32 range -2147483648 through 2147483647.

Success returns (ok i32 i32 value). The empty string, a lone -, non-digit bytes, leading +, whitespace, trailing bytes, non-ASCII digits, and out-of-range values return (err i32 i32 1). The only ordinary parse error code promised by exp-13 is err 1.

exp-13 adds no new result family. It uses the existing (result i32 i32) constructors, observers, unwraps, and match behavior.

The intended exp-12 composition shape is structural:

(let input (result string i32) (std.io.read_stdin_result))
(match input
  ((ok text)
    (std.string.parse_i32_result text))
  ((err code)
    (err i32 i32 code)))

Fixtures must not assume a particular stdin payload. A trailing newline read from stdin is a trailing byte and therefore returns (err i32 i32 1) unless a future contract adds trimming or line APIs.

The later exp-111 staged std/io.slo stdin helpers follow the same rule: their explicit-import fixture stays structural and payload-agnostic because the runner may provide implementation-owned stdin text.

exp-13 release fixtures are:

examples/supported/string-parse-i32-result.slo
examples/formatter/string-parse-i32-result.slo

Artifact manifests record exp-13 standard-runtime usage only if existing manifest patterns already record standard-runtime usage metadata. Otherwise no parse-specific manifest field or schema version change is promoted.

exp-13 explicitly defers trap-based std.string.parse_i32, parsing floats, bools, strings, or bytes, whitespace trimming, locale-aware parsing, base prefixes, radix arguments, underscores, plus-sign acceptance, generic parse APIs, parse error messages, richer parse error codes, parse error ADTs, Unicode digit parsing, string indexing and slicing, tokenizer/scanner APIs, stdin line APIs, stable ABI/layout/helper symbols, manifest schema changes, and beta maturity.

The normative exp-13 contract is .llm/EXP_13_STRING_PARSE_I32_RESULT_ALPHA.md.

4.19 exp-14 Standard Runtime Conformance Alignment

Status: released experimental conformance alignment. exp-14 is not a beta maturity claim.

exp-14 seeds standard-runtime conformance/readiness over the released exp-13 surface. It aligns documentation, fixture inventory, fixture byte checks, and release gates around already promoted compiler-known std.* behavior.

exp-14 adds the normative catalog:

STANDARD_RUNTIME.md

The catalog lists every promoted compiler-known std.* operation through exp-13 with signature, release, fixture, behavior/trap/result note, manifest note, and deferrals. It does not make legacy compatibility aliases such as print_i32, print_string, print_bool, or string_len into std.* operations.

exp-14 adds byte-identical canonical Slovo fixtures for the already released exp-8 host time/sleep names:

examples/supported/time-sleep.slo
examples/formatter/time-sleep.slo

The fixture uses only std.time.sleep_ms 0 and structural/non-negative std.time.monotonic_ms checks. It must not assert positive-duration timing, elapsed-time precision, scheduler behavior, wall-clock correspondence, or ordering across threads.

exp-14 requires the current supported fixture inventory to stay explicit and requires Slovo/Glagol supported and formatter fixtures to stay byte-aligned where matching files exist.

exp-14 also requires a fresh-project workflow to cover new, check, fmt --check, test, doc, and build where the hosted toolchain exists. That workflow, or an added conformance project, must exercise existing features together: modules/imports, tests, strings, std.string.concat, std.string.parse_i32_result, result match, (vec i32), (vec i64), enum match, and std.io.print_i32.

The exp-14 release gate includes Slovo and Glagol diff checks, cargo fmt --check, cargo test, ignored promotion gate, binary smoke, LLVM smoke, fixture byte-alignment checks, fresh-project workflow checks, artifact-manifest no-schema-drift checks, and release review PASS.

exp-14 adds no source syntax, type forms, runtime APIs, compiler-known std.* names, standard library functions, manifest schema version, ABI/layout promise, runtime headers/libraries, or beta maturity.

The normative exp-14 release contract is .llm/EXP_14_STANDARD_RUNTIME_CONFORMANCE_ALIGNMENT.md.

4.20 exp-15 Result Helper Standard Names Alpha

Status: released experimental alpha. exp-15 is not a beta maturity claim.

exp-15 promotes standard source-level names for the existing result helper surface:

std.result.is_ok
std.result.is_err
std.result.unwrap_ok
std.result.unwrap_err

These names are accepted only for the currently supported concrete result families:

(result i32 i32)
(result string i32)

They are the preferred names for new source. Existing unqualified result helper forms is_ok, is_err, unwrap_ok, and unwrap_err remain compatibility syntax where they are already supported.

exp-15 adds byte-identical canonical fixtures:

examples/supported/result-helpers.slo
examples/formatter/result-helpers.slo

The fixture covers ok/err observation and unwraps for both supported result families.

exp-15 adds no result mapping, chaining, unwrap_or, option helper standard names, new payload families, generic result, user-defined error payloads, enum payloads, manifest schema changes, runtime ABI/layout promises, stable helper symbols, runtime headers/libraries, or beta maturity.

The normative exp-15 release contract is .llm/EXP_15_RESULT_HELPER_STANDARD_NAMES_ALPHA.md.

5. Slice 1: Struct Value Flow

Status: promoted as examples/supported/struct-value-flow.slo.

5.1 Goal

v0 structs can be declared, constructed, and immediately field-accessed:

(. (Point (x 20) (y 22)) x)

v1 should make structs usable as ordinary values in the supported subset. Later promoted slices may broaden the direct field-type family while reusing the same constructor, local, parameter, return, call, and field-access flow.

The first v1 struct slice promotes:

  • struct locals
  • struct parameters
  • struct returns
  • calls returning structs
  • field access through stored struct values

Struct field mutation and whole-struct value mutation are intentionally deferred beyond v1. They must not be claimed as supported until a later promotion specifies syntax, typed-core meaning, lowering, formatting, diagnostics, examples, and tests at the same standard.

5.2 Surface Syntax

Struct declaration syntax remains:

(struct Point
  (x i32)
  (y i32))

Constructor syntax remains:

(Point (x 20) (y 22))

Local storage uses the existing local declaration shape:

(let p Point (Point (x 20) (y 22)))
(. p x)

Function parameters and returns use the nominal struct name:

(fn point_x ((p Point)) -> i32
  (. p x))

(fn make_point ((x i32) (y i32)) -> Point
  (Point (x x) (y y)))

5.3 Type Rules

  • Struct names are nominal types.
  • Struct names must be declared before use.
  • A struct local declared with let is immutable and supported.
  • A struct local declared with var is deferred beyond v1 until field/value mutation is explicitly promoted.
  • A function parameter of struct type is immutable and supported.
  • A function may return a struct value when the struct has only supported v1 field types.
  • A call may produce a struct value when the callee return type is a declared supported struct.
  • Field access through a value of known struct type returns the field type.
  • The first struct-flow slice supports i32 fields. exp-18 additionally supports direct fields whose types are current user-defined enum names. exp-19 additionally supports direct bool and immutable string fields.
  • exp-29 additionally supports direct immutable i64 and finite f64 fields.
  • exp-120 additionally supports direct fixed immutable array fields over i32, i64, f64, bool, and string element families with positive literal lengths.
  • Nested struct fields remain deferred unless separately specified.

5.4 Lowering Direction

The typed core represents struct values as nominal typed expressions. The promoted slice requires checked forms for:

  • struct constructor expressions
  • field access expressions
  • immutable struct local bindings
  • struct-typed parameters
  • struct-typed return values
  • calls whose result type is a struct

The explicit constructor and field-access forms are:

StructConstruct {
  name,
  fields,
  result_type
}

StructFieldAccess {
  value,
  field,
  result_type
}

Glagol uses a compiler-owned LLVM aggregate representation for v1 struct values, but v1 does not promise a stable external ABI or cross-module layout. Source field declaration order currently drives the implementation aggregate order inside a closed compilation unit; it is not a public ABI promise.

The implementation prioritizes correctness and verification over layout optimization.

5.5 Formatter Rules

Formatter behavior preserves v0 style:

  • top-level struct declarations are multi-line
  • constructor expressions with inline i32 fields may stay inline
  • local declarations containing constructors follow existing local formatting
  • field access remains (. value field)

If constructor expressions become too complex for one line, v1 must define a canonical multiline layout before support is claimed.

5.6 Diagnostics

The promoted struct-flow slice requires the existing structured diagnostic format: machine-readable code, source span, line/column range, and any useful expected/found or hint fields.

The promoted slice is covered by Glagol diagnostics for:

  • constructor field type mismatch
  • missing constructor field
  • unknown constructor field
  • constructor field order mismatch if declaration order remains required
  • unsupported struct field type
  • empty struct declaration
  • unknown field access
  • MutableStructLocalUnsupported when a struct local uses var

Before v1 release, the diagnostic matrix must also cover:

  • unknown struct type in local declaration
  • unknown struct type in function parameter
  • unknown struct type in function return
  • duplicate struct declarations
  • duplicate struct fields
  • duplicate constructor fields
  • field access on non-struct value
  • unsupported struct field/value mutation because mutation remains deferred
  • unsupported nested struct field if nested structs remain deferred

5.7 Fixtures

The first v1 struct-flow promotion adds:

examples/supported/struct-value-flow.slo
examples/formatter/struct-value-flow.slo

Later promoted struct-field slices additionally use:

examples/supported/array-struct-fields.slo
examples/formatter/array-struct-fields.slo

Glagol mirrors these with compiler fixtures and a mutable-struct-local diagnostic snapshot. monorepo promotion verification must run both the default Glagol promotion gate and its ignored Slovo/Glagol alignment gate.

6. Slice 2: Option/Result Value Flow And Payload Access

Status: promoted as examples/supported/option-result-flow.slo and examples/supported/option-result-payload.slo.

6.1 Goal

v0 option/result support allowed only direct constructor returns. The v1 option/result flow slice makes first-pass i32 option/result values usable as ordinary immutable values. The payload-access extension promotes explicit trap-based unary extraction for i32 payloads. The v1.4 core-language expansion later promotes source-level match for the same concrete option/result families while keeping broader algebraic-data-type behavior deferred.

The promoted option/result contract supports:

  • immutable (option i32), (option i64), (option f64), (option bool), (option string), and (result i32 i32) locals
  • (option i32), (option i64), (option f64), (option bool), (option string), and (result i32 i32) function parameters
  • calls returning option/result values
  • tag observation with is_some, is_none, is_ok, and is_err
  • explicit payload extraction with unwrap_some, unwrap_ok, and unwrap_err

The exp-10 release additionally promotes only the concrete (result string i32) family for result-based host errors. That family follows the same result value-flow, observer, unwrap, and match rules where the ok payload is string and the err payload is i32.

Direct constructor-return functions remain part of the v0 baseline. Returning option/result values from locals, call results, or value-producing if expressions is not part of this promoted slice until fixtures and tests cover those forms.

6.2 Surface Syntax

Constructors remain:

(some i32 value)
(none i32)
(some i64 value)
(none i64)
(some f64 value)
(none f64)
(some bool value)
(none bool)
(some string value)
(none string)
(ok i32 i32 value)
(err i32 i32 value)

Local storage uses the existing local declaration shape:

(let value (option i32) (some i32 42))
(let wide (option i64) (some i64 42i64))
(let fraction (option f64) (some f64 42.5))
(let flag (option bool) (some bool true))
(let text (option string) (some string "hello"))
(let status (result i32 i32) (ok i32 i32 42))

Function parameters and returns use the existing type forms:

(fn option_score ((value (option i32))) -> i32
  (if (is_some value)
    1
    0))

(fn option_wide_score ((value (option i64))) -> i32
  (if (is_some value)
    1
    0))

(fn option_fraction_score ((value (option f64))) -> i32
  (if (is_some value)
    1
    0))

(fn option_flag_score ((value (option bool))) -> i32
  (if (is_some value)
    1
    0))

(fn option_text_score ((value (option string))) -> i32
  (if (is_some value)
    1
    0))

(fn result_failure_score ((value (result i32 i32))) -> i32
  (if (is_err value)
    1
    0))

The promoted tag observers are unary forms:

(is_some option-value)
(is_none option-value)
(is_ok result-value)
(is_err result-value)
(std.result.is_ok result-value)
(std.result.is_err result-value)

The promoted payload extractors are unary forms:

(unwrap_some option-value)
(unwrap_ok result-value)
(unwrap_err result-value)
(std.result.unwrap_ok result-value)
(std.result.unwrap_err result-value)

They are intentionally trap-based extraction forms. They are not pattern matching and do not introduce user-catchable exceptions.

For result values, exp-15 makes the std.result.* forms the preferred source surface. The unqualified result helpers remain compatibility syntax where they were already supported. Option helper standard names are not promoted.

6.3 Type Rules

  • The promoted slice supports (option i32), (option i64), (option f64), (option bool), (option string), (result i32 i32), the exp-10 family (result string i32), and the exp-25 family (result i64 i32).
  • Payloads and extraction beyond those concrete families remain unsupported; unwrap_ok returns string for (result string i32) and i64 for (result i64 i32).
  • Option/result locals are supported only with immutable let.
  • Option/result parameters are immutable.
  • is_some and is_none require (option i32), (option i64), (option f64), (option bool), or (option string) and return bool.
  • is_ok and is_err require (result i32 i32) or the exp-10 family (result string i32) and return bool.
  • std.result.is_ok and std.result.is_err have the same result-family type rules as the legacy unqualified compatibility observers.
  • unwrap_some requires (option i32), (option i64), (option f64), (option bool), or (option string) and returns the matching concrete payload type.
  • unwrap_ok requires (result i32 i32) and returns i32, or requires the exp-10 family (result string i32) and returns string.
  • unwrap_err requires (result i32 i32) or the exp-10 family (result string i32) and returns i32.
  • std.result.unwrap_ok and std.result.unwrap_err have the same result-family type rules and trap behavior as the legacy unqualified compatibility extractors.
  • unwrap_some traps at runtime when its operand is none.
  • unwrap_ok traps at runtime when its operand is err.
  • unwrap_err traps at runtime when its operand is ok.
  • Source-level option/result match for (option i32), (option i64), (option f64), (option bool), (option string), and (result i32 i32) is promoted by v1.4. exp-10 promotes the same result match shape for (result string i32). Mapping remains deferred.
  • Option/result equality remains unsupported and deferred beyond v1.
  • Printing option/result values remains unsupported and deferred beyond v1.
  • Nested option/result values, arrays of options/results, and structs containing option/results remain deferred beyond v1.
  • Additional option/result payload families beyond the current (option i32), (option i64), (option f64), (option bool), (option string), and released concrete result slices remain deferred.
  • Payload traps are not user-catchable exceptions in v1; user-catchable exceptions remain deferred beyond v1.

6.4 Lowering Direction

The typed core represents current option/result values as tagged concrete payload aggregates. The promoted slice requires checked forms for:

  • option/result constructors
  • immutable option/result local bindings
  • option/result typed parameters
  • option/result typed return values
  • calls whose result type is option/result
  • tag observers
  • payload extractors

Glagol uses a compiler-owned tagged aggregate representation for current option/result values. The tag indicates some/ok when true and none/err when false. This is closed-module implementation behavior, not a stable external ABI or layout promise.

Payload extraction must lower through an explicit tag check before payload access. On the non-matching tag, the generated runtime path traps. The exact trap helper, block names, aggregate layout, and ABI are implementation-owned, but the check-before-payload-access shape is part of the v1 contract so Glagol tests can verify it.

The v1.2 runtime error messages for payload traps are stable:

slovo runtime error: unwrap_some on none
slovo runtime error: unwrap_ok on err
slovo runtime error: unwrap_err on ok

The message is written to stderr with a trailing newline. The process then exits with code 1. These traps are not user-catchable Slovo exceptions.

6.5 Formatter Rules

Formatter behavior preserves the current compact style:

  • constructors stay inline when their payload expression is compact
  • option/result local declarations use one-line local formatting
  • option/result parameter and return types print as (option i32), (option i64), (option string), and (result i32 i32)
  • exp-10 (result string i32) parameter and return types print in the same canonical type-form style
  • tag observers print as unary expression forms
  • payload extractors print as unary expression forms
  • exp-15 std.result.* observers and payload extractors print as unary expression forms and remain inline when used as expressions

v1.4 promotes option/result match; its canonical multiline layout is defined in section 4.2 and .llm/V1_4_CORE_LANGUAGE_EXPANSION.md.

6.6 Diagnostics

The promoted slice keeps the existing structured diagnostic format. It is covered by Glagol diagnostics for:

  • malformed option/result constructors
  • non-i32 option/result payload types
  • constructor payload type mismatch
  • option/result equality
  • option/result printing
  • option observers applied to non-option values
  • result observers applied to non-result values
  • unwrap_some applied to non-option values
  • unwrap_ok or unwrap_err applied to non-result values
  • std.result.* helpers applied to non-result values or unsupported result families

Before v1 release, the diagnostic matrix must also cover:

  • non-i32 option/result payloads in function parameter position
  • non-i32 option/result payloads in function return position
  • unsupported option/result mapping if such forms become source-reachable without promotion

6.7 Fixtures

The option/result value-flow and payload-access promotion adds:

examples/supported/option-result-flow.slo
examples/formatter/option-result-flow.slo
examples/supported/option-result-payload.slo
examples/formatter/option-result-payload.slo

The exp-10 result-based host errors release adds:

examples/supported/host-io-result.slo
examples/formatter/host-io-result.slo

The exp-13 string parse i32 result release adds:

examples/supported/string-parse-i32-result.slo
examples/formatter/string-parse-i32-result.slo

The exp-15 result helper standard names release adds:

examples/supported/result-helpers.slo
examples/formatter/result-helpers.slo

Glagol mirrors these with compiler fixtures, formatter coverage, test-runner coverage, LLVM shape checks, runtime trap checks, observer diagnostics, and payload-extractor diagnostics.

7. Slice 3: Array Value Flow And Dynamic Indexing

Status: promoted as examples/supported/array-value-flow.slo, widened by exp-117 through examples/supported/array-direct-scalars.slo and examples/supported/array-direct-scalars-value-flow.slo, then broadened again by exp-118 through examples/supported/array-string.slo and examples/supported/array-string-value-flow.slo.

7.1 Goal

v0 arrays support fixed (array i32 N) constructors, immutable array locals initialized from matching constructors, and literal indexing. The v1 array slice keeps those v0 forms valid and broadens fixed-size direct scalar arrays plus one concrete string array lane as ordinary values in the supported subset, including immutable locals initialized from matching array-valued expressions.

The promoted slice supports:

  • fixed array types (array T N) with positive literal N when T is one of i32, i64, f64, bool, or string
  • fixed array constructors over those promoted element families
  • immutable array locals initialized from any supported expression that checks as the exact declared (array T N) type
  • (array T N) function parameters
  • (array T N) function returns
  • calls returning (array T N) values
  • dynamic (index array-expr index-expr) when index-expr checks as i32

The slice intentionally does not promote array mutation, arrays of other unsupported element types, zero-length arrays, slices, array equality, printing arrays, nested arrays, unchecked indexing, or any stable ABI/layout promise.

7.2 Surface Syntax

Fixed array type syntax remains:

(array T N)

For this slice, T is exactly one of i32, i64, f64, bool, or string.

Constructor syntax remains:

(array T value...)

Function parameters and returns may use fixed direct scalar or string array types:

(fn pick ((values (array i64 3)) (i i32)) -> i64
  (index values i))

(fn make_values () -> (array bool 3)
  (array bool true false true))

(fn make_words () -> (array string 3)
  (array string "sun" "moon" "star"))

A call may return an array value and feed another supported array expression position:

(fn pick_from_return ((i i32)) -> bool
  (index (make_values) i))

Immutable array locals may be initialized from any supported array-valued expression with the exact declared type:

(fn local_array_flow ((i i32)) -> f64
  (let values (array f64 3) (array f64 1.0 2.0 3.0))
  (index values i))

Index syntax remains:

(index array-expr index-expr)

For this slice, index-expr may be any supported expression that checks as i32. Literal indexing remains valid.

7.3 Type Rules

  • N in (array T N) is a positive source integer literal in type position.
  • The promoted element types are exactly i32, i64, f64, bool, and string.
  • Array constructors produce (array T count) values.
  • Constructor values are checked left to right and must each check as T.
  • In an expected-type context, (array T count) is valid for (array T N) only when count == N.
  • Immutable array locals declared with let may be initialized by any supported expression that checks as exactly the declared (array T N) type, including direct constructors, parameters, and call results.
  • This slice does not promote mutable array locals.
  • Function parameters may have type (array T N).
  • Function returns may have type (array T N).
  • Calls may produce (array T N) when the callee return type is a promoted fixed array type.
  • Supported array values may be passed to parameters with the exact same (array T N) type.
  • Returning an array expression requires the exact declared (array T N) return type.
  • index requires an array expression that checks as (array T N). Promoted index bases are any supported expression with that type, including immediate constructors, immutable array locals, array parameters, and calls returning promoted fixed arrays.
  • index requires an index expression that checks as i32.
  • index returns T.
  • Array equality remains unsupported.
  • Printing arrays remains unsupported.
  • Nested arrays and arrays of structs/options/results remain deferred.

7.4 Bounds Behavior

Literal out-of-bounds indexing remains a structured diagnostic. A literal index must satisfy 0 <= index < N; if it does not, checking fails before lowering.

Dynamic indexing must be checked at runtime by Glagol. For every accepted dynamic index expression, the lowered program must evaluate the array expression once, evaluate the index expression once, then branch through an explicit bounds check equivalent to:

0 <= index && index < N

If the check succeeds, the selected element is read and returned. If the check fails, execution must enter an explicit runtime trap path before any out-of-bounds element access occurs. The trap path may be compiler-owned and is not a stable Slovo runtime ABI in v1, but it must be visible in lowering or LLVM output well enough for Glagol tests to verify that dynamic array access is not unchecked.

Top-level tests that trigger the runtime trap should be reported as trapped tests by Glagol's test runner once that runner covers trap results. This slice does not require Slovo to standardize a user-catchable exception value.

The v1.2 runtime error message for a failed dynamic bounds check is stable:

slovo runtime error: array index out of bounds

The message is written to stderr with a trailing newline. The process then exits with code 1. For glagol test, the trapped top-level test is reported as a trapped test and the command exits with code 1. For glagol build, the produced executable exits with code 1.

7.5 Lowering Direction

The typed core represents promoted arrays as fixed-length aggregate values with compiler-owned layout. The promoted slice requires checked forms for:

  • fixed promoted array types
  • fixed promoted array constructor expressions
  • immutable array local bindings whose initializer checks as the exact declared fixed promoted array type
  • array-typed parameters
  • array-typed return values
  • calls whose result type is a fixed promoted array
  • literal and dynamic array indexing

The array index core form records whether bounds were proven at check time or must be checked at runtime:

ArrayIndex {
  array: TExpr<Array(element_type, length)>,
  index: TExpr<i32>,
  bounds: LiteralInBounds | RuntimeChecked,
  result_type: element_type,
  span,
  array_span,
  index_span
}

Literal in-bounds indices may lower to direct aggregate extraction. Dynamic indices lower to a runtime-checked element access with a trap edge. Glagol may copy fixed arrays between local storage, parameters, returns, and call results using any compiler-owned aggregate representation, but v1 does not promise a stable LLVM, C, FFI, or cross-module ABI layout.

7.6 Formatter Rules

Formatter behavior preserves the current compact array style:

  • (array T N) types print inline
  • constructors with inline promoted values print as (array T value...)
  • array local declarations print with existing one-line local formatting when their initializer is inline
  • array parameter and return types print inline in function signatures
  • index expressions print as (index array-expr index-expr) when both operands are inline
  • function and test body indentation follows the existing one-body-form-per-line rule

If later slices add multiline array constructors, slices, or pattern-style array forms, those slices must define their own canonical layouts.

7.7 Diagnostics

The promoted slice keeps the existing structured diagnostic format. It is covered by the v0 array diagnostics for malformed types, malformed constructors, unsupported element types, zero-length arrays, empty constructors, constructor length mismatch, element type mismatch, malformed index syntax, indexing non-arrays, non-i32 index expressions, literal out-of-bounds indices, mutable array locals, array equality, array printing, and array mutation.

The v1 promotion changes the first-pass UnsupportedArraySignatureType boundary: exact (array T N) parameters and returns are now supported for the direct scalar and string element families. Unsupported array signature diagnostics remain required for other unsupported element types, zero-length arrays, nested arrays, arrays containing unsupported value types, and any future array type form not promoted here.

Dynamic indices are no longer rejected as DynamicArrayIndexUnsupported when the index expression checks as i32. That diagnostic remains appropriate only for compilers or modes that explicitly target the v0 baseline.

The promoted array slice also requires diagnostics or lowering checks for these source-reachable promoted boundaries:

  • array return expression type mismatch
  • array argument type mismatch
  • array local initializer type mismatch when an immutable array local initializer does not check as the exact declared fixed promoted array type
  • missing runtime trap lowering if a dynamic index reaches LLVM unchecked

Future diagnostics for newly promoted array forms remain separate from this slice. In particular, later slices that promote mutable arrays, array mutation, zero-length arrays, other unsupported array element types, nested arrays, slices, equality, printing, unchecked indexing, or stable layout must define their own diagnostics before claiming support.

7.8 Fixtures

The current array fixtures for this slice are:

examples/supported/array-direct-scalars.slo
examples/supported/array-value-flow.slo
examples/supported/array-direct-scalars-value-flow.slo
examples/supported/array-string.slo
examples/supported/array-string-value-flow.slo
examples/formatter/array-direct-scalars.slo
examples/formatter/array-value-flow.slo
examples/formatter/array-direct-scalars-value-flow.slo
examples/formatter/array-string.slo
examples/formatter/array-string-value-flow.slo

Glagol mirrors these with compiler fixtures, formatter coverage, test-runner coverage, LLVM checks that dynamic indexing branches to an explicit trap path, and diagnostics for unsupported array forms.

8. Slice 4: Runtime Strings And Practical Runtime Values

Status: promoted as examples/supported/string-print.slo, extended in v1.2 through examples/supported/string-value-flow.slo and examples/supported/print-bool.slo, then given v1.5 standard-runtime names in examples/supported/standard-runtime.slo. exp-1 adds examples/supported/owned-string-concat.slo as the first owned-runtime-string compiler-supported fixture. exp-13 adds examples/supported/string-parse-i32-result.slo as the first string parse result compiler-supported fixture. exp-34 adds examples/supported/string-parse-bool-result.slo for the exact lowercase bool parse result slice. 1.0.0-beta.16 adds byte-oriented string scanning and token-boundary helpers through the std.string source facade and explicit examples.

8.1 Goal

The first runtime string slice promoted enough string behavior to print compiler-emitted immutable source literals from ordinary programs. Slovo v1.2 extends that slice conservatively so immutable strings can flow through small programs without introducing allocation or ownership. exp-1 adds one narrow heap-created owned-string operation, std.string.concat, while preserving the same source type and keeping memory management out of user code.

The promoted slice supports:

  • source string literals as immutable runtime literals
  • ASCII-plus-current-escape literal semantics, without a full Unicode promise
  • legacy compiler/runtime compatibility alias (print_string value)
  • direct string-literal printing in a normal i32 function body
  • immutable string locals with let
  • string parameters and string returns
  • calls returning strings
  • string equality with =
  • string byte length with legacy compatibility alias (string_len value)
  • top-level tests whose final expression uses string equality or compares a string length result
  • bool printing with legacy compatibility alias (print_bool value)
  • v1.5 source-level standard-runtime names for the same print and string length behavior: std.io.print_i32, std.io.print_string, std.io.print_bool, and std.string.len
  • exp-1 std.string.concat, returning an immutable runtime-owned string from two string operands
  • exp-13 released std.string.parse_i32_result, returning an existing (result i32 i32) value from an entire ASCII decimal signed i32 string
  • exp-34 released std.string.parse_bool_result, returning (result bool i32) for exact lowercase true/false parsing with err 1 ordinary failures
  • 1.0.0-beta.16 byte-oriented string helpers: std.string.byte_at_result, std.string.slice_result, std.string.starts_with, and std.string.ends_with

Everything else in the string family remains deferred until separately specified, implemented, diagnosed, formatted, and tested.

8.2 Surface Syntax

String literals continue to use double quotes:

"hello"

The first promoted runtime string consumer is:

(print_string "hello")

print_string has exactly one argument of type string, returns builtin unit, and prints the string followed by a newline. Like print_i32, it is a legacy compiler/runtime compatibility alias paired with runtime lowering. v1.5 promotes the source-level standard-runtime name std.io.print_string for the same behavior. Neither spelling is a user-defined function, import, foreign function, package dependency, or stable runtime ABI.

v1.2 promotes string value flow:

(let value string "hello")

(fn echo ((value string)) -> string
  value)

(fn call_return () -> string
  (echo "hello"))

v1.2 promotes string equality and length through the legacy alias:

(= "hello" (call_return))
(string_len "hello")

= accepts two string operands and returns bool. String equality compares the decoded byte sequence before the trailing NUL byte. It is not locale-sensitive and makes no Unicode normalization promise.

string_len has exactly one string argument and returns i32. It counts decoded bytes before the trailing NUL byte. It is not a Unicode scalar count, grapheme count, display width, or locale-sensitive length.

v1.5 promotes std.string.len for the same behavior:

(std.string.len "hello")

exp-1 promotes std.string.concat as the first heap-created string operation:

(std.string.concat "hello, " "slovo")

std.string.concat has exactly two string arguments and returns string. The result is immutable and runtime-owned by the compiler/runtime. It is usable with existing string equality, std.string.len, std.io.print_string, string locals, parameters, returns, and calls returning string. No import is required, no legacy alias is introduced, and no user-visible allocation or deallocation form is exposed.

1.0.0-beta.16 adds byte-oriented string scanning and token-boundary helpers:

(std.string.byte_at_result "slovo" 0)
(std.string.slice_result "slovo" 1 3)
(std.string.starts_with "slovo" "slo")
(std.string.ends_with "slovo" "ovo")

std.string.byte_at_result has one string argument and one i32 index. It returns ok byte for valid zero-based byte indexes before the trailing NUL and err 1 for ordinary invalid indexes.

std.string.slice_result has one string argument, one i32 start byte, and one i32 byte count. It returns ok text for a valid range and err 1 for an ordinary invalid range. The successful result is runtime-owned and immutable. Allocation failure may trap with the existing string allocation failure policy.

std.string.starts_with and std.string.ends_with compare byte prefixes and suffixes and return bool. Empty prefixes and suffixes match. These helpers do not perform Unicode normalization, grapheme segmentation, display-width measurement, locale-sensitive matching, or case-folding.

v1.2 promotes bool printing through the legacy alias:

(print_bool (= "hello" "hello"))

print_bool has exactly one bool argument, returns builtin unit, and prints true or false followed by a newline. v1.5 promotes std.io.print_bool for the same behavior. v1.5 also promotes std.io.print_i32 for the same behavior as legacy print_i32.

Slovo v1.5 does not define a broader standard-runtime printing contract. The only supported printing forms are legacy compatibility aliases print_i32, print_string, and print_bool, plus source-level standard-runtime names std.io.print_i32, std.io.print_string, and std.io.print_bool. Unit printing, composite value printing, overloaded print forms, file IO, imports, packages, and stable runtime print ABI bindings remain deferred beyond v1.5.

A supported ordinary program may use print_string or std.io.print_string as a sequential body form before an i32 final expression:

(fn main () -> i32
  (print_string "hello")
  0)

print_string and std.io.print_string are not supported as the final expression of an i32 function or bool test because they return builtin unit.

bool remains a checked value type for promoted conditions, tests, option/result observers, string equality, print_bool, and std.io.print_bool. unit remains an internal builtin result type for unit-producing forms such as set, while, legacy print aliases, and std.io.print_* calls. User-declared unit return types, unit parameters, unit locals, stored unit values, print_unit, and using unit as a user-visible final result remain unsupported in v1.2.

8.3 Literal Semantics

The promoted literal domain is intentionally narrow:

  • unescaped literal content is ASCII source text
  • the required current escapes are newline \n, tab \t, quote \", and backslash \\
  • decoded literal bytes are immutable
  • embedded NUL bytes and arbitrary byte escapes are not part of the promoted slice
  • this slice makes no promise that arbitrary Unicode source text is accepted, normalized, encoded, compared, or printed correctly

For the v1.2/v1.5 slice, the source literal denotes a runtime literal, not an owned heap string. Every promoted string value originates from a source string literal or from propagating such a value through an immutable local, parameter, return, or call result.

exp-1 extends this by allowing one heap-created string source: std.string.concat. The result is runtime-owned and immutable, but ownership is not source-visible. No Slovo program can mutate, manually allocate, free, retain, or otherwise manage the storage behind a promoted string value.

8.4 Type Boundary

The checker assigns source string literals the builtin type string.

Promoted uses of string values:

  • direct argument to print_string or std.io.print_string
  • immutable let locals with type string
  • mutable var locals with type string plus same-type set reassignment
  • function parameters with type string
  • function returns with type string
  • call results whose declared return type is string
  • operands to = when both operands check as string
  • argument to string_len or std.string.len
  • exp-1 arguments to and result from std.string.concat
  • 1.0.0-beta.16 byte indexes and byte ranges through std.string.byte_at_result and std.string.slice_result
  • 1.0.0-beta.16 prefix and suffix byte comparisons through std.string.starts_with and std.string.ends_with

Still deferred:

  • string ordering or comparison other than equality
  • string values inside arrays or vectors
  • language slice/view syntax or borrowed substring views
  • concatenation beyond exp-1 std.string.concat
  • unchecked indexing or character/grapheme indexing
  • ownership or lifetime annotations
  • user-defined runtime bindings involving string

8.5 Runtime Representation And Lowering

The runtime representation for this slice is still a borrowed immutable NUL-terminated byte pointer to compiler-emitted static storage. v1.2 does not add allocation.

Required lowering shape:

  • each promoted string literal lowers to immutable static storage containing the decoded ASCII-plus-escape bytes followed by one trailing NUL byte
  • string locals, parameters, returns, and call results lower as copies of that borrowed immutable pointer value
  • (print_string value) lowers to a runtime call that receives a borrowed pointer to that storage and writes the bytes followed by a newline
  • (print_bool value) lowers to a runtime call that writes true\n or false\n
  • string equality lowers to a byte-sequence comparison before the trailing NUL
  • (string_len value) lowers to a byte count before the trailing NUL
  • v1.5 std.io.print_string, std.io.print_bool, and std.string.len lower through the same implementation paths as their legacy aliases
  • exp-1 std.string.concat lowers to a runtime-owned immutable string allocation, byte copy, and trailing terminator write; allocation failure traps with slovo runtime error: string allocation failed
  • 1.0.0-beta.16 std.string.byte_at_result, std.string.slice_result, std.string.starts_with, and std.string.ends_with operate over bytes before the trailing NUL; invalid byte indexes/ranges return err 1, and successful slice_result returns a runtime-owned immutable string
  • since embedded NUL is not promoted, printing observes the whole decoded literal and equality/length observe the whole decoded value

Typed-core shape:

StringLiteral {
  bytes,
  type: string,
  span
}

CallIntrinsic {
  name: print_string,
  args: [StringLiteral],
  type: unit,
  span
}

StringLet {
  name,
  type: string,
  value: TExpr<string>,
  span
}

CallIntrinsic {
  name: string_len,
  args: [TExpr<string>],
  type: i32,
  span
}

StringEquals {
  left: TExpr<string>,
  right: TExpr<string>,
  type: bool,
  span
}

CallIntrinsic {
  name: print_bool,
  args: [TExpr<bool>],
  type: unit,
  span
}

StdStringConcat {
  left: TExpr<string>,
  right: TExpr<string>,
  type: string,
  span
}

This representation is not a stable Slovo ABI. Slovo v1 does not promise a C signature, symbol name, pointer type spelling, address space, literal deduplication behavior, static object layout, allocator interaction, or FFI contract for strings. exp-1 also does not promise a stable runtime-owned string layout, allocator, cleanup timing, helper symbol, or C ABI.

8.6 Formatter Rules

Formatter behavior preserves the current compact call style:

(fn main () -> i32
  (print_string "hello")
  0)

String literals stay inline when used as the direct argument to print_string, as immutable string local initializers, as string returns, as string equality operands, and as string_len arguments. String parameter and return types print as string. string_len and print_bool use the same compact call style as other promoted intrinsics. v1.5 std.io.print_* and std.string.len calls use the same compact call style. exp-1 std.string.concat uses the same compact call style and remains inline when nested in std.io.print_string, std.string.len, equality, local initializers, returns, and user calls. 1.0.0-beta.16 string scanning helpers use the same compact call style. The formatter must preserve the decoded literal meaning when re-emitting the current supported escapes.

8.7 Diagnostics

The promoted slice keeps the existing structured diagnostic format. It is acceptable to reuse general diagnostics when the expected/found data is clear.

Required promoted-boundary diagnostics:

  • malformed or unterminated string literals must be reported as structured lexer/parser diagnostics before checking
  • (print_string) and (print_string a b) must report an arity diagnostic with expected 1
  • (print_string value) where value is not string must report a type diagnostic with expected string and found checked type
  • using print_string as an i32 function result or bool test result must report the existing result-type diagnostic for found unit
  • (string_len) and (string_len a b) must report an arity diagnostic with expected 1
  • (string_len value) where value is not string must report a type diagnostic with expected string and found checked type
  • (= left right) where exactly one operand is string must report a type diagnostic; both operands must be string for string equality
  • (print_bool) and (print_bool a b) must report an arity diagnostic with expected 1
  • (print_bool value) where value is not bool must report a type diagnostic with expected bool and found checked type
  • (std.string.concat), (std.string.concat a), and (std.string.concat a b c) must report an arity diagnostic with expected 2
  • (std.string.concat left right) where either operand is not string must report a type diagnostic with expected string and the found checked type
  • using std.string.concat where a non-string result is required must report the existing result-type diagnostic for found string
  • declaring, exporting, importing, or binding a name that shadows std.string.concat must produce a structured reserved-name diagnostic
  • print_unit must report an unsupported intrinsic/form diagnostic, or a structured unknown-call diagnostic if the implementation has no intrinsic entry for it
  • string ordering/comparison other than equality, string containers beyond the current direct struct fields, current fixed string arrays, current direct fixed-array struct fields, and current concrete option/result families, language slice/view syntax, concatenation beyond exp-1 std.string.concat, unchecked indexing, character/grapheme indexing, mutation, user-visible allocation, user-visible deallocation, and user-defined runtime bindings must remain unsupported with structured diagnostics or explicit backend-feature diagnostics; they must not reach a backend panic

Future diagnostics for broader string features remain separate from this slice.

8.8 Fixtures

The runtime string promotions add:

examples/supported/string-print.slo
examples/supported/string-value-flow.slo
examples/supported/print-bool.slo
examples/formatter/string-print.slo
examples/formatter/string-value-flow.slo
examples/formatter/print-bool.slo

exp-1 adds:

examples/supported/owned-string-concat.slo
examples/formatter/owned-string-concat.slo

The exp-1 fixture files are current compiler-supported fixtures after the matching Glagol exp-1 release gate.

Glagol mirrors these with compiler fixtures, formatter coverage, test-runner coverage, LLVM checks that literals lower to immutable static NUL-terminated storage, executable/runtime checks that print_string prints the decoded literal plus a newline, string equality and length checks, print_bool stdout checks, and diagnostics for the deferred boundaries.

8.9 v1.5 Standard Runtime Names

v1.5 adds source-level standard-runtime names for stable v1.2 runtime behavior:

(std.io.print_i32 value)
(std.io.print_string value)
(std.io.print_bool value)
(std.string.len value)

These names are compiler-known. They are not user modules, not importable module members, not package dependencies, not foreign functions, and not stable C ABI symbols. No import is required to call them.

The promoted names have exactly the same type and behavior contracts as the legacy compatibility aliases:

  • std.io.print_i32: one i32, returns builtin unit
  • std.io.print_string: one string, returns builtin unit
  • std.io.print_bool: one bool, returns builtin unit
  • std.string.len: one string, returns i32

Unknown or unpromoted std.* calls must produce a structured diagnostic; the suggested code is UnsupportedStandardLibraryCall. Arity and type mismatches for the promoted std.* calls use existing arity/type diagnostics where applicable. The promoted names are reserved from user function/export shadowing.

v1.5 adds:

examples/supported/standard-runtime.slo
examples/formatter/standard-runtime.slo

8.10 exp-1 Owned Runtime String Name

exp-1 adds one standard-runtime name:

(std.string.concat left right)

The name is compiler-known and has the exact signature:

std.string.concat: (string, string) -> string

The result is an immutable runtime-owned string. Existing string operations do not distinguish source-visible value kinds: literal-backed strings and runtime-owned strings both have type string.

std.string.concat is not an importable module member, not a user-defined function, not a package dependency, not a foreign function, and not a stable C ABI symbol. The implementation may lower through any runtime helper and allocator strategy that preserves the source contract.

No source-visible deallocation form is promoted. Runtime-owned string cleanup is an implementation responsibility and is not observable except that supported safe source must not require manual free and must not expose use-after-free.

Allocation failure traps with:

slovo runtime error: string allocation failed

The trap is process-terminating and exits with code 1.

8.11 exp-13 String Parse I32 Result Name

exp-13 adds one standard-runtime name:

(std.string.parse_i32_result text)

The name is compiler-known and has the exact signature:

std.string.parse_i32_result: (string) -> (result i32 i32)

The result uses the existing (result i32 i32) family. Success returns (ok i32 i32 value). Ordinary parse failure returns (err i32 i32 1).

The parser accepts the entire string only when it is ASCII decimal signed i32: optional leading -, one or more ASCII digits, and an in-range value. It rejects empty input, a lone -, +, whitespace, trailing bytes, non-digits, non-ASCII digits, and out-of-range values with err 1.

std.string.parse_i32_result is not an importable module member, not a user-defined function, not a package dependency, not a foreign function, and not a stable C ABI symbol. The implementation may lower through any runtime helper strategy that preserves the source contract.

8.12 exp-14 Standard Runtime Catalog

exp-14 adds no new standard-runtime names. It adds STANDARD_RUNTIME.md as a conformance catalog for the compiler-known std.* operations promoted through exp-13.

The catalog is documentation and release-gate inventory. It must match the already promoted names, signatures, fixture references, behavior/trap/result notes, manifest notes, and deferrals. It must not add imports, user modules, package dependencies, runtime APIs, helper-symbol promises, ABI/layout promises, manifest schema versions, runtime headers/libraries, or beta maturity.

8.13 exp-15 Result Helper Standard Names

exp-15 adds four standard-runtime source names:

(std.result.is_ok value)
(std.result.is_err value)
(std.result.unwrap_ok value)
(std.result.unwrap_err value)

The names are compiler-known and accepted only for (result i32 i32), (result i64 i32), (result string i32), exp-28 returned (result f64 i32), and exp-34 returned (result bool i32).

The exact signatures are:

std.result.is_ok: ((result i32 i32)) -> bool
std.result.is_ok: ((result i64 i32)) -> bool
std.result.is_ok: ((result string i32)) -> bool
std.result.is_ok: ((result f64 i32)) -> bool
std.result.is_ok: ((result bool i32)) -> bool
std.result.is_err: ((result i32 i32)) -> bool
std.result.is_err: ((result i64 i32)) -> bool
std.result.is_err: ((result string i32)) -> bool
std.result.is_err: ((result f64 i32)) -> bool
std.result.is_err: ((result bool i32)) -> bool
std.result.unwrap_ok: ((result i32 i32)) -> i32
std.result.unwrap_ok: ((result i64 i32)) -> i64
std.result.unwrap_ok: ((result string i32)) -> string
std.result.unwrap_ok: ((result f64 i32)) -> f64
std.result.unwrap_ok: ((result bool i32)) -> bool
std.result.unwrap_err: ((result i32 i32)) -> i32
std.result.unwrap_err: ((result i64 i32)) -> i32
std.result.unwrap_err: ((result string i32)) -> i32
std.result.unwrap_err: ((result f64 i32)) -> i32
std.result.unwrap_err: ((result bool i32)) -> i32

These forms lower to the same typed-core observer and payload-extraction operations as the legacy unqualified compatibility forms. The existing unwrap_ok on err and unwrap_err on ok trap behavior applies.

std.result.* helper names are not importable module members, not user-defined functions, not package dependencies, not foreign functions, and not stable C ABI symbols. The implementation may lower through any helper strategy that preserves the source contract.

9. Slice 5: Tooling Contracts

Status: promoted as a tooling contract only. This slice does not add source syntax, runtime behavior, type-system behavior, or a native executable output requirement.

9.1 Machine Diagnostic Schema

Slovo v1 keeps the v0 rule that diagnostics have both human-readable and machine-readable forms generated from one compiler diagnostic object. Human rendering may choose layout and surrounding prose. The machine form is the tooling contract, with beta compatibility and migration rules defined by the diagnostics policy rather than by human text.

The v1 machine diagnostic schema is slovo.diagnostic version 1. As of 1.0.0-beta.13, the detailed beta schema policy, JSON-line discipline, source-less diagnostic policy, compatibility classes, and current code catalog live in docs/language/DIAGNOSTICS.md.

Every machine diagnostic emitted for a v1 compiler boundary must include:

  • schema marker: slovo.diagnostic
  • version marker: 1
  • severity
  • stable PascalCase diagnostic code
  • concise message
  • source file path
  • primary zero-based, half-open byte span
  • primary one-based line/column range

Optional fields:

  • expected value, type, arity, or form
  • found value, type, arity, or form
  • safe repair hint
  • related spans, each represented as a repeated (related (span ...)) form with its own file path, byte span, line/column range, and optional message

Machine-readable diagnostic example:

(diagnostic
  (schema slovo.diagnostic)
  (version 1)
  (severity error)
  (code TypeMismatch)
  (message "expected i32, found string")
  (file "main.slo")
  (span
    (bytes 42 49)
    (range 12 8 12 15))
  (expected i32)
  (found string)
  (hint "Use an integer value or convert explicitly."))

Related span example:

(related
  (span
    (file "main.slo")
    (bytes 10 14)
    (range 2 8 2 12)
    (message "original declaration")))

Each related span is emitted as its own repeated (related ...) form. The related message belongs to that related span object; it is not a top-level diagnostic message.

The primary and related byte spans are zero-based and half-open. Line values are one-based source line numbers. Column values are one-based byte columns within the original UTF-8 source line; a tab counts as one input byte. The end column is the first byte column after the highlighted range on the end line. Diagnostic locations are derived from original source text, not from formatter output.

The schema version belongs in every machine diagnostic and every golden diagnostic fixture. Human-readable diagnostic prose remains beta-flexible, but future machine-shape or code changes require the compatibility class defined in docs/language/DIAGNOSTICS.md and updated Glagol snapshots when the current golden contract changes.

9.2 Artifact Manifest Schema

Slovo v1 defines a narrow textual artifact manifest for compiler outputs and test reports. The manifest records what a tool invocation consumed, what mode it ran in, whether it succeeded, which diagnostic schema applies, and where generated textual or structured artifacts can be found.

The v1 artifact manifest schema is slovo.artifact-manifest version 1.

Every manifest must include:

  • schema marker: slovo.artifact-manifest
  • version marker: 1
  • source path
  • command string
  • mode
  • success marker
  • diagnostics schema version
  • primary output, either as a kind/path pair, stdout text, or explicit no-output marker
  • generated artifact references, which may be empty

Optional field:

  • test report summary. When present in v1, it contains total, passed, failed, and skipped counts.

Compiler-output manifest example:

(artifact-manifest
  (schema slovo.artifact-manifest)
  (version 1)
  (source "examples/supported/add.slo")
  (command "glagol compile examples/supported/add.slo --emit llvm")
  (mode emit-llvm)
  (success true)
  (diagnostics-schema-version 1)
  (primary-output
    (kind llvm-ir)
    (path "build/add.ll"))
  (artifacts
    (artifact
      (kind llvm-ir)
      (path "build/add.ll"))))

Test-report manifest example:

(artifact-manifest
  (schema slovo.artifact-manifest)
  (version 1)
  (source "examples/supported/top-level-test.slo")
  (command "glagol test examples/supported/top-level-test.slo")
  (mode test)
  (success true)
  (diagnostics-schema-version 1)
  (primary-output
    (kind stdout)
    (stdout "1 passed\n"))
  (artifacts)
  (test-report
    (total 1)
    (passed 1)
    (failed 0)
    (skipped 0)))

Successful modes that intentionally produce no primary text may use:

(primary-output
  (kind no-output))

Recommended v1 modes are check, format, emit-llvm, inspect-lowering, and test. Recommended output and artifact kinds are diagnostics, formatted-source, llvm-ir, lowering-inspector, stdout, stderr, symbols, no-output, and test-report.

A failed invocation still writes a manifest when the tool mode supports manifests. In that case (success false) is paired with a diagnostics artifact or stdout/stderr output whose diagnostics use schema version 1.

This contract does not require native executable output. LLVM IR, formatted source, inspector output, diagnostics, stdout/stderr capture, and test reports are sufficient v1 artifacts.

9.3 LLVM Source-Map And Debug-Info Direction

Slovo v1 requires compiler data to preserve diagnostic source spans through parse, check, typed core, lowering, and LLVM IR emission. This is a tooling requirement so diagnostics, lowering inspectors, trap checks, and artifact manifests can point back to original source.

Stable LLVM debug metadata, DWARF emission, and source-map files are deferred. Future promotion should map Slovo source spans to generated LLVM functions, basic blocks, instructions, runtime intrinsic calls, and explicit trap paths. Array bounds traps and option/result payload traps should carry the source span of the Slovo operation that can trap.

Lowering-inspector golden fixtures are textual compiler-tree artifacts. They show accepted source as compiler-owned tree output, such as surface and checked forms, and are not a substitute for or a promise of stable LLVM debug metadata, DWARF, or standalone source-map files.

9.4 Formatter Stability Contract

Formatter stability is a promoted v1 tooling contract. Every promoted fixture under examples/formatter/ defines canonical output. Formatting a promoted fixture must produce the same source bytes again, including line comments, indentation, blank-line placement, and a final newline. Reformatting formatter output must be idempotent.

The v1 formatter is not a width-based pretty printer. It may normalize spacing and indentation for supported forms, but it does not promise terminal-width measurement, column reflow, or wrapping of long inline calls/forms. Long inline forms stay inline unless their form has an explicit canonical multiline shape.

Line comments are supported only as full-line comments in these positions:

  • before top-level forms
  • inside fn and test bodies before body expressions
  • after the final fn or test body expression and before the closing paren
  • after the last top-level form

All other comment positions are unsupported in v1 and must be rejected with structured diagnostics, not silently dropped or moved. In particular, v1 rejects comments inside:

  • (module ...) forms
  • (struct ...) forms
  • (type ...) alias declaration forms
  • fn and test headers before their body begins
  • type forms such as (array i32 N), (option i32), (result i32 i32), exp-2 (vec i32), exp-94 (vec i64), exp-103 (vec f64), and exp-4 enum type names
  • inline expression forms, including calls, field access, array constructors, struct constructors, option/result constructors, observers, unwraps, match patterns, comparisons, arithmetic, string_len, std.string.len, print_i32, print_string, print_bool, std.io.print_i32, std.io.print_string, std.io.print_bool, std.io.print_f64, exp-2 std.vec.i32.* calls, exp-94 std.vec.i64.* calls, exp-103 std.vec.f64.* calls, exp-99 std.vec.string.* calls, exp-3 host calls, exp-4 qualified enum constructors, and exp-13 std.string.parse_i32_result calls, and exp-15 std.result.* helper calls

Nested promoted forms have these stable shapes:

  • if, while, unsafe, and match use their existing multiline indentation and do not collapse to a single line because their contents are short
  • calls, field access, arrays, struct constructors, option/result constructors, option/result observers, option/result unwraps, string_len, std.string.len, legacy print aliases, std.io.print_* calls, and exp-2 std.vec.i32.* calls, exp-94 std.vec.i64.* calls, exp-103 std.vec.f64.* calls, exp-99 std.vec.string.* calls, exp-3 host calls, and exp-4 qualified enum constructors, exp-13 std.string.parse_i32_result calls, exp-15 std.result.* helper calls, exp-20 std.io.print_f64 calls, exp-21 std.io.print_i64 calls, exp-22 std.num.* conversion calls, exp-23 std.num.i64_to_i32_result calls, exp-24 integer-to-string calls, and exp-25 std.string.parse_i64_result calls, and exp-26 std.num.f64_to_string calls, and exp-27 std.num.f64_to_i32_result calls, and exp-28 std.string.parse_f64_result calls, and exp-31 std.num.f64_to_i64_result calls, and exp-34 std.string.parse_bool_result calls remain inline when used as expressions

Unsupported formatter positions must produce diagnostics using the v1 slovo.diagnostic schema. A formatter diagnostic must identify the unsupported position with a machine-readable code, source span, line/column range, and a message or hint that names the accepted v1 comment/layout positions.

9.5 Glagol Promotion Obligations

Before a promoted v1 boundary is treated as complete, Glagol must provide and keep an explicit coverage inventory. This is a Slovo-to-Glagol contract obligation; it does not by itself claim that the current Glagol implementation has already completed every listed fixture.

  • golden machine diagnostic fixtures using slovo.diagnostic version 1 for every promoted v1 boundary and every current explicitly rejected source-reachable v1 boundary
  • a diagnostic fixture inventory that maps each explicitly rejected v1 boundary to the golden fixture and diagnostic code that prove it
  • tests that assert the diagnostic schema and version markers are present
  • textual lowering-inspector golden fixtures for every promoted v1 feature family:
    • add/canonical
    • top-level tests
    • locals
    • if
    • while
    • struct
    • struct value flow
    • array
    • array value flow
    • option/result
    • option/result flow
    • option/result payload
    • option/result match
    • string print
    • string value flow
    • print bool
    • standard runtime alpha
    • unsafe
    • formatter comments/stability, only where inspector mode applies to source accepted by lowering
  • artifact manifest examples or tests for successful compiler output, diagnostic failure, and test-report output
  • source-span preservation through the compiler data needed by diagnostics and LLVM emission
  • no source-reachable panic for supported v1 source or for explicitly unsupported source at promoted boundaries

Future feature families must extend both inventories before promotion: accepted source needs textual lowering-inspector golden fixtures, and every new explicitly rejected source-reachable boundary needs golden machine-diagnostic coverage.

9.6 v1.7 Tooling Extensions

v1.7 hardens developer experience tooling while preserving all v1.6 language semantics. The promoted tooling extensions are:

  • project scaffolding with glagol new <project-dir> [--name <name>]
  • formatter check mode with glagol fmt --check <file-or-project>
  • formatter write mode with glagol fmt --write <file-or-project>
  • deterministic Markdown documentation generation with glagol doc <file-or-project> -o <dir>
  • a local release-gate script contract

Project scaffolding emits the existing v1.3 project shape: slovo.toml plus flat source modules under src. The generated main module must be testable using only already-promoted language forms. Scaffolding must reject non-empty target directories without overwriting existing content.

Formatter check/write modes use the canonical formatter rules from section 9.4. Project formatting applies only to immediate .slo modules under the manifest source root and uses deterministic v1.3 module ordering. Plain glagol fmt <file.slo> continues to write formatted source to stdout.

Documentation generation records modules, imports/exports, structs, functions, tests, and beta.11 exported/public API sections as deterministic Markdown. Public API sections include exact exported function signatures, exported struct fields, exported enum variants/payload types, non-export filtering, and module-local alias normalization. It is generated documentation, not runtime reflection, typed-core reflection, debug metadata, DWARF, source maps, ABI/layout information, or a stable Markdown schema.

LSP, watch mode, daemon protocols, SARIF, debug adapters, diagnostics schema policy, stable debug metadata, DWARF emission, standalone source-map files, stable stdlib/API compatibility freeze, executable generics, maps/sets, re-exports, globs, hierarchical modules, and registry semantics remain deferred.

10. Slice 6: Unsafe, Memory, And FFI

Status: v1.6 reservation and gating contract. Raw-memory execution remains deferred.

Slovo v1 keeps v0 lexical unsafe as the only accepted unsafe boundary. Lexical unsafe permits otherwise supported safe forms in an unsafe block; it does not promote raw memory, pointer, allocation, unchecked indexing, or FFI operations.

v1.6 reserves the following compiler-known unsafe operation heads:

  • alloc
  • dealloc
  • load
  • store
  • ptr_add
  • unchecked_index
  • reinterpret
  • ffi_call

These names are recognized before ordinary user-call lookup. Safe code that uses any reserved unsafe head must be rejected with UnsafeRequired.

Code inside lexical (unsafe ...) that uses any reserved unsafe head must be rejected with UnsupportedUnsafeOperation until a future release defines that operation's syntax, type rules, lowering, runtime behavior, diagnostics, and tests.

User functions, imports, exports, and parameters must not shadow these compiler-known unsafe heads. Such declarations must be rejected with a structured duplicate/reserved-name diagnostic.

The v1.6 memory direction is staged: safe values remain the default; future memory work is expected to define affine ownership plus explicit unsafe regions before raw memory can execute. v1.6 makes no stable ABI, layout, FFI, allocator, ownership, or raw-memory execution promise.

A future raw-memory or FFI contract must specify:

  • pointer types
  • allocation and deallocation
  • load and store
  • pointer arithmetic
  • unchecked indexing
  • reinterpretation
  • FFI call shape
  • ownership of allocation failures and cleanup behavior
  • ownership, affine/resource, and lifetime rules
  • diagnostics beyond the v1.6 UnsafeRequired and UnsupportedUnsafeOperation gates

No stable ABI or layout promise is made in v1. Stable ABI and stable layout promises remain deferred until a future spec explicitly promotes them.

11. Deferred Until Future Beta Unless Promoted Explicitly

  • broad conformance suite, stable beta compatibility policy, semantic versioning, and deprecation policy
  • struct field mutation and whole-struct value mutation
  • option/result mapping, equality, printing, payload families beyond the current exp-10 (result string i32) slice and the exp-36/exp-75/exp-95/ exp-100/exp-102/exp-109 concrete (option i32) / (option i64) / (option f64) / (option bool) / (option string) source helper slices, nested option/result values, arrays or structs containing option/results, generic payloads, enum payloads beyond exp-16 unary i32 variants, exp-116 unary direct scalar/string variants, and exp-121 unary current known non-recursive struct variants, enum import behavior beyond exp-17 explicit local export/import lists, enum values in containers or nested structs beyond exp-18 direct fields, general payload ADTs, and user-catchable exceptions
  • unit printing and user-declared or stored unit values
  • broader standard-runtime printing beyond v1.5 std.io.print_i32, std.io.print_string, and std.io.print_bool
  • std.io.print_unit, host IO beyond the exp-3 slice, exp-10 *_result slice, and exp-12 stdin-result slice, networking, async IO, binary file APIs, directory traversal, terminal control, platform abstraction, general host error ADTs, stdin APIs beyond exp-12, parsing APIs beyond exp-13 std.string.parse_i32_result, exp-25 std.string.parse_i64_result, exp-28 std.string.parse_f64_result, and exp-34 exact lowercase std.string.parse_bool_result, string scanning/tokenizing APIs beyond 1.0.0-beta.16 byte access, substring, and prefix/suffix helpers, result helper payload families beyond the explicitly listed (result i32 i32), (result i64 i32), (result string i32), exp-28 returned (result f64 i32), and exp-34 returned (result bool i32) families, generic option helpers beyond exp-36/exp-75/exp-95/exp-100/ exp-102/exp-109 concrete option source helpers, randomness beyond the exp-11 target, time beyond the exp-8 host time/sleep target, vectors/collections beyond the exp-2 (vec i32), exp-94 (vec i64), exp-99 (vec string), exp-103 (vec f64), exp-104 (vec bool), and beta.12 source-helper parity targets, user-defined standard modules, overloading, and generic standard-library APIs
  • numeric primitives and conversions beyond exp-20 direct f64, exp-21 direct i64, exp-22 explicit std.num.i32_to_i64, std.num.i32_to_f64, and std.num.i64_to_f64 calls, exp-23 std.num.i64_to_i32_result, exp-24 std.num.i32_to_string and std.num.i64_to_string, exp-25 std.string.parse_i64_result, exp-27 std.num.f64_to_i32_result, exp-28 std.string.parse_f64_result, exp-31 std.num.f64_to_i64_result, and existing i32/bool, including f32, unsigned integers, narrower integer widths, char, bytes, decimal, numeric casts or conversions beyond exp-22 explicit widening calls, the exp-23 checked i64 -> i32 result call, the exp-27 checked f64 -> i32 result call, and the exp-31 checked f64 -> i64 result call, implicit promotion, mixed i32/i64/f64 arithmetic, generic numeric operators, numeric container families beyond the current fixed direct-scalar arrays, current concrete vec families, current concrete option/result families, and current direct numeric enum payloads, numeric struct fields beyond exp-29 direct i64 and finite f64 fields, random floats or random i64, f64 formatting beyond exp-26 finite decimal text, locale/base/radix/grouping/padding formatting controls, generic format/display traits, and stable numeric formatting or ABI/layout promises
  • standard math source helpers beyond the exp-39 std/math.slo helper slice and exp-44 explicit std.math import path, including trigonometry, sqrt, pow, exponentials, logarithms, rounding APIs, generic math, overloads, traits, automatic std imports, workspace dependency syntax for std, package std dependency declarations, and mixed numeric helper families
  • standard result source helpers beyond the released exp-33, exp-35, exp-74, and exp-109 std/result.slo concrete helper slices, exp-45 explicit std.result project import path, and exp-46 workspace source-search model, including generic std.result.map, generic std.result.unwrap_or, std.result.and_then, broader result/option bridge or transpose/flatten helpers, generic result helpers, and new result payload families
  • standard option source helpers beyond the released exp-36/exp-75/exp-95/ exp-100/exp-102/exp-109 std/option.slo concrete helper slices, exp-45 explicit std.option project import path, and exp-46 workspace source-search model, including generic option helpers, option mapping/chaining, broader option/result bridge helpers, and option payload families beyond i32, i64, f64, bool, and string
  • standard time source helpers beyond the released exp-37 std/time.slo facade wrappers, including wall-clock/calendar/timezone APIs, high-resolution timers, async timers, cancellation, and scheduling guarantees
  • generic vectors, vector element types other than i32, i64, f64, bool, and string, element-level mutable vectors and mutable vector operations beyond whole-value local reassignment, vector literals beyond empty/append construction, push, nested vectors, vectors in arrays/structs/options/results, iterators, slices/views, maps, sets, new runtime vector helper names, performance claims, user-visible vector deallocation, stable stdlib API freeze, and stable vector ABI/layout/helper symbols
  • string concatenation beyond exp-1 std.string.concat, parsing beyond exp-13 std.string.parse_i32_result, exp-25 std.string.parse_i64_result, and exp-28 std.string.parse_f64_result, plus exp-34 exact lowercase std.string.parse_bool_result, unchecked indexing, character/grapheme indexing, language slice/view syntax, string containers beyond the current direct struct fields, current fixed string arrays, current direct fixed-array struct fields, and current concrete option/result families, user-visible string allocation or deallocation, Unicode length, grapheme, display-width, locale, or digit semantics, full JSON parsing, object/array parsing, and stable string ABI/layout
  • pointer types, allocation, deallocation, load, store, pointer arithmetic, reinterpretation, unchecked indexing, raw memory operations, and FFI
  • stable ABI and stable layout promises
  • macros
  • generics
  • package management
  • ownership and affine resources
  • concurrency
  • direct machine-code backend
  • stable cross-language ABI