On Wed, Jul 1, 2026, at 12:22 PM, Tim Düsterhus wrote:
> 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”.

How about that.  Forgetting to respond to this thread meant you gave a good 
response for me.  Thanks, Tim. :-)

> 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

negated() would be consistent with the "ed means return new" pattern found in 
many languages, so I would strongly recommend following that pattern.

For the others, my inclination is to go short (add, sub) for easier typing and 
a more compact result, but that's not a make-or-break issue for me.

--Larry Garfield

Reply via email to