Every dependency in Mica enters through the imp section — that has been true since the first unit. 7.0.0 adds a second granularity to it: qualification, the dotted name that states a word’s origin at its use.

The example is examples/Qualification. Build and run it:

make -C examples/Qualification run

Two granularities

imp
    WriteLn : std;
    Clamp, Pi : math;
imp cstd;

The grouped import imp Clamp, Pi : math does what it always did — the names arrive unqualified — and now also makes math addressable, so math.Pi is equally sayable when a reader wants the origin visible.

The bare import imp cstd; puts no name in scope: a bare Sqrt stays identifier not found, but every exported member answers to the dot — one grain that gives the whole namespace to the dot and nothing to the bare word, made for math-heavy code:

x := cstd.Sqrt(2.0);
WriteLn("  cstd.Pow(2.0, 10.0) = %lf", cstd.Pow(2.0, 10.0));

The transcendentals read as what they are — C’s, by name — while Mica’s own verbs stay bare words. One meaning per word, and the call site states the split of labor instead of hiding it.

One mechanism underneath

Resolution stays declaration-first: a declared name wins the bare word, and a qualified name is an import in disguise — the dot rides the same one lookup mechanism every other name rides, materialized as an alias view under a dotted key. No second resolver, no search path, no surprises.

std, cstd and math are reserved words, so the three core qualifiers can never be shadowed. A vocabulary unit’s name stays a claimable word — a local simply shadows the dot road, by the ordinary scope rules.

The template boundary

A generic template never qualifies: a template is grafted under its own name — its body may reference that name — so math.Clamp is refused with the remedy spelled out:

5438: generic template 'Clamp' cannot be used through qualification: a template
is grafted under its own name, so import it by name — 'imp Clamp : math' —
and use it unqualified

Concrete functions, constants and types qualify; templates come in by name. The example’s dots stand on math.Pi and cstd’s concrete surface for exactly this reason.

What the compiler refused

The program tried toThe answer
math.Clamp(…) with math addressable5438 — the template boundary above
a dot on a namespace no import mentions5436: the qualified name 'math.Clamp' needs its namespace imported first: 'imp math;' makes the whole namespace addressable, and importing the member by name is the unqualified road
cstd.NoSuchName(…)5437: 'NoSuchName' is not an exported member of library 'cstd'

What this does not do

  • No wildcard dots, no search order. A dot names one namespace; two namespaces exporting one word never race, because the dot said which.
  • No renaming through the dot. A site-local rename is the import alias imp Say = WriteLn : std — the dot always speaks the exported name.
  • No qualification of keywords or locals. The dot is for imported namespaces; everything else is the scope chain you already know.

Try it

Remove imp cstd; and watch every cstd. use answer 5436 with the remedy in the message. Then add a local variable named cstd and watch the scope rules — not a special case — decide.

Next

The naming doctrine this page lives under — what may abbreviate, what is frozen, and why WriteLn stays — is the 7.0.0 release story, told in the release notes.