Mica 7.0.0 is two releases wearing one number, and both needed the other. It is a breaking release — the only one of its kind we will ever ask of you — whose whole break serves one sentence: names are decided once, by one rule, and then frozen. And it is the largest feature release Mica has shipped: the machinery the 7.x line stands on, from generics over shapes to a stream that carries its own failure across a network connection. The two belong together because a surface freeze is only credible on a surface worth freezing — so we finished the foundation first, renamed once across all of it, and froze what we renamed.
The release at a glance
| Movement | What a program can do now |
|---|---|
| The naming pass | one doctrine — a name may not truncate a word — applied across the whole surface, with a mechanical migration table; then the freeze |
| Qualified names | imp cstd; and cstd.Sqrt(x) beside math.Pi — a word’s origin stated at its use |
| Generics over shapes | gen value parameters: Vector of (T, N) is one declaration and a family of shapes, inference reading N off an argument’s dimension |
| WYSIWYG slicing | explicit named copy and view forms over arrays and tensors — no view/copy roulette, ever |
span of T | the borrowed sight over contiguous elements, under a lending law the compiler enforces by name |
| Deterministic reductions | one documented pairwise tree: serial equals parallel, both architectures, bit for bit |
The math unit | born generic, full type fidelity per width, one meaning per word |
| The stream that may fail | stream of T fails E — a spelled type; the for loop consumes the failure; rings latch it first-wins; select delivers it; adapters are generic over the domain |
| The network line | the net unit whole: parking-not-blocking sockets, fan-out as a compile-time fact, the worker pool in three declarations, the unix-domain pair, and a typed value stream over a connection |
Everything below is shipped and gated behavior — every claim in this article has a test the release gates run.
The rule
A name may not truncate a word. An initialism or an industry word said as a
word — Tcp, Nan, Gcd, ArgMin, StdOut — is a word. Two closed
heritage lists are honored deliberately and never grow: Pascal’s
(WriteLn, ReadLn, Chr, Ord, Inc, Dec, Pred, Succ, and the
classic string six Copy/Pos/Insert/Delete/Str/Val), and C’s — the
cstd/posix/linux namespaces mirror C, which is their correctness.
Keywords are structure, not API: imp, exp, gen, mod stay short by
design.
What changes for released programs
The break for programs written against 6.12.x is exactly this table:
| Was | Is | Why |
|---|---|---|
alias pointer T | borrowed pointer T | the pair is owning/borrowed — the industry’s own owned-versus-borrowed vocabulary; alias meant too many things |
imp WriteLn as Say : std | imp Say = WriteLn : std | the new name stands left, exactly how type and const introduce names |
regex Span | regex Match | {Found, Start, Length} answers a match; the word span now belongs to the language’s borrowed view |
regex Inst, InstList, OpKind | Instruction, InstructionList, OpCode | the compiled program’s types say what they are |
BigintAdd, BigintMul, BigintSub, BigintDivide, BigintDivMod, BigintModulo, BigintPow, BigintCompare, BigintFromInteger, BigintStr, BigintVal | Add, Multiply, Subtract, Divide, DivMod, Modulo, Pow, Compare, FromInteger, Text, Parse — in the integers unit | a vocabulary unit needs no prefix on its own verbs; import them, alias them, or qualify them |
net Conn | net Connection | no truncations |
Migration is mechanical — every row is a textual substitution, and the compiler’s refusals name the new spellings.
What deliberately stays
WriteLn stays. So do ReadLn, Chr, Ord, the classic string six, and
every C-mirror name in cstd, posix, and linux. Keeping them is a
decision, not an omission: heritage words are a bridge every Pascal reader
crosses without thinking, and a C mirror that renamed C would be wrong about
C. The division of labor is now doctrine — heritage words in the standard
core, full words (WriteLine, WriteText) on every unit-level verb.
Qualified names
imp cstd; makes a whole namespace addressable, and cstd.Sqrt(x),
time.Hour, strings.Copy(s, 0, 4) read exactly as they say. A declared
name always wins the word — qualification never shadows your code — and the
no-function-pointer rule holds: two identifiers around a dot ahead of a
parenthesis are always a call. A name clash between two imports never
resolves silently: the import site refuses, and the alias or the dot
settles it explicitly.
Beside it, the alias ladder runs end to end: one rebinding form serves
every concrete import — functions, types, intrinsics — spelled as a
declaration, MatchCount = Count : regex beside Count : bits. Templates
graft under their own names and say so if you try to alias them, with the
working road in the message.
Generics learned shapes
A gen block now declares value parameters beside type parameters, so
gen
T is numeric;
N is int64;
type
Vector of (T, N) = vector[N] of T;is one declaration and a family of shapes. Inference reads N off an
argument’s dimension or the assignment target; a named constant denotes
the same instantiation its number denotes; and the debugger names the
shape a frame was built for. The built-in forms joined the same admission
— array[0..4] of T, vector[N] of T, matrix[R, C] of T stand in
every type-denoter position — which is what lets a library be generic
over shape the way the math unit now is, and what the 7.x tensor work
will stand on. The qualified-names and
generics pages carry the full story.
Slicing without roulette, and the span
Every slicing form in Mica now says whether it views or copies — explicit named forms over arrays and tensors, no spelling whose meaning depends on context. The slicing page states the whole law.
The viewing half has its own word: span of T is the borrowed sight —
three words, zero copies — standing in var, parameter and return
positions, with a Span intrinsic that borrows any sub-range in place.
Its safety story fits in one visible spelling: a view that escapes a call
comes from storage the caller lent through address, and everything that
would outlive its backing is refused at compile time by name — the
lending law. The *Span suffix family dissolved into
composition — Sum(Span(a, from, upto)) — and the whole-matrix
reductions dissolved into the same face, a matrix’s elements admitting as
one row-major span.
One tree, everywhere: the deterministic reductions
Sum walks one documented pairwise tree: the same
order serially and in parallel, on both architectures, bit for bit. That
sentence is the semantic promise numeric code needs before anyone
parallelizes anything — a result that cannot depend on the carrier count
is a result you can regression-test — and it is the ground the 7.x AI
line is built on. The elementwise verbs share it, and the math unit
speaks the same language: Min/Max/Clamp/Abs/Sign at full type
fidelity per width, constants spelled as the expressions they are,
IsNan/IsInf through pure IEEE arithmetic, the shaped verbs —
Exp(v : vector[N] of T), Outer answering matrix[N, M] of T —
spelling the language’s own forms with no named tensor type in between.
One meaning per word: math.Exp(v) beside cstd.Exp(x) when you want
both in one body.
The stream that may fail
A stream type now carries its failure domain: stream of T fails E is a
spelled type, and everything that touches it holds up its half.
generator Prices(c : Connection) : stream of Quote fails NetError;A generator declares what its body may fail with. The for loop
consumes the stream’s failing end with the same on fail e do every call
site writes — one consumption form for calls and streams alike. A
task-fed ring latches its producer’s failure first-wins, and every worker
drains the buffered values before meeting it at its own exit: delivery
order, not wall-clock order. select delivers a fallible arm’s ending
through its own on fail, one domain across the arms. And the adapters
stay one exported name — Take, Skip and Chain are generic over the
failure domain, a plain stream instantiates them with none — so
composition never forks on fallibility. Plain records ride streams now
too, crossing the suspension whole.
The consumption duty is compile-time in both directions: a fallible
stream walked without on fail refuses, and on fail over a stream that
cannot fail refuses as the meaningless form it is.
The network line
The net unit debuts publicly in 7.0.0, carrying everything the 6.13
line built and never shipped: a connection is a value, a wait is a task
suspension, a failure is a typed failure. Every wait parks only the
calling task — the blocking spelling is the scalable one — so an
echo server is a loop around Accept with a
schedule inside it, and that is the whole design. A task takes a plain
aggregate by value now, which is what lets schedule Session(connection)
hand a session its own connection with no sharing to reason about.
On top of it, three things arrived at once:
Fan-out is a compile-time fact. Whether a stream variable holds a
task-fed ring or a pull chain is a static property of its bind, so
stream of T stands on a task parameter, N workers pop one ring with
every value delivered exactly once, and the one runtime trap in the story
became a compile diagnostic. The worker pool is
three declarations.
The unix-domain pair. ListenIpc(name) and DialIpc(name) open the
same Listener and Connection every TCP endpoint answers, under the
kernel’s abstract namespace — no socket file, nothing stale after a crash
— with the transport named at the constructor and invisible after.
The typed value stream. WriteValue and ReadInto frame plain
values over a connection, and the stream’s end crosses the wire as one
closing frame — clean, or failing with the producer’s reason word. The
reading side is an ordinary fallible generator over the connection, so
the wire’s three troubles — a polite failure, a dead transport, a foreign
frame — arrive through the one declared domain, and the
same for loop consumes them all. The
multicore scheduler underneath was hardened for exactly this shape: a
generator that parks on a descriptor mid-stream migrates carriers
correctly, and the stress gate that proves it runs on every merge.
The promise
From 7.0.0 on, exported names are frozen. A future rename requires a deprecation era and a major release, and no future unit ships a name that fails the rule above. We spent the one renaming a community tolerates — there is no second one.
What comes next builds on this surface without moving it: the 7.x line takes the shapes, the reductions, the spans and the streams and aims them at numeric and AI work. That story starts at 7.1. The ground it stands on is this release.