| title | Known limitations | ||
|---|---|---|---|
| sidebar |
|
The deferred parts:
- Polymorphism is overloading. Overloading (ad-hoc, exact-type dispatch) is the polymorphism; type variables are deferred, and the matchers are compiler-provided. The module system is the built-in
core.*modules and file-path imports, reached through qualified access; selective import, re-export, and aliasing are deferred. - Closures are monomorphic. Lexical capture works end-to-end (
=by value /:=by reference; see Closures), including recursion of non-capturing nested functions, capture across nesting levels, and capturing-then-calling another closure. A closure can be passed to a function-typed parameter and called there, and returned from a function — its captures live on the GC heap, so they outlive the frame that made them. Deferred (each needs the closure's type threaded through inference): capturing a polymorphic value and generic closures. - Closure values are lambdas and closure bindings. A closure is passed (or returned) as a lambda literal or a named closure binding; a top-level function or an overloaded name travels as a lambda that calls it, and the compiler says so ("a function name is not a value yet — wrap it in a lambda that calls it"). Function names as values are deferred.
- A pattern tests one level. A constructor pattern's payload sub-pattern is irrefutable — a binding (
Ok(x)) or_(Ok(_)); dispatch reads the variant tag, and the arm body compares the bound payload. A match on aTextor aBoolis covered by a catch-all arm; literal patterns for them are deferred. - A field write's path ends at a binding. A write whose root is a call result (
same(m).v := 5on a:=-boundm) passes the checker — the value is mutable — and its lowering is deferred; bind the result first (h := same(m), thenh.v := 5). AResultsignature's payload isGeneric, so a record passed through a genericResultparameter is outside the deep-immutability analysis; a user sum with a concrete record payload is inside it. - A named-composite sum payload is a record, and a record field is a built-in type or an array. A variant may carry a named record (
Post(Body)); a named sum payload is deferred, and a record field of a user type ({ inner :: Inner }) is deferred. - A range consumed directly by an array method iterates its endpoints; every other consumption builds the array. A
lo <- hifed straight to.each/.map/.filter/.reduceiterates its endpoints —(1 <- 100000000).each(...)is a counter — so "do this N times" scales (see ranges). Indexing,.size, binding to a name, and passing to a function build the whole array at 8 bytes per element, and the first method of a chain is the lazy one — the later links consume the arrays it produces. - A stack overflow is reported as
QN507.^runs on the scheduler's seed fiber, whose stack is 8 MiB — a process stack's size, with the same recursion depth. Recursion of unbounded depth is written as a self-tail-call, which is lowered to a loop and runs in constant stack. - Concurrency is partly built. The model is locked; the fiber scheduler, reactor,
time.@sleep, the deferred-value primitives (io.@readStdin,net.@tcpRequest), the block-scope join for a launch made directly in a< >block (allSettled, every fault reported by its own launch site), the atomic-binding syntax@name := …— its reassignment rejected when the right side forces a deferred value — the raw TCP server layer (net.@tcpServe/Connection/Server), and the fiber-sharing check the checker enforces againstnet.@tcpServe's handler — a non-atomic:=binding it reaches, directly or through a call, is a compile error — run. Remaining for 1.0: an overlap showcase, deferred composites, cross-function pipelining (a launch made inside a called function, joined by the block that made the call), file primitives, and the M:N runtime with atomic types.