Mica 7.5.0 is a release with no new sentence in the language, and it is the most consequential release since the AI arc began. Two releases in a row grew Mica toward training a GPT in the language’s own words; this one slows down and does the careful work those features were resting on. Its three subjects are performance, efficiency, and the compiler’s own robustness, and its rule is that nothing is claimed that was not measured: every number below names the machine it was taken on and the date, every defect names the instrument that found it, and every guarantee names the gate that keeps it true.

Everything below is shipped and gated behavior. The benchmark tables are produced by one documented run that anyone can repeat; the sweep that found forty-one defects is a corpus of programs the release gate compiles; and the technical report on the memory model is written against the compiler as it ships.

The release at a glance

SubjectWhat changed
Performance, measuredthe Benchmarks Game kernels run against their C twins on named, rentable machines, by wall clock, both compilers at O2, every Mica check on; eight of ten kernels within 1.97x of gcc -O2 on ARM64 and within 1.49x on AMD64, the regex kernel ahead of C’s engine on ARM64
A price at every mergeevery kernel and every standard-library operation runs under callgrind at every merge and must stay within one percent of its pinned instruction count
Checked builds on the optimizing loweringO2,checked keeps every guard on the release code; NBody at O2,checked runs about a third of the instructions the previous checked build ran
Memory brought downstrings reclaimed when superseded, a dying value moved instead of copied, an allocation that is a call: RegexRedux 150.9 → 40.1 MB, a million map insertions 119 → 63 MB, a tokenizer over 40,000 merge rules 35.5 s → 0.6 s
The first technical reportTechnical Report 1, the memory model: where every byte lives, what the compiler proves, what the checked build catches
The regex engine rebuiltlinear over the caller’s text, a walk over the matches, \p{L}-class patterns, lookaround refused by name
Forty-one defects, by familyan adversarial sweep of 283 programs written to be wrongly accepted; every finding a refusal that names its rule
Wrong code and hangs, by instrumentcallee-saved registers restored from below the stack pointer at release, found by valgrind; a lost wakeup in the multicore scheduler, found by the emulated leg of the gate
Profiling, with the tools you already use--optimize O2,profiling keeps the line table and the inlining records on the release build’s exact code, so perf, valgrind’s callgrind, gdb and hyperfine attribute an optimized Mica binary to its source lines and name inlined callees as their own frames; the profiling walk runs all four on one program
The toolchain--static, --strip, O0/O1/O2, the utf unit
Three spellings changethe archives are mica-<component>-<arch>.a, hosted is hosted-heap, a bare checked selects the release profile

Performance, on machines anyone can rent

A performance number without a machine, a date and a method is a marketing claim, so 7.5 publishes all three with every number. Ten kernels of the Computer Language Benchmarks Game are implemented twice, in Mica and in C with the identical algorithm and loop structure, and run on two named Google Cloud machine types, an Ampere Altra and an EPYC Milan, with both compilers at O2 and every Mica safety check on: bounds, division guards, the memory-safety floor. Every Mica binary’s output is byte-identical to its C reference on every run, or the run is refused.

The metric that matters is wall clock. Measured on 10 September 2026 with the 7.5 compiler, eight of the ten kernels stand between 1.01x and 1.97x of gcc -O2 on ARM64 and between 1.05x and 1.49x on AMD64; the regular-expression kernel runs at 0.69x on ARM64, ahead of C’s engine, and at 1.37x on AMD64. The two kernels set beside that band measure an allocator and a regular-expression engine respectively, and the tables name the procedures their time goes to. Peak memory is measured beside time and held within a per-kernel budget, and the tables on the facts page carry the machine types, the zone, the compilers' versions and the date, so a reader re-measures rather than trusts.

Between releases the number cannot drift. Every kernel of both benchmark suites runs under callgrind on every merge and must stay within one percent of its pinned instruction count; a change that makes one kernel slower by more than that fails the gate with the kernel named. A slower compiler can no longer arrive by accident, and a faster one is recorded the day it lands.

Some of what the release bought, read from the same instrument: a counting loop compiles to the same six instructions on ARM64 that a hand-written loop takes; a temporary the optimizer retired no longer takes a stack slot the prologue zeroes; the string scans behind Pos, Contains, Split and Replace hunt a separator’s first byte the way the platform’s own library does; a view passed along is no longer copied on the way.

Checked builds on the optimizing lowering

Until 7.4, a checked build was a debug build with guards. From 7.5 the guards ride the optimizing lowering: --optimize O2,checked builds the register-homed, inlined code the release build runs and keeps every guard on it — array bounds, integer overflow, a cast outside its domain, a non-finite floating result, a pointer into a region already drained. The guards themselves shrank to a few instructions each: a non-finite check is one subtraction and one flag test on the hot path, and the report it would print lives in cold text. Measured on NBody, the O2,checked build runs about a third of the instructions the previous checked build ran. A checked build is now something to ship a test fleet with, not only something to debug under.

mica --compile --link --optimize O2,checked --platform linux,arm64,utf-32 \
     --source Program.mica --build out

Efficiency: memory brought down, and stated

Three changes to what a program holds, each measured on the program that exposed it. A string is reclaimed the moment it is superseded, so a loop that builds a new string each round holds one, not all of them: RegexRedux at five million bases went from 150.9 MB resident to 40.1 MB. A value whose source dies at the end of its scope is moved into its destination instead of copied: a million map insertions went from 119 MB peak to 63 MB. And an allocation is a call, not a walk: the runtime kept a registry of every cell ever allocated and walked it on each new, which made allocation quadratic in the number of live cells; a tokenizer parsing 40,000 merge rules went from 35.5 seconds to 0.6. The benchmark tables now carry a memory column beside time, held within a budget per kernel, so a regression in what a program holds fails the same gate a regression in speed does.

The model behind these numbers is written down. Technical Report 1: Memory management in Mica states where every byte of a program lives, which construct reclaims it, what the compiler proves at compile time, and what the checked build catches at run time — regions, ownership and the value model, for readers who know what a stack and a heap are and have not studied compilers. One promise the first edition made in the future tense is kept in this release: a pointer into a region that has already been drained is reported at its line by the checked build, with the guard reading the cell’s header ahead of the payload.

The standard library ships at O2 — the Mica-written units were built below the level their own C neighbours were, and correcting that found two real defects in the optimizer that no build had exercised, both fixed. And a new unit, utf, carries text to interchange bytes and back: encode, validate, strict and lossy decode, and a cursor that decodes a chunked stream without losing a code point cut by a boundary, every failure on the language’s own channel as a UnicodeError. Transcoding text walks it.

The regular-expression engine, rebuilt at its root

A loop over Find was quadratic, and the reason was not the matcher: the engine copied the subject into its own scratch on every call. That road is gone. A compiled pattern is an immutable value; the match state is a cursor the caller holds; the engine matches over the caller’s text without copying it; and a walk over the matches is linear however many it answers. The general-category classes \p{L}, \p{N} and their family are admitted, spelled as raw regex literals so the backslash is the pattern’s own; lookaround is refused by name, because the engine matches in linear time by construction and lookaround is what would break that. On a 32,000-rune text under utf-8 the Find loop went from 472 ms to 39 ms.

program Words;

imp
    WriteLn : std;
    Compile, MatchStart, Matching, NextMatch : regex;
    Regex, RegexError, Match, MatchCursor : regex;

var
    r : Regex;
    e : RegexError;
    c : MatchCursor;
    m : Match;
    t : string;
    n : int64;

begin
    t := "Mica 7.5 measures quality, and quality counts";
    r := Compile(0r"\p{L}+") on fail e do leave;
    c := MatchStart(address r, t);
    n := 0;

    while Matching(address c) do begin
        m := NextMatch(address r, t, address c);

        if m.Found then
            n := n + 1;
    end;

    WriteLn("%lld words", n);
end.
6 words

The walk reads the caller’s own string at every step; nothing is copied, no window is materialized, and the cursor is a value the caller owns — two walks over one pattern are two cursors.

Robustness: found by a sweep, by instruments, and by the compiler’s own gates

Forty-one defects, fixed by family

The release ran an adversarial sweep against the compiler: 283 programs, each written to be wrongly accepted, aimed at the memory model, the borrow rules, the failure channel and the task discipline. Forty-one were accepted when they should have been refused. Each was root-caused, and the findings closed as families rather than one by one — an address stored where it outlives the storage a call reclaims, a launder of a borrowed pointer through a plainly declared local, a dynamic array grown inside the loop that walks it, a stream variable held past its producer’s activation, a dispose of a part of a cell the pointer only lends. Every one is now a refusal that names its rule and the lawful road; every one is a case in the corpus, so it stays refused.

Wrong code and hangs, found by instruments

Two classes of defect that no test expectation catches were found by running instruments over ordinary programs, which is the release’s own lesson about itself. A release build restored callee-saved registers from below the stack pointer in its epilogue — correct only until a signal handler ran on that stack — found by valgrind reporting fourteen thousand reads below the stack pointer on a program that printed the right answer; fixed on both backends. The multicore scheduler could lose a wakeup at a waiting point, a hang with no deadline — found by the emulated leg of the release gate, reproduced with a C driver under the emulator, fixed in the protocol’s own idiom with two siblings beside it. The loop optimizer crashed on an empty loop body; the constant folder refused at O2 a program it accepted at O0; an element access through a pointer hop and a bit-field store through a pointer crashed the code generator; an allocation’s reserve count was skipped by the analyzer’s passes; a dynamic array allocated through a pointer was homed in the wrong activation; an exported record alias crossed a library contract twice. Each has a case.

The compiler’s own gates

Mica’s compiler runs two internal quality gates on every compile of every test program, ahead of code generation: one over the analyzed program, one over the intermediate representation. In 7.5 they were audited against the compiler’s own code — every contract the code generator and the two backends demand is now stated by the gates first, so an internal fault is reported at the source line with the contract named rather than as a crash deep inside emission. The audit’s first run found a latent inconsistency the emitter had never met and fixed it the same day.

Around those gates, the release gate grew: valgrind over the heap, obligation and string cases on both architectures; the multicore package gate’s 296 legs; the price gate above; the harness’s own tests; the compiler’s package dependency graph pinned; position-independent and non-PIE builds and shared objects in the harness; every remark inventoried across the corpus so the programs users copy pass the compiler’s own review; and every Mica code block on this website compiled by the released compiler. The corpus stands at 13,033 runs on both architectures, every one green at the cut.

The first technical report

Everything above is foundation: the performance and efficiency work a language needs under it before what is built on top can be trusted, measured and stated. One thing stands on that foundation in this release, a new kind of document for Mica.

Technical Report 1 states the memory model whole: regions, ownership and the value model, where every byte lives, what the compiler proves and what the checked build catches. It is written for programmers and students, structured like a paper, and true of the compiler at the commit it names.

The toolchain

  • --static. A program links wholly statically and runs on a machine with no libc — the road to a container image built FROM scratch that holds one file. --strip beside it for the shipping shape; without it every function keeps its flat name for profilers and debuggers, and every tier carries call-frame information, so perf unwinds a release binary.
  • O0, O1, O2 and profiling. The level spellings stand beside debug and release. profiling joins any set — O2,profiling — and keeps the line table, the subprogram entries and the inlining records while the code stays the release build’s to the byte. A Mica binary is an ordinary ELF executable with DWARF 5 debug information and call-frame information at every tier, which is what the profilers and debuggers written for C read: perf samples and unwinds it, valgrind’s callgrind counts its instructions per source line, gdb steps it and names an inlined callee as its own frame, hyperfine times it. Nothing Mica-specific is installed or configured; Profiling a Mica program walks those four on one program, and the container ships them installed.
  • Two more remarks. Under --remarks, a regex Find standing inside a loop under utf-8 and a Part window formed from a match’s rune position inside a loop each name the linear road.
  • The GPU probe, scripted whole. The device floor’s kernels are held bitwise against a serial reference in 89 comparisons at four PTX targets on one card, and the four checks the release runs on real hardware are four scripts that refuse an unreachable host by name. The device work itself — Mica generating GPU kernels for suitable expressions — is 7.6’s headline.

Three spellings change

Each is refused by name with the new spelling in the message, so the fix is never a search; the announcement states each one and what to do.

Before 7.5From 7.5
libmicadragon-rt[-fixedarena][-mc]-<arch>.a, libmicadragon-<arch>.amica-dragon-rt[-fixedarena][-mc]-<arch>.a, mica-dragon-<arch>.amica-stdlib-<arch>.a is unchanged
--memory-class hosted--memory-class hosted-heap
--optimize checked meant debug,checked, and release,checked silently dropped its guardschecked is a flag beside either profile: a bare checked means release,checked, debug,checked keeps every variable observable at the trap, and release,checked keeps every guard

A program that lets the compiler find its archives, never names the memory class, and spells its optimization profile in full notices nothing.

Shipped alongside

The user container carries the benchmark suites with their wall-clock, memory and per-procedure attribution tables, the profiling tools installed, and the release’s examples; the learn area carries the profiling walk and the transcoding walk; Technical Reports 1 and 2 are published; VS Code extension 4.3.0 accompanies the release with this compiler’s language server. The next release, 7.5.1, follows directly with the plain-programming surface — environment variables, command-line arguments, a flags unit, process spawn — and the editor’s profile and export viewers; 7.6 is the GPU release.

Getting it

The packages are on the download page for amd64 and arm64; the container image micalang/mica:7.5.0 follows on Docker Hub. The facts page states where benchmarks and tests stand as of this release, and every number on it is generated from the repository rather than typed.