Hi
Am 2026-06-23 15:04, schrieb Tim Düsterhus:
Both Derick and I were receptive to the `Duration::sum()` suggestion.
One big benefit I am personally seeing is that it would allow to rename
the `negate()`, `multiplyBy()`, and `divideBy()` methods to use “past
tense” (is that the correct term?) to indicate that they return a copy,
without requiring awkward naming like `added()`. `->sub()` is also
technically redundant due to the existence of negative Durations, thus
there is no need for a mirrored pair like multiplication / division,
since the information can be encoded in the Duration object itself.
To avoid readers making assumptions, can you spell out your arguments
against replacing `->add()` and `->sub()` by a unified `::sum()`
method?
To close this out ourselves: While having a static `sum()` method works
for `Duration`s, since the Duration with addition forms an abelian
group, this doesn't work for the other future-scope classes where
addition doesn't form an (abelian) group. More specifically: Adding two
Instants together is not a meaningful operation. Adding a Duration to an
Instant however is. Using something like:
$epoch = Instant::fromUnixtime(0);
$onePointFiveHoursLater = Instant::sum($epoch,
Duration::fromMinutes(30), Duration::fromHours(1));
would be very weird. Instead `->add()` is the obvious operation here:
$epoch = Instant::fromUnixtime(0);
$onePointFiveHoursLater = $epoch
->add(Duration::fromMinutes(30))
->add(Duration::fromHours(1));
notably this would also work then:
$epoch = Instant::fromUnixtime(0);
$onePointFiveHoursLater = $epoch
->add(
Duration::fromMinutes(30)
->add(Duration::fromHours(1)
);
making the Instant + Duration -> Instant operation a “right group
action”.
We will thus keep instance methods for “addition” and “subtraction”. If
someone has a suggestion regarding naming (particularly with regard to
negate() vs negated() and multiplyBy() and multipliedBy()), I'll be
happy to discuss that. Java uses plus, minus, multipliedBy, dividedBy
and negated. Golang is just using an integer (meaning you just use the
operators). Rust’s std::time::Duration uses add, sub, mul, div (with
saturating and checked variants), but also overloads operators. Rust’s
chrono::TimeDelta is similar to std::time::Duration, but doesn't have
the saturating variants. JavaScript’s Temporal uses add, sub, negated
and doesn't support multiplication and division.
Please keep the `divide**By**()` (Duration / int -> Duration) vs
`divide**Into**()` (Duration / Duration -> (int, Duration)) suggestion
in mind when having opinions about the naming. See:
https://news-web.php.net/php.internals/131634
Best regards
Tim Düsterhus