Most of what the Mica compiler guarantees depends on seeing the whole program’s behaviour. An indirect call is opaque: the analyzer cannot know its effects and the optimizer cannot reason across it. One such construct in the language would not weaken a guarantee slightly — it would remove the ability to make it at all.

So several constructs are refused by the compiler rather than discouraged in a style guide: reaching for one meets a parse error, never a silent acceptance.

The refusals are not all the same shape

This distinction matters when reading Mica code, and it is easy to overstate:

  • Absent from the grammar. goto and label are not keywords. They are not reserved either: both are legal variable names, and a program declaring them compiles and links. They are refused only as statements — written where a statement belongs, goto parses as a bare identifier.
  • Reserved, and accepted nowhere. with is a word the compiler knows. No rule accepts it, which also makes it unusable as an identifier — declaring a variable called with is itself an error. This is a stronger refusal than goto’s, not a weaker one.
  • Refused in one position only. procedure is a reserved word and the ordinary way to declare a routine — procedure Name();, parentheses required. Procedure declarations run right through the merge-gated corpus. What is refused is the procedural type: you cannot name a signature and store a routine in a variable.

Only the last is the function-pointer refusal — worth stating exactly, because “Mica has no procedures” would be wrong in a way that matters.

RefusedPrinciple it would breakThe replacement
goto and labelsstructured control flowleave / next, including leave <loop> when <condition>
with record donames mean what they sayexplicit selectors — p.x
procedural types (function pointers)analyzabilitycapability-constrained generics, unit finalizers, signalfd/timerfd, the task tree
pointer pointer Tone visible level of indirectionrecords with pointer fields
variant recordsthis is the silent-corruption classtagged alternatives via explicit types

Each of them but goto presents as a parse error naming the offending word — expected identifier or wildcard '*', found procedure for a procedural type, the same message with found pointer for a second level of indirection. goto is the exception, for the reason above: with no such word in the grammar, the parser can only report expected becomes, found identifier.

Variant records

Variant records are the clearest case, and the only one refused on safety grounds rather than language identity. A case arm inside a record — the untagged union — is rejected where the record body expects to end. Write one arm, read another, get garbage with no diagnostic: that is precisely the silent-corruption failure mode the whole project exists to eliminate.

The genuine need a variant record serves — a value that is one of several shapes — is not met today. It waits on user-definable capabilities, where the discriminant would be one the compiler enforces rather than one the programmer promises to check.

Every callback need has a known answer

The usual objection to refusing function pointers is that callbacks are necessary. They are — but each concrete need has a structural form the compiler can see:

  • Sorting by a comparison — a generic constrained by the ordered capability, monomorphized at the call site.
  • Cleanup on scope exitdefer, and unit finalizers.
  • Reacting to signals and timerssignalfd and timerfd, which are file descriptors, not callbacks.
  • Concurrent work — the task tree, where the compiler knows the whole shape.

Each one is analysable in a way an indirect call through a variable is not.

Named loop exits

The replacement for goto covers the case people actually reach for it — a bounded scan that stops the moment a guard fires:

    scan : for i := 1 to 100 do
    begin
        leave scan when i > 5;
        count := count + 1;
    end;

A named loop is left by name, from any nesting depth, without a label to jump to. The guard is evaluated on each arrival. The same when suffix guards next, and guards the bare leave that returns from a procedure early.

See also