You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
While there are a smattering of useful const functions in Jiff (like Date::constant), the vast majority of all routines are notconst.
When I originally set out to build Jiff, I had a goal of making as much of the crate const as possible. In theory, most APIs are "just math" and thus should be const. The only things that at least conceptually cannot be const in a datetime library are things like:
Determining the current time.
Determining the current time zone.
Reading time zone data from a database at runtime.
But everything else can pretty much be const. More than that, I believe const in Rust is expressive enough where one could actually write a datetime library with that sort of support today (2024-03-10).
However, despite starting with this goal, I quickly gave it up. The specific thing that caused me to give up were Jiff's internal ranged integer types. They are built in a way where they track additional state and do additional checks whenever debug_assertions is enabled. And crucially, they give half-way decent error messages when an invariant or boundary is broken. I found it incredibly difficult to make all of this work in const. Some issues I ran into:
While adding two i32 values via the + operator (and others) works in const Rust today, this is not supported for custom types. As far as I can tell, support for primitive operations like this is special cased in const Rust. But because traits can't be used in const Rust today, I'm not able to use operator overloading for ranged integer types. While this is technically a surmountable hurdle by simply declining to use operators, I found this to be far too annoying of a hurdle to clear. Moreover, I was unwilling to give up my specific formulation of ranged integers due to their incredible ability to provoke bugs in code that I never would have caught.
I found it very difficult to write nice panic error messages in const functions because none of the formatting machinery is available. This essentially means it is quite difficult to write a message that includes the troublesome value(s) and relevant boundaries. While this is also a surmountable hurdle by simply living with worse error messages, this was too big of a pill to swallow. It made diagnosing and tracking down bugs provoked by ranged integers too difficult.
While I mentioned this in the first bullet point, the overall inability to use traits in const Rust is a huuuuuge buzzkill. And this was especially damning in a ranged integer abstraction. In particular, ranged integers don't really want to care about their primitive representation. You want to be able to add an ri8 with an ri32 without thinking about casts or whatever. Indeed, that is their superpower. But of course, you still want to be able to specify a primitive representation so that types like Date are only 4 bytes. To make all of this work, you want impl Into<RangedIntegerTypeYouWant> everywhere. This is simply incompatible with const Rust as it exists today.
And that's just for the ranged integers. I honestly don't know what other kind of issues I'd run into, but I never really got the chance to explore it. In particular, ranged integers are such a core and fundamental part of this library's internals, that if they can't be const, then pretty much nothing can be. Indeed, even the existing const routines like Date::constant specifically need to duplicate code just to work in const Rust.
This is overall something I'd like to support, but I think const Rust needs to evolve considerably before it's compatible with the internal architecture of Jiff. In theory, Jiff could use something else that is more const friendly internally, but the hurdle it will need to clear is huge. My best guess is that it will be years before this library sees a meaningful increase in the surface area of const APIs.
I may be willing to consider one-off cases of making an API const, but the trade off will almost certainly be something like, "duplicates code and gives up ranged integers." In other words, there probably needs to be a compelling use case for it to be const. Something like Date::constant is compelling because it's not uncommon to want to write dates in source code and treat them as constants. On top of that, these routines are limited to cases where there is no or very little code duplication and the operation is itself not too complicated.
The text was updated successfully, but these errors were encountered:
While there are a smattering of useful
const
functions in Jiff (likeDate::constant
), the vast majority of all routines are notconst
.When I originally set out to build Jiff, I had a goal of making as much of the crate
const
as possible. In theory, most APIs are "just math" and thus should beconst
. The only things that at least conceptually cannot beconst
in a datetime library are things like:But everything else can pretty much be
const
. More than that, I believeconst
in Rust is expressive enough where one could actually write a datetime library with that sort of support today (2024-03-10).However, despite starting with this goal, I quickly gave it up. The specific thing that caused me to give up were Jiff's internal ranged integer types. They are built in a way where they track additional state and do additional checks whenever
debug_assertions
is enabled. And crucially, they give half-way decent error messages when an invariant or boundary is broken. I found it incredibly difficult to make all of this work inconst
. Some issues I ran into:i32
values via the+
operator (and others) works inconst
Rust today, this is not supported for custom types. As far as I can tell, support for primitive operations like this is special cased inconst
Rust. But because traits can't be used inconst
Rust today, I'm not able to use operator overloading for ranged integer types. While this is technically a surmountable hurdle by simply declining to use operators, I found this to be far too annoying of a hurdle to clear. Moreover, I was unwilling to give up my specific formulation of ranged integers due to their incredible ability to provoke bugs in code that I never would have caught.const
functions because none of the formatting machinery is available. This essentially means it is quite difficult to write a message that includes the troublesome value(s) and relevant boundaries. While this is also a surmountable hurdle by simply living with worse error messages, this was too big of a pill to swallow. It made diagnosing and tracking down bugs provoked by ranged integers too difficult.const
Rust is a huuuuuge buzzkill. And this was especially damning in a ranged integer abstraction. In particular, ranged integers don't really want to care about their primitive representation. You want to be able to add anri8
with anri32
without thinking about casts or whatever. Indeed, that is their superpower. But of course, you still want to be able to specify a primitive representation so that types likeDate
are only 4 bytes. To make all of this work, you wantimpl Into<RangedIntegerTypeYouWant>
everywhere. This is simply incompatible withconst
Rust as it exists today.And that's just for the ranged integers. I honestly don't know what other kind of issues I'd run into, but I never really got the chance to explore it. In particular, ranged integers are such a core and fundamental part of this library's internals, that if they can't be
const
, then pretty much nothing can be. Indeed, even the existingconst
routines likeDate::constant
specifically need to duplicate code just to work inconst
Rust.This is overall something I'd like to support, but I think
const
Rust needs to evolve considerably before it's compatible with the internal architecture of Jiff. In theory, Jiff could use something else that is moreconst
friendly internally, but the hurdle it will need to clear is huge. My best guess is that it will be years before this library sees a meaningful increase in the surface area ofconst
APIs.I may be willing to consider one-off cases of making an API
const
, but the trade off will almost certainly be something like, "duplicates code and gives up ranged integers." In other words, there probably needs to be a compelling use case for it to beconst
. Something likeDate::constant
is compelling because it's not uncommon to want to write dates in source code and treat them as constants. On top of that, these routines are limited to cases where there is no or very little code duplication and the operation is itself not too complicated.The text was updated successfully, but these errors were encountered: