Mica 7.6.5 finishes what 7.6 began across activations and processes. A task, a generator, a stream and a worker process now take any value a program holds by value: text, arrays and records of them, to any depth. A worker process receives the sockets, pipes and files its task names. And how many carriers and worker processes a program runs is a range the program states and the runtime reports.
C libraries meet Mica as they are written, with their handles, their text and their status codes, and the sqlite library is rebuilt on them. A library is linked only under a version, and a program says which versions it accepts. The editor extension 5.1 shows what a stopped program holds, and runs and debugs a Mica file with nothing to configure.
The release at a glance
| Subject | What changed |
|---|---|
| Values cross every activation | tasks on carriers, tasks on a process and generators take text, arrays and records to any depth by value; every such value is a stream element |
| Generators and streams on a process | a producer placed on process feeds a stream from a worker, and a lost worker is answered where the stream is read |
| Descriptors cross to workers | the descriptor type; a task on a process receives the sockets, pipes and files its arguments hold |
| The scale a program runs at | --processes N and +mica processes=N -mica, 1 to 1024 workers beside 1 to 1024 carriers, oversubscription stated |
| C libraries as they are written | opaque handles, text from C, status codes, results through a pointer, a thread_safe statement per handle type |
| sqlite, rebuilt | statements as values, rows by a generator, every column type and NULL, transactions, sqlite’s codes as failures |
| Versions | a library linked only under its version; requires in mica.project; pkg-config minimums for C libraries |
| Memory held to account | an overwritten owning slot refused where it loses its cell; the leak report names each cell’s type and line |
| The editor 5.1 | what a program holds at a breakpoint; F5 with nothing to configure; the launch card sets how a program starts |
Values cross every activation
A task’s arguments were always snapshots: schedule copies them at the moment
it runs, so a task never reads a variable its parent changes afterwards. In
7.6.5 the snapshot is the whole value, whatever it holds. A record with a name
and a list of scores crosses the way a number does:
task Report(who : Player);
var
total, at : int64;
begin
total := 0;
for at := 0 to Length(who.scores) - 1 do
total := total + who.scores[at];
WriteLn(" %ls scored %lld in %lld rounds", who.name, total, Length(who.scores));
end;player.name := "Ada";
player.scores := new Scores reserve 0;
Append(address player.scores, 12);
Append(address player.scores, 30);
concurrent
schedule Report(player);
player.name := "Grace";
player.scores[0] := 0;
Append(address player.scores, 99);
end; Ada scored 42 in 2 roundsThe task receives its own copy of the text and of the array, made at
schedule in memory the task owns and released when the task ends. The same
holds for a task placed on a process, for a generator’s arguments, and for
every stream element, pulled or through a ring. What cannot cross is a
pointer, because it names memory the receiver could not own, and the compiler
names the field that holds it. The tasks and
generators tutorials walk the rules.
Generators and streams on a process
A producer placed on process feeds a stream from a worker process. The
stream is read as any other, and because a worker can end before the stream
does, the consumer says what a lost worker means: in the stream’s on lost
section, or in the arm of a select that reads it. The compiler asks for that
answer where a producer runs on a process (5600, 5602), and refuses it where
none does (5601). Tasks on processes shows the
whole road, a library’s tasks included.
Descriptors cross to workers
The new descriptor type names an open socket, pipe or file. It converts to
and from the machine integers and to nothing else (5603), so a descriptor can
never be mistaken for a count or an index. A task placed on a process receives
the descriptors its arguments hold: each is duplicated for the worker as it is
placed, so a server may close its own copy the moment the task is placed, and
a number that no longer names an open descriptor is refused by name.
ListenIpc answers only its own user, and DialIpc refuses a listener that
another user opened, both read from the peer’s credentials, so a local socket
path cannot be taken over by another account on the machine.
The scale a program runs at
--processes N, or +mica processes=N -mica at the start, sets how many worker
processes run the tasks a program places on processes at once, from 1 to 1024.
A pool holds 1 to 1024 carriers. A task placed beyond the count waits until a
worker ends, and a stream on a process takes no worker slot, because its
consumer paces it. Asked with info, a program says what its start resolved
and whether the machine can run it all at once:
mica --tasking multicore,4 --processes 2 Scale.mica +mica carriers=32 processes=64 info -mica"configuration":{"carriers":{"effective":32,"source":"flag","oversubscribed":true},
"processes":{"effective":64,"source":"flag","oversubscribed":true}}The machine here has sixteen processors, so both counts are stated as oversubscribed, and the program runs them in turn. The pool itself got faster on the way: five thousand placements behind two workers complete in under a second.
C libraries as they are written
A C library’s contract now states what its functions really hand over. An
opaque handle, a pointer whose layout is the library’s alone, crosses into
generators, tasks and stream elements as a value. Mica never makes, reads or
releases what it points to (5607 to 5609), and its contract states whether the
type is thread_safe, which the data-race checks honour on every road into a
task (5610, 5611). Text a C function answers as a const char * arrives as a
Mica string. A status code becomes a failure on the failure channel, and a
result written through a pointer becomes the call’s result. A generic or
generator body that a library exports may call the library’s private routines
and use its private types, which cross hidden with the body.
The sqlite library is rebuilt on these, with no C of its own: statements are values, rows arrive by a generator, every column type and NULL is read as it is stored, transactions are part of the library, and sqlite’s own codes arrive as failures.
Versions a build can rely on
A library is linked only under a version, and a program says which versions of each library it accepts, the way Cargo and npm read a requirement:
{
"sources": ["demo.mica"],
"contracts": ["../build/sqlite"],
"version": "1.0.0",
"requires": {"sqlite": "2.0"}
}A C library’s contract names its pkg-config package and the minimum it needs, and the build asks the machine’s pkg-config. A link refuses an archive another build made, and a standard library or a runtime floor another compiler built, each by name.
Memory held to account
A store that overwrites the only owner of a cell that nothing released is refused where it loses the cell:
c := new Box;
c.l := new Leaf;
c.l := new Leaf;obligation error 13110 [13,6]: heap cell is lost here: this store overwrites the owning slot that held
the cell allocated at line 12, which nothing had released, and nothing releases it after - dispose the
slot's cell before storing into the slot, or read it out into a name that disposes it or hands it onThe checked build’s leak report names each cell by the type it holds and the
line that made it, Cell, made at HeapLeakTrapsChecked.mica:32:17, 16 bytes,
where it used to name an address. A program that ends joins its carriers and
gives back the scheduler’s own tables, so a checker finds nothing left behind.
The editor 5.1
Stopped at a breakpoint, or attached while it runs, a program shows what it holds: its cells summed by type with the line that made each, and every region block as a gauge of its capacity over a strip of its cells.

F5 builds and debugs the Mica file in focus with no launch or task file. The launch card above a program sets the runtime flags and arguments it starts with, and Run, Debug and F5 all start the program that way.
Upgrading
Two things a 7.6.0 build accepted are refused by name in 7.6.5, each with what to write instead:
- A build from a
mica.projectstates the project’sversion, as"1.0.0"; a program compiled from its sources with flags alone, or run as a script, needs none. - A store that loses a cell by overwriting its only owner is refused (13110), where 7.6.0 compiled the leak.
The packages and the commands that install them are on the install page.