Pre-RFC: support negative duration or interval

Why

When processing date & time, negative duration or interval is inevitable, though weird.

And it is supported in many other programming languages, for example C++, Java, Julia, etc.

How

Add a field negative to indicate the duration is negative or not:

struct Duration {
    secs: u64,
    nanos: u32,
    negative: bool,
}

The default Duration is non-negative.

Reference

  1. The time crate defines a signed Duration
  2. The chrono crate allows for negative duration

Please provide significantly more detail. Nearly every API involving Duration currently assumes it is unsigned.

9 Likes

It is not inevitable. You can always swap the arguments and get a positive result.

1 Like

Presumably, however, this would add panic cases to some existing APIs which assume Durations are always positive. In particular, there's not much that thread::sleep can sensibly do with a negative duration.

Also, there are existing workarounds to avoid these panics:

  • SystemTime - SystemTime: Does not currently panic, because operation does not compile. Use SystemTime::duration_since instead, which does not panic.
  • SystemTime - Duration: Use SystemTime::checked_sub instead
  • Instant - Instant: Does not currently panic, saturates instead. Spurious¹ saturation only possible on non-Tier 1 platforms.
  • Instant - Duration: Use Instant::checked_sub instead
  • Instant::elapsed: Does not currently panic, saturates instead. Saturation only possible on non-Tier 1 platforms.

¹ i.e. Saturation which occurs when calculating A - B where instant A was observed after instant B.

NB: All of this information comes from the std docs; I have neither tested nor inspected the relevant source code.

3 Likes

How do I sleep for −3 seconds?

Live with a newborn :wink: .

18 Likes

sleep is already allowed to sleep for longer than the requested time, so there's no difficulty there.

1 Like

I would argue that the current semantics of Sub<Duration> for Instant is quite unfortunate on mac: Subtracting Duration from Instant on Mac is panic-prone · Issue #100141 · rust-lang/rust · GitHub

On Mac in the current implementation, Instant counts time from boot, so subtracting even a small amount from Instant::now could panic. This is exacerbated by the fact that on Linux this works just fine (it's Instant seems to start at u64::MAX / 2), so reproducing a mac-only just after reboot issue is hard.

5 Likes

If we compare time to one-dimensional motion, time corresponds to position, and time interval corresponds to displacement, then negative time intervals are natural. Likewise, positive and negative only represent the direction, and sometimes we don't care about the direction, such as physics doing work, sleep.

Now the question is, can the time interval be equated with Duration?

I encourage you to fill out the RFC template. Your writeup is a starting point for the Summary and Motivation sections, though they need to be fleshed out in a lot more detail. There are many additional sections to write up as well:

  • Guide-level explanation. Explain the proposal as if it was already included in the language and you were teaching it to another Rust programmer. This section should provide an example-driven introduction to the change, and explain its impact in concrete terms.

  • Reference-level explanation. This is the technical portion of the RFC. Explain the design in detail. The section should return to the examples given in the previous section, and explain more fully how the detailed proposal makes those examples work.

  • Drawbacks. Why should we not do this?

  • Rationale and alternatives. Why is this design the best in the space of possible designs? What other designs have been considered and what is the rationale for not choosing them? What is the impact of not doing this?

  • Prior art. It's important to not only link prior art as you've done but also explain and evaluate it. This section is intended to encourage you as an author to think about the lessons from other languages, provide readers of your RFC with a fuller picture.

  • Unresolved questions. What parts of the design do you expect to resolve through the RFC process before this gets merged? What parts of the design do you expect to resolve through the implementation of this feature before stabilization? What related issues do you consider out of scope for this RFC that could be addressed in the future independently of the solution that comes out of this RFC?

  • Future possibilities.

As you can see from the RFC prompts, it's important to capture the full scope of an idea. Not just what the idea is, but why it's helpful, what drawbacks there are, alternate proposals, limitations, and so on.

If you want help writing all this up please ask questions and tell us where you need assistance. As the idea originator you should do the bulk of the thinking and writing, though. Don't expect us to fill in all of the gaps.

A good next step would be to capture the questions and responses from this thread. Even if you have great answers for the questions and counterarguments for the criticisms, you still need to capture the questions and criticisms in your writeup.

4 Likes

Another alternative could be to keep unsigned duration, but make subtraction return absolute values instead.

A length of time between two events is always a positive number, so timestamp subtraction could return an absolute value of the difference, so that (a - b) == (b - a).

3 Likes