In most array languages, m[1, :] hands you something — a view in numpy, a copy in MATLAB, and in either case a bug when you guessed wrong. Mica refuses the roulette outright: a verb whose name says copy answers a fresh value, always, and the borrowing twin has its own names on the spans page.

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

make -C examples/Slicing run

The copy verbs

r := Row(m, 1);            { one row of a 3x4, as a vector of 4 }
c := Column(m, 2);         { one column, as a vector of 3 }
corner := SubMatrix(m, 1, 2);   { a rectangle; its SHAPE is the target's }
run := Window(r, 1);       { SubMatrix in one dimension }

The result shapes come from declared types, so a row of a matrix[3, 4] of float64 is a vector[4] of float64 — checked at compile time. SubMatrix reads its rectangle’s shape off the assignment target: corner declares 2×2, the call names only the origin. Four value parameters, two sources, one generics deduction.

Column is a copy on purpose: a column of a row-major matrix is strided storage, and the three-word view cannot say so honestly — so there is no ColumnView to lie with, and the copy is the honest verb.

Independence, proven

r[0] := 999.0;
WriteLn("  after r[0] := 999, m[1, 0] is still %lf", m[1, 0]);   { 10.000000 }

The example edits the copy and prints the original — not a promise, a demonstration.

The constructors

ramp := Range(1.0, 2.0);   { start + k * step, one rounding per element }
eye := Identity();          { the eye, numpy's rectangular rule }
m := MatrixFill(1.5);
v := Fill(2.0);

All target-bound: the declared type on the left tells the call its shape, the same imposition every factory call reads. A constructor buried inside another call has no target to read — Exp(Fill(0.0)) is refused with the written-out escape named (5209'Fill of int64 (...)') — which is the imposition’s honest boundary, not a gap.

Guards, not clamps

Every verb guards its contract: an origin or index that does not fit panics with the contract named — the same loud answer at every optimization tier, never a clamp, never a wrap. The harness pins the panic’s file and line through every tier including full optimization.

What this does not do

  • No bracket slicing sugar. v[lo..hi] is exactly where the roulette lives in other languages; the named forms carry the semantics first. Sugar can come later — semantics cannot be retrofitted.
  • No strided views. ColumnView would need a fourth word and its own design look; recorded, not smuggled.
  • No allocation-free copies. A copy allocates its value on the stack like any Mica value; when you want zero copies, say so — that verb family is the span’s.

Try it

Declare corner : matrix[2, 3] of float64 instead and watch the same call return a different rectangle — the target is the shape. Then ask for SubMatrix(m, 2, 3) and meet the guard panic with its contract named.

Next

The borrowing twins — RowView, WindowView, and the span of T value they answer — are the spans page.