Skip to content

Support Interval 2.0 - #14

Draft
robertvansteen wants to merge 2 commits into
mainfrom
brick-interval
Draft

Support Interval 2.0#14
robertvansteen wants to merge 2 commits into
mainfrom
brick-interval

Conversation

@robertvansteen

Copy link
Copy Markdown
Contributor

Draft — blocked. Needs gosuperscript/axiom 0.6.9 and gosuperscript/interval 2.0.0 tagged first (gosuperscript/axiom#82, gosuperscript/interval#6). Marking ready once they publish.

Widens to superscript/interval ^2.0 and gosuperscript/axiom ^0.6.9.

Interval 2.0 no longer accepts a float in its bound comparisons, because a binary float carries no exact decimal value to compare with — the literal 0.1 is not one tenth. The host language still yields int|float scalars, so exact() renders one as the shortest decimal that round-trips to it, which is the number the source text denoted:

Operator::infix('<')->takes($interval, $number)->returns($boolean)
    ->evaluatesWith(fn(Interval $left, int|float $right) => $left->isLessThan(self::exact($right))),

format() took mixed and cast it to string, which quietly accepted anything stringable. It now rejects a value that is not an Interval, with the same TransformValueException the coercions raise.

Verified against the local chain: PHPStan clean, 28 tests, 100% coverage, MSI 100%.

robertvansteen and others added 2 commits August 5, 2026 18:47
Interval no longer accepts a float in its bound comparisons, because a binary
float carries no exact decimal value to compare with: the literal 0.1 is not one
tenth. The host language still yields int|float scalars, so exact() renders one
as the shortest decimal that round-trips to it — the number the source text
denoted — and the four ordering operators pass their operand through it.

format() took mixed and cast it to string, which quietly accepted anything
stringable. It now rejects a value that is not an Interval, with the same
TransformValueException the coercions raise.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The float conversion vouched for a guarantee it did not provide. PHP's
`(string)` cast on a float honours `precision` — 14 significant digits by
default — not `serialize_precision`, so it truncates and can emit exponent
notation: `(string) 123456789012345.67` is `1.2345678901235E+14`, which is
123456789012350. A bound sitting between the two compares to the wrong side.

`json_encode` honours `serialize_precision` (-1) and yields the shortest decimal
that round-trips, which is what the docblock describes. A comparison case with a
bound in that gap pins it, and fails on the old cast.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant