Manuscript Documentation
v0.1.0

Source guarantees and Go representations#

A Go value must preserve the behavior promised by its Manuscript type. For example, generated Int arithmetic must detect overflow, and generated collections must prevent mutation through an alias. The compiler and runtime enforce guarantees that unrestricted Go values do not provide on their own.

The frontend enforces semantics that Go representations do not provide:

Source guaranteeGo lowering
Checked Intint64 with checked operations and conversions
DecimalVersioned finite decimal implementation honoring the coefficient/exponent grid, exact literals, and per-operator rounding in the numeric contract
Valid UTF-8 StringValidated construction and conversion; no raw string escape
Mutable records and collectionsShared record field storage and pointer-backed collection headers; explicit shallow clone
Immutable bytesEncapsulated storage; copies or exclusive adapter transfer
Ordered maps and setsOrdered wrappers
Tagged alternativesGenerated typed tags and payloads; exhaustive frontend checking
Recursive dataRecord maps and alternative payload slices retain references; direct and mutual recursion require no extra wrapper; reject expanding generic families before Go emission
Value equality and hashingGenerated operations for eligible types
Explicit contract implementationFrontend selection of a unique applicable concrete/generic implementation, then Go interfaces and wrappers
Closures and resource referencesGC-retained environments, snapshot captures, and synchronized native closed-state checks
Lexical cleanupExplicit with registrations, shielded Closeable.close(), and scope unwind operations
Task resultsNative Task[T] handles retaining cached, exactly typed return values

The frontend checks Task[T] through ordinary generics. Native handles retain runtime value storage; source cannot perform unchecked casts.

Representation boundaries#

The current shared runtime ABI boxes locals, captures, arguments, and return values as Go any. Within statically checked Int and Float expressions, lowering emits typed literals and scalar operations; integer arithmetic retains overflow and zero-divisor checks, and floating arithmetic rounds at each source operation. Equality still uses the selected implementation scope.

Direct calls to the checked native List.at and Optional.unwrap operations share runtime helpers with bound-method dispatch, avoiding temporary callable wrappers. Indexing still returns an Optional, including none for out-of-range indexes; it does not introduce unchecked access. Library members of String, Bytes, List, Map, and Set called on a statically typed receiver with every argument supplied in order bind once per call site and run the same library body, equality scope, and cancellation checkpoints without building a bound Function per call. StringBuilder.append and freeze, standard free functions without default expressions, and generic functions with static type arguments are likewise resolved once. Unary minus over Int and Float stays typed. Bound methods, callbacks, and calls with dynamic type arguments retain the ordinary ABI. The reproducible native workloads in scripts/benchmarks/ measure numeric loops, calls, list reads, and Game of Life; they do not establish that values or source functions are fully unboxed.

For example, emitting a raw int64 does not supply checked arithmetic. A raw Go slice does not establish immutable source bytes. The frontend and runtime cooperate with generated wrappers and operations to preserve those contracts.

Explicit view constructors create ordinary contract wrappers. There is one contract-view identity and no sharing proof in the frontend or IR. Native services synchronize their internals. Local queues rely on caller-managed Synchronized guards for concurrent access.

Contract wrappers and bound methods retain the selected implementation scope. Generic specialization carries that scope with each type argument, including nested receiver arguments; forwarding a bounded parameter must preserve its implementation evidence. Cleanup dispatch obeys the same scope rules.

Generic implementation bodies use checked substitutions; Go method selection cannot resolve overlapping source implementations. Function wrappers retain source labels/order in frontend identity even though Go erases labels. Check recursive storage rules before emission; a generated-Go error is not a source type check.

Int division/remainder overflow handling, Float non-finite outcomes, Decimal underflow/overflow, and checked truncation conversions follow runtime numeric outcomes , including parameterized runtime operands. Unchecked Go casts or a decimal package’s defaults do not establish these semantics.

See type checking , and scope and capture checking .