SE-0329: Clock, Instant, Date, and Duration

First off, I'm quite surprised this is going up for review already. There was only the single pitch thread, and (from what I saw) the public proposal text was never updated for further feedback. This review seems premature.

That being said...

What is your evaluation of the proposal?

-1. This proposal is a good start, but I fundamentally object to the inclusion of moving Date into the Standard Library and do not believe the proposal should move forward as long as that's part of it.

Is the problem being addressed significant enough to warrant a change to Swift?

Yes. The addition of the Clock and Instant types is long overdue. I also really appreciate @Philippe_Hausler's incorporation of custom clocks (and the accommodations to the various protocols to support them). Those will be enormously beneficial. I'm excited to use them (and delete my own versions of them!).

Does this proposal fit well with the feel and direction of Swift?

Overall, mostly. The Clock and Instant additions are great and we should absolutely accept those. I have two major specific concerns:

  1. The presence of .minutes(...) and .hours(...) on Duration are going to be abused by developers wanting fundamentally different concepts. I do not think they should be there, because they look like the right thing, but might not actually be what you want. You think "ah, I want to show something to the user 3 hours from now, therefore I do myWallClock.now + .hours(3), without realizing that this is usually the wrong approach to be taking.

    Because of this, I would like to see Duration limited to only .seconds(...).

    At a broader level, I can see potential trouble for having a single Duration type that's common to all Clocks. With the ability to create custom clocks, it seems reasonable that I'll be able to make a RegionalClock that is calendar, timezone, and locale-aware. For such a clock, I don't think I'd want to use common Duration type, because of the complexities around calendar-aware durations. Thus, the requirement that my RegionalInstant type be forced to advance by a Duration seems counter-productive. I'd instead want to make sure that my type only supports a calendar-aware Duration. This leads me to believe that perhaps Duration should be another associated type on the Clock protocol. I know this came up in the pitch thread, but I believe it needs further examination and is part of why I'm surprised to see this move to review phase already.

  2. Date should not be moved into the standard library. There is universal agreement that "Date" is the wrong name for the type. Even the manager of the Foundation team concurs. Here, with the introduction of new timekeeping APIs, we have the opportunity to correct this, and we're instead proposing to double-down on this very confusing name.

    What I keep coming back to is asking myself this question: "do we think Swift's popularity has peaked?". I don't believe so. I sure hope not. I believe that interest in Swift will continue to grow, and that our current developer community size is a fraction of what it will eventually be.

    To me, that strongly implies that we will have more new Swift developers than what we currently have, and every single one of them will need to be taught: "This thing that's called Date is not actually a date".

    We can do better than this, if we're willing to accept some minor, short-term discomfort for the sake of longer-term pleasantness.

    The proposal discusses an alternative:

    It is true that there will be short-term confusion if we have both WallClock.Instant and Date, or if we deprecate Date in favor of WallClock.Instant.

    But how does that short-term confusion stack up against the confusion that millions of future developers will face every time they encounter this incorrectly-named type?

    Two of Swift's stated goals are to be "safe" and "expressive". What is safe and expressive about having a confusing API because we gave a concept the wrong name? We claim that "Swift benefits from decades of advancement in computer science to offer syntax that is a joy to use". I submit that renaming Date is an opportunity to contribute to that goal, just as the rest of our language and APIs have. We owe it to every current and future developer who uses this language and library to give them the best-possible thing we can make, and I do not believe the Date name is capable of fulfilling that goal.

    I think the way forward would be:

    • Create WallClock.Instant as a separate concept from Date
    • Deprecate Date (but not NSDate)
    • Teach the importer to create both WallClock.Instant and Date-taking versions of methods
    • Do this over a major release or two if we're really worried about churn and confusion

If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

In other comparable languages, the term Date has been eschewed entirely. Any locale-aware language prefers terms like Moment and Instant for the "instantaneous point in time" concept. The only major exception I can think of to this is JavaScript, but that's a false positive because the JS definition of a date is intrinsically tied to a Gregorian calendar. All major languages use names like ZonedTime or LocalDate for calendar-aware types.

How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

I've been building calendaring APIs for a decade. This is basically my thing.

64 Likes