Of that list,
Opinions on "1.0 ability"
1.0 only really matters for "vocabulary" crates, where their intended use case is as a public dependency. Taking 1.0 to mean "we don't expect to ever want to make breaking changes,"
- libc is essentially committed to staying 0.2 forever. The 0.1=>0.2 move isn't (sometimes) referred to as the libcpocalypse for no reason. I see one scenario where libc goes to 1.0:
- it's api compatible and semver tricked,
- we're confident that Rust has the capability to express all C API features with full accuracy and matching the forward compatibility of ABI-stable C (this means at least opaque extern type support), and
- we've developed some standard for LTS and MSRV of LTS.
- getrandom: As you mentioned,
getrandom
is (slowly) on its way towards being included in std as a minimal interface to the OS's "strong" randomness source
.
- rand_core: How best to implement or consume pseudorandomness (especially where cryptographic integrity is concerned) is still evolving, even outside of Rust. I expect committing to a stable
CryptoRngCore
to be undesirable still (and especially with upcastable traits coming "soon").
- There's also
SeedableRng::seed_from_u64
; rand considers determinism a stability guarantee, and that provided trait method embeds a small rng to mix any u64 into a "reasonably good quality" rng seed. The choice of how this is done is both currently considered part of the stable ABI and is subject to wanting to be replaced with a different choice in the future.
- But I could see at least considering
RngCore
as "1.0 stable," and it's certainly a downstream public interface member... except that the error type definition is not really obviously correct; it would kinda prefer being a no_std-compatible std::io::Error
.
- rand_chacha: As far as I understand it, not intended to be a public API member. Also blocked on the rand_core public dependency.
- base64: Not intended as a public dependency, and still seeing breaking API updates. (Efficient decoding interfaces aren't trivial!)
- hashbrown, parking_lot: have stable equivalents in std.
- time: APIs for time are complicated. Has a std alternative in
SystemTime
, although it's a bit more clunky to use and doesn't support timezones.
- log: Like libc, seems for-the-most-part frozen to 0.4. Currently working on support for structured logging (attaching arbitrary fields to logs), which probably blocks it from being "1.0 ready."
- AIUI they're currently aiming towards making the structured logging backend production and consumption stable, but not the macros yet. Perhaps a log-core for just the sink interface could make sense and 1.0 earlier?
- The global state would still live in the
log
crate; log-core
would be just the Log
trait and supporting cast.
- Depending on how exactly it's done, this could even separate out "simple" unstructured logging and 1.0 it before structured logging.
- But this very much ends up feeling like an exercise in making API subsets 1.0 just for the point of them being 1.0, not for actualizable benefit.
- On the other hand, I don't know the comparison/tradeoff/choices between log's sval and tracing's valuable. (log is an established choice, but tracing (is a lot more complex and) I think has a bit more adopted velocity.)
- tracing_core: (for comparison): has been 0.1 since it existed. tracing was designed for downstream extension, so this has been possible... but also has a long-running 0.2 branch with some (very useful) renaming for clarification and some pending possible breaking changes they'd like to make to the core abstraction. 1.0 isn't happening without 0.2 first, and 0.2 isn't happening without a reasonable migration plan.
From that I guess the best takeaway is that library design is difficult. In the cargo backlog is a feature for differentiating between public and private dependencies. It's reasonably plausible that if/when cargo gets support for explicitly public/private dependencies, that libraries with separate public/private API subsets will more often split themselves to take advantage of such. Better tooling support for split crates will help this as well.
And to repeat the point: while "late 1.0" is common within the Rust community, it's increasingly common darn near everywhere in the software space. But truly, it's less of a consistent ecosystem choice to avoid 1.0, and more that people (especially in Open Source) are a lot more open to sharing code for reuse before it's "done." There's no large-scale "solution" to widely used crates being 0.Y a lot of the time; the solution is individually tracking the 1.0 blockers for the crates you care about, and helping them to clear those blockers and publish that 1.0 version.
on glam, specifically
I meant to say this in my earlier, but I don't think I did.
Linear algebra terms may be fairly stable, and you might even consider the desirable API for doing linear algebra w.r.t. games a fairly set beast. But neither are really fully true.
To the latter, simd in Rust is still cooking, and this has impacts on API choices, such as when it's preferable to pass by-copy or by-reference. This makes a much larger impact on SIMD-enabled types because of the additional cost of moving things into and out of SIMD registers.
To the former, game maths typically use vec3
for multiple different concepts, such as direction, offset, position, and cross product. I think glam's fairly bought into just being semanticless math shapes, but other libraries are proving out benefits of separating these concepts more clearly. There's an entire field of mathematics called geometric algebra essentially derived from the fact that the cross products don't really produce a vector, but rather what geometric algebra calls a bivector, which makes the idea of cross product properly scale to different dimensionality, and uses bivectors to build a different version of Quaternions called Rotors, which are arguably easier to conceptualize and work with.
Typically, in almost any field you perceive as stable and/or solved, you're just not aware of the complexity hidden under the surface if you know where to look for it. And too many times, that hidden complexity has enough of an impact on API design choices that makes it difficult to commit to fully stable interfaces.
Rust also has a really high bar for API stability. It really does seem unfortunate that it's not (reasonably) possible to have multiple incompatible interfaces visible to different users of the same semantic type.
And additionally, glam wants to (optionally) provide a number of implementations of (presumably) upstream traits from crates which aren't themselves 1.0, including but not limited to the aforementioned rand, and the ever difficult-to-stabilize num-traits (but which to be fair seems essentially 0.2-frozen due to the inertia of being widely vocabularized).