Hacker News new | ask | show | jobs
by pcx 2961 days ago
The wonderful thing about Rust is that despite being fairly new and rare to get paid for working on it, it is still enticing( to most programmers I've met). The consistent effort to improve it is really paying off. I hope it gets to a place where it's `batteries included` like Python. There are some glaring holes in the stdlib I would like to see fixed sometime soon.
2 comments

The argument for putting things in third-party "blessed" crates rather than the standard library is that it allows them not to have to follow the versioning guarantees of Rust itself. Given that the core team has stated that they don't plan to have a Rust 2.0, this means that there wouldn't _ever_ be any API-breaking changes for things added to the standard library; by having things like `regex` and `rand` be external crates, versions bumps can happen independently happen, which means (among other things) that major version bumps are possible.
That's certainly an advantage. But for devs like me, we are used to prog langs providing a set of APIs in the stdlibs, that are officially blessed to be maintained. They might not be the best designed, but they are guaranteed to work for a long long time. This kind of trust is very hard to build for 3rd part libs. It's a trade-off to make, and rust for now has decided to keep stdlib lean and quick to iterate over. But I hope at some point, Rust devs would consider including more APIs.
I think that the rust-lang-nursery Github organization[1] is designed to solve part of the trust issue. A lot of the "batteries" crates are in there; `rand`, `futures`, `error-chain`, `lazy-static`, `glob`, `bitflags`, and `log` catch my eye after looking through. In the long run, I don't think that having things like the blessed HTTP library being third-party will be that much of a detriment; at least when I was writing Python, almost everyone I knew used the `requests` library, and nobody worried about it not being part of the standard library.
What sort of maintenance is actually needed though?

Rust promises that existing versions of crates will build and run in the future, assuming the crate is well-behaved and doesn't do anything illegal with unsafe code. That's part of Rust's general stability guarantee.

Maybe "blessed to be maintained" means crates get ongoing critical security fixes? Thanks to Rust, for most crates that's a very low-probability concern. (Obvious exceptions for features like HTTP and TLS that contain their own security decisions.)

Maybe you mean that all kinds of bugs will continue to be fixed and the quality of the crate will keep increasing? I don't think any languages really give you that; they all have standard library features that are effectively end-of-life. A lot of application developers don't even WANT such fixes since there's always a risk of breaking previously-working applications.

So I think it would make sense for the Rust community to commit to a subset of crates for ongoing maintenance, but for probably the majority of crates you could just keep using the exact same version for the next five years with no worries.

But the versioning guarantees are _exactly_ why having them in the stdlib would be good for me as a user; it means I'd be able to have code that keeps working, but have new improvements available.

It's totally fine to decide to make the trade off, but it's just frustrating to not have the downside acknowledged.

As long as you don't use "*" as the version for any of the crates in your project's Cargo.toml it should stay at one particular version and therefore follow SemVer guarantees. If you are REALLY paranoid, you can even have the crate be a particular git commit or you could download your preferred version and then refer to it using the "path" key in the Cargo.toml.

Adopting crates into the stdlib would make stdlib and the crate depend on each other, which is not a nice scenario. Also having certain "core"-functionality be dependent on a 6wk release cycle is not great for stuff that is not good once it's set in stone (aka released on stable).

Real core functionality, bare bones stuff like parsing of Rust itself, I/O and TCP/UDP connectivity, which provide an unlikely to ever change framework for crates to build upon rightly has its place in std; e.g. convenience methods for downloading (like what reqwest provides) OTOH have to stay flexible to adapt to the real world.

Yeah, but 20 years down the road, you're either going to be writing the same code or sifting through piles of crufty bad stuff.
Do you know where I can find the comment about no plan for Rust 2.0? I tried googling it but I couldn't find it. Reason why I'd like to find it to have some guarantee that this is true.

Cause it sounds like a strong commitment here.

https://github.com/rust-lang/rfcs/blob/master/text/2052-epoc...

Though we are calling them “editions” instead of “epochs” now.

Which glaring holes are there in your point of view? Rust devs are on HN a lot, so maybe they will see your comment.

All that said, Rust definitely errs on the side of preferring to put things in 3rd party crates instead of stdlib, even for things that are very common to put in std for other languages (e.g. random number generation).

A couple of commong APIs I can think off the top of my head:

- HTTP client

- CSV parser/generator

I know Hyper and rust-csv are popular. But having an stdlib that's much more feature complete would be great.

These are really interesting examples. In Python, the HTTP client in the standard lib is pretty crappy compared to requests, which is the defacto standard. Likewise, the CSV library in the Python stdlib is not very good, but can't improve much for compatibility reasons.

Developers have different needs. Some value stability, some value bleeding edge features. Trying to put libraries in the standard library and freezing their interface is really tricky to balance.

Though the ecosystem is still young, the long term story for "batteries included" in Rust is going to be a rich ecosystem in Cargo, not a rich standard library.

Yeah, I can totally appreciate the perspective, but without a significant set of policy changes, I don't see either of these happening. We'll see!
An interesting compromise might be a crate maintained by the core team (std-ext?) that simply re-exports crates under generic names that the community has blessed as being, for better or worse, the default in the Rust ecosystem.

So someone who wants batteries included could add only std-ext as a dependency and get hyper as std_ext::http, regex as std_ext::regex, rust-csv as std_ext::csv and such to avoid needing awareness of the entire ecosystem when first starting out. Seasoned Rust developers would probably continue pulling in dependencies directly, but it might improve the experience for new Rust developers to have everything a 'use' statement away without needing to go look for it.

Several of these kinds of initiatives, in various forms, have been tried. They never really caught on. (The biggest was stdx)
Maybe after the community chooses a few “winners” the Rust devs could promote them as being “suggested” packages?

Also, some suggested metapackages/bundles wouldn’t hurt for newbies, like a set of crates for developing command line tools, for example.

Something like this: https://marketplace.visualstudio.com/

Why choose a winner?

What if a 'winner' today is a loser in a year? What if we come up with a new approach to solving a problem that requires a breaking change, or a new crate?

Would someone be inclined to try to improve the state of HTTP given a good enough version in std? Would we be ok with discouraging that sort of competitive approach?

To be honest, all I see are downsides to having a huge std lib. The benefit seems to be that there isn't an obvious, de facto choice for what crates to use. But I think that's a problem better solved by crates.io.

I tend to agree, but I also think that there's a little bit of nuance here. For one thing, I have definitely enjoyed using a large standard library...when I didn't have access to cargo or tools of similar quality.

My impression is that many of those who are asking for Rust's stdlib to grow are also/actually asking "please make it really easy for me to use these APIs that I care about," to which I would respond "it's OK, code can be easy to reuse even if it's not in the stdlib," "try cargo," and "crates.io needs to continue improving on discoverability."

EDIT: also, hi!

Perhaps a better idea might be to include the most popular client in some form of official tutorial / guide / documentation, or as part of some extended documentation separate to the language doc?

That way libraries can coexist, but new developers have a single doc location to go to to find really common usages.

You misread what I said. Click my link and tell me what you see. Hint: there’s a reason those things are called “suggested extensions”.
It depends, the team suggested this kind of thing two years ago, and the community pretty resoundingly rejected the idea.
And the community does (organically) pick defacto winners. Like chrono, serde and rust csv (well, I'm not sure about rust csv).

It might be nice to have autogenerated docs about the most used soltuions, but I guess the rust cook book sort of fills that niche.

Needing to use two separate third-party crates (lazy_static and maplit) to have a global constant-initialized hash table is the one that surprised me recently.
maplit is purely a convenience macro, so you shouldn't have actually needed it. Once `const fn` is a thing, lazy_static should be used a lot less too.

Incidentally you might like the phf crate, depending on your needs.

Sure, maplit's hashmap! is just a convenience macro, but then so is vec!. Hashtables are a pretty fundamental data type and they deserve to be easy to write constant initializers for, just like vectors.

'const fn' seems like a red herring -- I don't want to write const functions, because I don't want to write code to initialize data structures at all. I want to write representations of data structures...

Sure, I think it's a useful crate. But it's certainly not "Need[ed] ... to have a global constant-initialized hash table" that's all.

const fn isn't a red herring; you won't be writing const fns, you'll be using them to do the actual initialization. If maplit would use them internally, for example.