4 ms·
I think it's worth expanding this a little more. The problem with standard libraries in general is that it's not really possible to adjust the API later if it
by jcranmer 5y ago
I think it's worth expanding this a little more.
The problem with standard libraries in general is that it's not really possible to adjust the API later if it turns out to not be well-designed. And it turns out that "oops, we got the API wrong" afflicts, well, literally every standard library I've ever worked with (note: this even does include Rust, as young as it is). Examples include:
* C/C++: wide strings, locale support, std::unordered_map (it prevents you from using a good hashtable implementation)
* Python: mail parsing libraries, http requests [and this even after having an exceptionally painful major version that allowed them to break compatibility!]
* Java: java.util.Date, java.util.Vector [as opposed to java.util.ArrayList]
* Rust: raw FD support, std::io::Read interactions with partially-uninitialized buffers
There is something you notice when you look at standard library misfeatures, which is there are different kinds of issues. The simplest issue is something like locale support in C/C++: you can just simply not use it, and everything will be fine. On the other hand--and this afflicts Python the most of any language I'm familiar with--having a broken implementation in stdlib can dissuade the community from making a good version of what you want (this is what happens with the mail format stuff). The worst possible kind, though, is when you make a core type with an utterly broken API--and this is what java.util.Date qualifies as.
Having "batteries included" makes it more likely you get more severe kinds of API failures in the standard library. Already, the Rust ecosystem has had evolution in core package libraries that allowed it to absorb poor API design--consider the shift from error-chain to thiserror/anyhow, or the futures 0.1->0.3 change.
- tptacek 5y agoBut the comparison here is between the organization of the Rust library ecosystem and Go's; the Go standard library has, I think, more (and more ambitious) strongly-accepted abstractions --- it's uncontroversial to observe that Rust programs pull in more deps than Go packages pull in modules. But the phenomenon you refer to in your last 2 paragraphs hasn't really occurred with Go; it's hard to point to something in the stdlib that Go just straight-up botched, to the detriment of all other packages. Go programs pull in deps, of course, but it's unusual bordering on unidiomatic to pull in a dep that changes the general programming environment (idiomatic Go sticks with the data structures and, notably, concurrency primitives in the stdlib, net/http remains the de facto standard HTTP interface, things tend to build on top of database/sql instead of replacing it, for the most part the stuff in encoding/* is canon, &c). That's not a plus for Go, but it's a contrast with Rust, where crates routinely redefine or refine the underlying Rust programming environment (best example is anyhow, of course). So Go programs rely heavily on the stdlib and its abstractions. And my perception is that by and large Go devs are pretty happy with it? Maybe DNS would qualify as such a botch; maybe the interaction between sockets and contexts as well. And we'll see what chaos erupts from 1.18 generics. (None of this should be construed as in any way a dig on Rust, which I find frustrating but also enjoyable to work in, and whose expressiveness and utility advantages over Go I respect).
- mustache_kimono 5y agoI think both you and the parent are correct. I don't think there is one answer to this question for both languages. I do think the right answer for Rust is to "wait and see." Let libraries organically develop, and wait to pull them in at the right time, to, for lack of a better word, die.