Skip to content

[8/15] Type-promotion and conformability semantics are tested bug-by-bug, not as the grid they form #129

Description

@mns-nordicals

What happens

The recent correctness fixes (promotion lattice, recycling rejection,
runtime shape guards, ifelse/BLAS contracts) each landed with bespoke
regression tests: one function per bug, exercising the exact cell that was
wrong. The semantics they collectively implement, however, form a grid —
every binary operation is a point in

mode(left) x mode(right) x shape(left) x shape(right) x op

and the policy for each point is fully determined by two small tables
(result mode + operand casts; conformable / compile error / runtime
guard). Nothing currently checks the grid systematically, so:

  • cells nobody happened to file a bug for are untested (e.g. most
    mixed-mode cells of %%, %/%, ^ across the shape pairs, reversed
    operand orders, logical operands in comparison/division positions);
  • there is no single artifact that demonstrates the contract holds,
    only a scatter of point tests;
  • any future refactor of the operator handlers has no regression
    firewall proportional to the surface it touches.

Expected behavior

A combinatorial test harness that transcribes the two contract tables
into an expected-outcome function and checks every cell against plain R
as the oracle:

  • valid cells: quick(f) matches R exactly — values, typeof(), shape;
  • statically invalid cells: quick() fails with the documented
    compile-time message;
  • statically undecidable cells: the compiled function runs a runtime
    guard — conformable inputs match R, nonconformable inputs raise the
    documented error instead of reading out of bounds.

Compile cost is controlled by packing: all cells that share a shape pair
are emitted as one compiled function per value-safety op family, with one
statement per (op, mode pair, operand order), so one gfortran invocation
covers dozens of cells. The default run compiles a fixed, deterministic
representative sample (~20 functions); QUICKR_FULL_GRID=1 unlocks every
shape pair. Value edges (negative bases and divisors, magnitudes past
2^24 and 2^31, descending ranges, TRUE/FALSE arithmetic) ride along as
input choices. NA/NaN-producing cells (e.g. division by zero) stay out:
NA support is a documented non-goal.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions