SE-0374: Add `sleep(for:)` to Clock

Hello, Swift community.

The review of SE-0374: Add sleep(for:) to Clock begins now and runs through October 25th, 2022.

Reviews are an important part of the Swift evolution process. All review feedback should be either on this forum thread or, if you would like to keep your feedback private, directly to me as the review manager, either via email or PM on these forums. When emailing me directly, please put "[SE-0374]" at the start of the subject line.

What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

  • What is your evaluation of the proposal?
  • Is the problem being addressed significant enough to warrant a change to Swift?
  • Does this proposal fit well with the feel and direction of Swift?
  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available at

https://github.com/apple/swift-evolution/blob/main/process.md

Thanks for participating in this review.

Steve Canon
Review Manager

33 Likes

In the "alternatives considered" section, the proposal states:

The only potential problem would be if someone has already run into this shortcoming and decided to define their own sleep(for:) method on clocks.

I would like to clarify that this would not really be a problem; their code would continue calling their implementation until they decided to remove it. It is vaguely plausible that their implementation would not be semantically compatible with the stdlib implementation, but this is quite unlikely given the nature of the operation, and probably would indicate a bug in their implementation that should be fixed anyway.

8 Likes

+1! This will make it much simpler to use clocks as generic dependencies.

3 Likes

Yes, we need this. No objections (and in fact enthusiastic support) for the proposal as written.

9 Likes

+1 Clearly a missing needed API

1 Like

LGTM, no concerns AFAICS :slight_smile:

Looks good to me; great quality of use improvement!

1 Like

Enthusiastic support for this proposal, the use cases motivating the proposal are relevant to my team and the features we implement, preview and test.

During the pitch, this comment was made:

Perhaps what follows is reading a bit too much into the above comment. While I can't imagine how else it might work, could there be a way of avoiding the existential (that is, use a concrete type only) whose behaviour can be controlled environmentally, much like how a Task can inherit priority, could it inherit a clock or the clock inherit a way to control the passage of time?

  • Can the proposed method "back-deploy", by using @available(SwiftStdlib 5.7, *) and @_alwaysEmitIntoClient attributes?

  • Should the proposed tolerance: Duration? = nil parameter also be added to the existing method on Task?

4 Likes

Availability details are at the discretion of the platform vending the stable ABI, rather than Evolution. Technically there is no obstacle to doing so in this case, and it is in-line with API that we have done this for in the past, so I expect that we would do it here as well.

I'd like @Philippe_Hausler to weigh in on this.

3 Likes

I think that is a very reasonable request that we should do; basically pull it back to as if it were introduced in the same release as Clock itself.

Per the tolerance part; that is a good catch - it is of course still available in the Instant form of that API but it would make the on-ramp of the progressive disclosure even smoother (with little to no impact on maintenance). sleep(for:) progresses to sleep(for:tolerance:) to sleep(until:clock:) to sleep(until:tolerance:clock:). So yea that seems like a very minor and reasonable addendum.

9 Likes

The question as to whether a proposed feature will be back-deployed is at the discretion of the platform vendor, but the question whether a feature can be back-deployed is a relevant question for the purposes of the Evolution process, IIUC, that falls under the โ€œimpact on ABIโ€ part of the proposal.

5 Likes

Then, "yes, this can be back deployed using said mechanism."

7 Likes

+1, I think this is a great addition.

Many time-related APIs in Foundation use this pattern you defined as "instant-based" as their primary mechanism and I always thought it was weird that they didn't include conveniences like the proposed one given that this is what most people tend to use them for.

1 Like

+1, the texting use case is compelling.

1 Like

+1 this fits right in as it should have been part of the initial API.

1 Like

Existentials aren't so bad - especially now that we can use the language's actual existentials for PATs. I've found that the compiler is quite good at devirtualising them, so they can perform identically to generics in many situations.

For something like this where you're going to be suspending for some appreciable amount of time anyway, I think the overhead of using an existential is going to be negligible. And if you do find it to be significant, you can still opt for a restricted set of concrete types by defining an enum. In any case, this function would still be a convenient addition.

1 Like

Please donโ€™t get me wrong, I understand and completely agree with this, but I tend to think of the method as more of a necessary addition given the obvious pain points it solves. My point in bringing it up was to stimulate some imaginative discussion where developers could control the passage of time or not with the same concrete type.

+1, great examples in the proposal!

+1 and thanks for the discussion and clarifications from the team.