They do not want a big stdlib. The downsides are real (the stdlib cannot make breaking changes), and there are no upsides (except, maybe, for faster compilation, since std comes precompiled).
They want more official crates (e.g. `regex` and `libc` are official crates, maintained by the Rust project). And the Rust project does not oppose to that, it just doesn't have the funding.
There are upsides, your program is smaller, better security because a random kid can't pwn your deps, quality and interoperability. What's not to love?
The std making a breaking change is the language making a breaking change. Most mainstream languages guarantee stability, certainly Rust.
> your program is smaller
How so? It doesn't matter if the code is in std or a crate.
> better security because a random kid can't pwn your deps, quality and interoperability
That's exactly what I said: you don't need bigger std, you just need more official crates.
That's their mistake, right there... When you're upgrading software, you presumably want a better version. You can't have something better without changing it. It's a logical contradiction.
>It doesn't matter if the code is in std or a crate. It very much does because you don't need 95% of the random stuff in the crates. Even for something like rand, you need an xorshift and that's roughly it. 25 lines of code, sorted. You can even write it as a copypaste "dependency" without much fuss in practically any language. That, versus importing a whole rand library with lots of different algorithms, deps on crypto, tests, OS random-based seeding, customisability, etc.
>you just need more official crates
I guess that's one solution but it would probably just be a better idea to split std in two SLAs, one is guaranteed for core stuff i.e. the status quo, one is YMMV.
Sorry, that's a strawman. Of course you cannot have a better version without changing things. You definitely can have a better version without changing public API.
And people upgrade their toolchain not because they want a different API. They mostly want bugs fixed, support, and sometimes features. Breaking the API has a huge cost and minor benefit.
> It very much does because you don't need 95% of the random stuff in the crates.
But why does it matter if all that stuff comes in std or in an different crate? As I said security doesn't play a role here. You can't even avoid compile-time cost because the std can only come precompiled because it only changes with the toolchain, which is another downside we want to avoid.
> I guess that's one solution but it would probably just be a better idea to split std in two SLAs, one is guaranteed for core stuff i.e. the status quo, one is YMMV.
And again, how is that different from what I say, other than calling "official crates" as "std"?
No it's not. It's exactly what I want, at least.
> When you're upgrading software, you presumably want a better version.
Sure...
> You can't have something better without changing it. It's a logical contradiction.
No, that makes no sense. When I upgrade the rust compiler, I might want it to compile programs faster. I might want its borrow checker to be smarter so that it accepts more valid programs than it did before. I might want to have some new language features (like if-let chaining or GATs).
What I absolutely do not want is to have to change the code in my programs so that it can be successfully compiled by the new version of the compiler.
Yes, certainly there are some times in the lifecycle of a piece of software that there's an improvement that requires a breaking change, but you believe is important and necessary, so you bite the bullet and do it. But you burn user goodwill every time you do that (maybe not your goodwill, but most people are not like you in this regard), and create work for people that they would probably prefer not to do. You also create fragmentation, because people aren't going to upgrade their new stuff to the new version all at the same time, and some people may never upgrade. All of this has costs, and deciding never to make breaking changes (or at least keep them to the absolute bare minimum) is a reasonable choice in the face of those costs.
Maybe it's not the choice you personally would have made, but it doesn't mean it's a mistake. They just value a different set of things than you do, in a completely reasonable way.
I don't want my language creating work for me. "Batteries included" is a feature of higher level languages. Rust is going to live for a very long time, probably beyond all of our lifetimes, and it needs to endure fads without picking up baggage and liabilities.
Rust could have a mandate where certain crates are "blessed" as recommendations. This could come with additional review, oversight, support, documentation, etc.
The Cargo.toml spec should have the ability to limit direct and transitive dependency count and depth. (As well as other things, like "nopanic" annotations/guarantees.)
The Crates.io repo should grow namespaces so we don't typo squat popular packages. It's much harder to miss organization names changing than package names changing.
Another big reason to put something in std is providing types for cross-crate compatibility. If I want to pass a String from one crate to another, I’m glad that string is defined in std so there’s an obvious type we can both use in our APIs.
C - for example - does not have this luxury. Everyone makes their own string type, and C APIs all need to translate strings at the api boundary. It’s super annoying.
It would be nice if we had a standard way in rust to declare a type as serialisable. Right now lots of crates have a serde feature flag to do this with serde. But (a) they need to put this behind a feature flag, since it adds a dependency on serde. And (b) this doesn’t work with other serialisation libraries.
The other big one is futures. There’s still no futures executor in std. Async crates have to decide if they want to tie themselves to a single executor (like Tokio) or be compatible. There is no async stream api in std. No async file api. And so on. It’s a compatibility nightmare.
We need useful traits to abstract over async runtimes. But there are a lot of design points for runtimes so this can't ever go into std. There is embassy, for embedded systems. There is monio and glommio built around io-uring. Then there is smol intended to be simple and lightweight. And then there is the kitchensink of tokio.
Clearly embassy is the one we want in the standard library. /s (It is the only one I personally would have a use for. But no, I don't think any of them belong in std. Traits to abstract over them? Yes, absolutely.)
But even your other example of strings: there are many design points for strings too, that might be better fits for specific use cases: string builder (with a capacity, what String in rust is), copy on write, small string optimisation (like compact_str), even interned strings. So your example of a vocabulary type is somewhat flawed, a better example would be Option or Result. Even anyhow and thiserror build on top of those vocabulary types.
Batteries included ia the only sane way to do programming languages.
We also have the classic example of PHP with numerous not safe stdlib ways to use mysql.
To me the answer is still to vendor your dependencies and don't be on the bleeding edge of updates unless you're willing to invest the time into validating them.
I think it goes without saying that emulating PHP is rarely a good decision.
No, I prefer what rust is doing. It suits a system programming language. Which is what Rust is.
Not sure what the issue with std::format would be here, you would have to elaborate. Obviously you need to specify a minimum version to have support for it at all.
Not every application requires internationalisation, especially server code or internal company tools.
I can use most of the clunky Python, Java, .NET and if it must be, Go, standard libraries, than hunting down for dependencies with platform tier support and such.
Just to quote a possible scenario among others.
Guava for whatever cool reason, and so on.
And tons of parts of the standard library (and language) being cordoned off as "legacy, don't use for new development". Of course figuring out what you shouldn't use in C++ can be hard too. It isn't well documented (or universally agreed upon), and it takes having it as a full time job to be able to keep up with these days.
No, I much prefer the way Rust is doing it.
Sure, it would be great if the volunteers that contribute to C++ compilers, would improve regex instead of adding the gazillion of features that each ISO C++ standard requires, mostly on their free time, because devs can't be bother to pay for compilers.
Additionally the companies that actually sponsor those compilers also have bigger priorities than improving regex implementation.
Finally if you want to stick regex into a micro-benchmarks context, there are plenty of options out there, as you point out.
The Rust way, like you can have any async runtime, as long as it is Tokio?
As for async in Rust, I wrote in another comment that yes that is an issue. What we need is std to define traits that all the different runtimes can implement. Because there are absolutely reasons to use alternative runtimes, depending on what you do. I mostly use embassy (embedded microcontroller development) for example. And if you want thread-per-core with io-uring you want glommio or monio. Smol is simple and compact.
I could also see uses for async in desktop GUI or gamedev (but to my knowledge there isn't any runtime suitable for those domains yet).