Today is Leap Day, so I'd like to introduce you to a new Swift package I've been working on for over 2 years:
Time is a package that makes date and time calculations more expressive and safe in Swift. It's built on the power of Foundation's APIs, but smooths away their many rough and ambiguous edges. It relies heavily on Swift's generics to guarantee that the calculations you're performing are calendrically correct. If you'd like an overview of how it works, be sure to check out the documentation.
I'm releasing it today as an 0.9.0 version. I hope you will clone it and use it in your apps!
Well first off, having read through the documentation, Iām wondering what the rationale is for choosing the spelling clock.thisInstant() instead of clock.now().
And second, I think some of the type names are not specific enough, including Absolute, Value, Difference, and AbsoluteValueSequence.
now() is the same thing as thisInstant(). It has both because now() is the "proper" naming, but thisInstant() also helps it be consistent with thisDay(), thisMonth(), thisSecond(), etc.
Naming has been my #1 most difficult task with this framework. If you look on the "Roadmap" page, you'll see that I definitely want to rename Value, but only if I can find something better. I've spent weeks scouring sources for more definitive names for "a subset of calendrical values that may or may not be anchored to an actual calendrical point", but haven't come up with anything that really feels "better".
Difference used to be Delta; I renamed it in the hopes that Difference would be a bit clearer. Absolute (and the WIP Relative) used to be Anchored and Floating. AbsoluteValueSequence is basically just derived from Absolute.
I'm absolutely open to suggestions on better names. I'd prefer names that are terms-of-art, but I have yet to find such nomenclature.
Yeah, I donāt know what the types should be named, but I think the names should at least indicate that they have something to do with time. Spellings like Value, Difference, Anchored, and Delta seem too general-purpose, especially when used in an app that imports many different libraries.
To be fair, the names are all technically namespaced within the module, so we're really talking about a Time.Value, a Time.Difference, a Time.Absolute, etc..
But yes, in principle I agree. The current names are the "least bad" ones I've been able to come up with.
From reading the documentation, I have one comment, and thatās that your usage of the term āunsafeā seems to be at odds with how itās generally used in Swift.
āUnsafeā in Swift generally refers to memory safety. For example, in the Standard Library unsafe in the name of a type, method or parameter means that Swiftās standard guarantee of memory safety no longer applies, and unless you know what youāre doing you might have memory leaks, memory corruption or even undefined behavior on your hands.
You seem to be using āunsafeā to mean that an adjustment may throw. Thatās not the same. To someone accustomed to the Standard Libraryās usage of āunsafeā, it makes these adjustments look much scarier than they actually are.
Skimmed through the code a bit and it seems quite serious in tackling the calendar weirdnesses, that's great The topic of time/calendars is such a complete minefield...
I'd push back against this one. IMO properties ought to produce the same value when accessed repeatedly unless there's some intervening (imperative) logic.
The name that comes to mind is FailableAdjustment, since thatās essentially what they are: adjustments that can fail. I guess you could argue that āfailableā also means that they should return nil instead of throw, since thatās what failable means when we talk about initializers. I donāt have enough experience with the API yet to know if that would make sense. Regardless, something āfailableā that doesn't return nil seems to me a lesser sin than something āunsafeā thatās completely memory safe.
There are different kinds of "safe" in Swift. There's the memory safety you've brought up, but there's also type safety, the safety of exhaustiveness checking, etc.
It's true that "unsafe" has typically only referred to memory safety, but given then other kinds of "safety" guarantees that Swift provides, it seems reasonable to me to use the same term here.
However, I'm absolutely willing to change it if we can come up with a superior name.
We can just drop Unsafe. throws-ness signals plenty enough of that. And while I agree that there are multiple kinds of safety in swift, Unsafe is still used exclusively for memory safety.