I've always wanted to learn Rust but have found it devilishly complex compared to the likes of Go, but I appreciate there's not much that can be done about its complexity this far down the road.
My other big beef with Rust is its lack of a comprehensive stdlib, unlike Go. Having to pull in tons of external crates of varying quality and with varying degrees of dependency chains is not particularly pleasant.
Having a decent, well maintained, stdlib that contains "the basics" that one would expect in any 21st century programming language is sorely missing from Rust, and from my personal perspective is something that would draw me back to Rust for another go at learning it.
Actually, the "batteries included" school of library design was a 20th century idea; the trend in the 21st century in all other ecosystems very much goes in the opposite direction: fewer features in the stdlib to allow faster iteration, and strong package managers that make it seemless to mix and match packages.
Go just dodges that trend and does the 20th century thing, as it does for many other design decisions. Just as it has common data structures as hardcoded language features, instead of the ability to build them as abstractions.
To be clear: One can take the position that the trends go in the wrong direction and Go is right to reverse them -- that's a matter of opinion. I just don't think it's fair to argue Go is the language that does the more modern thing.
The main reason I've wrote so much python in the last 10 years is due to it's stdlib being comprehensive enough to do 95% of the tasks I need without adding any dependency.
This despite the fact that I never was super-fond of python's syntax and ideology, although I just learned to accept it. I was writing a ton of perl before that, and with python I could do more with less "CPAN". I would have _never_ made the switch without.
A good stdlib ensures decent performance, stability and overall code quality to your project. Without that, you need tons of dependencies along with version pinning (as developers nowdays understand semver even less than 20 years ago) and duplication due to your dependencies picking different packages as their own base due to the lacking stdlib.
I hate the sort of ecosystem which is built around this pattern. See npm for one extreme, although I see cargo not too far away in the horizon.
Go has a much easier time of it for including some batteries, because it’s a simpler language.
Take HTTP, for example: the decision of the data type to use for storing headers is easy, because there are really only four possibilities, two binary decisions to make: ① do you use string or []byte; and ② do you use map[T][]T, or join values with commas and special-case that pesky Set-Cookie header somewhere and use map[T]T? And so map[string][]string was fairly obviously the best choice from the start, and I think still is—in Go.
Meanwhile, in Rust, are you going to go Vec<(Vec<u8>, Vec<u8>)>, can you get away with HashMap<String, Vec<String>>, do you store a central buffer and work with slices for fewer allocations, or do you say “no, that’s stupid, headers aren’t strings, they’re just serialised as strings” and go all fancy typey in one of a variety of ways, some the most efficient of which depended on GATs which are only recently stable?
Go could have net/http from the start. I don’t know if there’s something better now (I don’t use Go), but I expect that the better would still be very similar in API.
If Rust had had a std::net::http at 1.0, it would certainly have been deprecated by now. Probably even over four years ago.
(Disclosure: I wrote the first de facto standard HTTP library in Rust, rust-http, back in 2013. Then in 2014, realising its design was a dead end, I went to write a new one from scratch, Teepee, but never finished it because of decision paralysis, others took up much of my work and finished the concept off in Hyper, and I’m glad I got out of the critical path and I’m glad they took it up.)
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.
As a counterpoint, we can look at the npm ecosystem for the disadvantages of a "just use small packages from the ecosystem" approach. Look how many dependencies a typical npm package has, how many different authors there are, and what happens when one of them goes off the deep end?
"All other ecosystems"? Not sure about that - besides Python, which another commenter mentioned, there is also PHP, which is pretty much 21st century and also "batteries included". I totally get it that small teams developing a language (Node, Rust) need to focus their efforts, but please don't try to spin this limitation into a "new way of doing things". What I hate most about this "package manager"-based way is not only having to choose between a multitude of options, each with its own pros and cons, for basic functionality, but also the burden of keeping everything safe and up to date (while making sure it's still working), and the constant threat of having to switch to another package/crate if the one you have decided to use is abandoned.
I don’t think this is right? C, C++, and JavaScript certainly had very spartan standard libraries. Python and Java certainly emerged in the mid 90s (within striking distance of the 21st century), but I’m not sure the state of their standard libraries at the time. I suspect other languages also had smaller libraries but can’t prove it.
With respect to mainstream 21st century programming languages, I’m only familiar with Go, Rust, and C#, of which C# and Go certainly have pretty comprehensive standard libraries. Other mainstream 21st century languages I can think of run atop either JVM or .Net and I believe they have access to the Java or C# standard libraries, respectively but I’m not sure if it would be fair to say they inherit those standard libraries or not.
The go stdlib has the compatibility promise. Managing ANY external dependencies is exactly what causes breaking changes to be introduced over time. Think of it as a long term support plan on all your packages.
python had a HUGE stdlib, which was its downfall. Go's stdlib is quite small in comparison. I'd say the kitchen-sink batteries included is the 20th centry idea, Not the approach go has taken.
> My other big beef with Rust is its lack of a comprehensive stdlib, unlike Go.
I think many of us are feeling these days that the rust standard library might already be too large and it's better to be very conservative adding stuff there or only after an extended period of time of independent vetting. I have yet to not experience that standard libraries turn into very stale and outdated things relatively quickly that carries an enormous maintenance burden.
> only after an extended period of time of independent vetting
Let's face it, what will your average dev do in the absence of something being in stdlib ?
They will (semi)randomly pick some third-party crate which in all likelihood is totally unvetted.
The crate that they selected could equally turn stale and outdated quickly if its a small one-man-band Github party (a not unfamiliar story these days).
Hence, having a standardised baseline available in stdlib is no bad thing IMHO. It brings "sane defaults" and forces anyone wanting to do different to make a thought-out decision, not just grab whatever Crate "looks good" so they can get on with coding.
I wish there was an `Either` type in std. I realize that there used to be one and we have `Result` now. However, now that we have `impl Trait` it's worth revisiting, I believe. If we don't we'll have the one from `itertools`, the one from `futures` etc.
In most GCed languages it wouldn't matter so much because you'd return a boxed `Iterator` or `Future` or what have you. But in Rust you generally want to avoid the allocation.
> I have yet to not experience that standard libraries turn into very stale and outdated things relatively quickly that carries an enormous maintenance burden
Maybe. I think .NET's core libs are excellent. So are Go's. I'm sure it's a maintenance burden, but man... It's so nice to be able to build a project with maybe 1-2 dependencies instead of 100s (as in my typical Node and Ruby projects, if you count transitive dependencies). It's hard to overstate how much of a strength I think a good stdlib is.
Two thoughts, as a very recent convert from expert-level Go to all-around-the-place-level Rust:
(For some context, interested in Rust since 2009, similar as with Go, but not involved at all, whereas contributor to Go pre-1.0.)
First thing, is that I was frustrated with lack of simplicity vs. Go for a long time as well. Finally, recently I got it: AFAIU it's a case of different priorities. In the triangle of simplicity-safety-performance, Go loves all of them, but in case of conflict, chooses simplicity (thus, most notably/infamously, we get GC and nil). Rust also loves all of them, but in case of conflict chooses safety AND performance. What's freaking crazy IMO is the "AND" here, which I see as a huge thing. And it instantly also explains to me a tension in the Rust community between safety and performance camps, infamously most visible around usage of the 'unsafe' keyword. Yet in a barely-managed marriage between safety and performance, simplicity is the heartily beloved friend, who still just gets silently shown out of the room when a serious row starts between the couple, until they're ready to open the door back, and with patient smiles listen to some friendly suggestions.
Secondly, I bumped my head into a wall a few times until recently I tried the O'Reilly "Programming in Rust (2nd ed.)" on some recommendation from Reddit. The "2nd ed." part is important here, because it covers a few relatively recent important additions to Rust, that I found I was teeth-gnashing frustrated without before (coming from Go), namely: anyhow, thiserror, and (to a lesser extent) async. Edit: Two bonus personal recommendations for the book: (1) I got a job in Rust after going through it and then testing my abilities on some personal project, where I finally felt I'm managing to do regular non-fancy-shmancy (i.e. web, sqlite, GUI via iced, but no macros and avoiding lifetimes whenever possible - if curious, the project is: https://github.com/akavel/backerrs) coding, and can work around lifetime issues (somewhat faster or slower but can, and often just falling back to .clone()/Rc); though in all honesty, they kind of didn't really test my Rust skills, to my huge surprise, and trusted my smarts shown in Go & C++ experience + passion for the project; (2) I'm carrying the book with me to workplace every day and definitely checking things in it from time to time.
I adhere very much to your first point. This made me think that from the opposite point of view the triangle becomes complex-unsafe-inefficient. And of those three "qualities" a program can have, complexity is the only one for which i don't have a tool or a methodology.
Bryan Cantrill has an interesting talk that discusses various languages in terms of their values that you might finding interesting: https://www.youtube.com/watch?v=2wZ1pCpJUIM
I learned Rust only to abandon it afterwards. It's not worth the effort, especially if you already know Ada and various memory-managed languages like CommonLisp and Go. Although I'm sure sure these exist, I've never written a program that would benefit from not having a garbage collector.
If your program benefits from having a garbage collector (GC) — which I guess is a lot of programs — then by all means go for a GC-ed language. It's one less thing to worry about.
However, the garbage collection process itself sometimes introduce a noticeable pause in execution, which can be unacceptable in certain applications. Especially in critical real-time applications.
(That GC pause won't be a problem if your program mostly just waits for user input the majority of the time).
For an extreme example, you don't want your car's airbag controller to be paused for garbage collecting during a crash.
The ONLY lib missing from stdlib.
Is the time library.
Maybe unified interface to work with DB.
Cryptographic functions while useful age poorly, and require constant change.
Serde while extremely useful won't fit every usecase. Sometimes you want something smaller or faster.
Http(s) clients also tend to age poorly. Python also had http client/server in std lib that aged like warm milk.
For a thing to be in std, it needs to be imo something you don't want implented in several different ways. Something that is essentially solved and will change very little over time.
Certainly not DB handling. Databases have vastly different features sets and tightly coupled to I/O abstractions, so it's not uncommon to call database specific functions from a driver. Maybe a very stable first-party crate, but not stdlib.
Unicode handling. There are two big projects on that front in the crate space, but this is, for me at least, the biggest gap in the std lib (but then I'm writing a text processing/formatting system so it matters a lot to me).
> Having a decent, well maintained, stdlib that contains "the basics" that one would expect in any 21st century programming language is sorely missing from Rust, and from my personal perspective is something that would draw me back to Rust for another go at learning it.
What would you like to see in that? Genuinely curious, I've considered putting something together that's just a meta-crate that pulls in some others.
I would suggest that an opinionated website documenting a curation of crate choices might be better than a crate (which would be a pain technically). I’ve been considering making one if you’d be interested in collaborating.
I think serde should be part of the stdlib. A http server and client library is also really a must-have today. Maybe some abstraction for SQL database drivers.
Some other candidates include: logging, anync runtime (Tokyo), random generator, regex
> What would you like to see in that? Genuinely curious
I see someone else has got there before me and my answer would not be dissimilar.
Stuff to be able to talk to web services (because let's face it, any modern software will be doing that) is the obvious low hanging fruit, i.e. HTTP, JSON, Crypto etc.
Beyond that (if its not there already) basic tools to enable out-of-the-box CLI writing (e.g. flags etc.)
A Collections grouping of common data structures and macros would be useful.
There are so many different idiomatic ways to instantiate a type in rust that a crate with a common calling convention for most data structures would be very useful.
good json parsing is important these days.
crypto is a must too.
golang's crypto is really good (ssh, tls, sha, md5..)
Right now in rust we rely on rust bindings to c libs.
Personally I would like a standard http library that has async and non async methods. One of the things that initially turned me away from Rust was the complexity of finding a library to use for simple http requests. I know this is also a strength, but it makes the intro days incredibly challenging
I found stdx to be a useful set of sign-posts. But it's not been updated in three years. E.g. it suggests `error-chain` instead of `anyhow` and `thiserror`.
The basics of rust really are not that bad. It gets funky once you start diving deeply into types. If you are just hitting an api and getting json out followed by working with storage etc in AWS, the situation is pretty straightforward.
It’s curious to me the abscence of c++ interop as a focus. I understand there may be more important problems within the Rust community and it’s not yet ready to take center stage, but there’s soooo much to be gained from being able to piecemeal rewrite c++ code into rust in a low-friction manner or to make Rust as easy an option to reach for as C++ to write new code for an existing c++ codebase (eg a goal could be that all new code in Chrome/Firefox should be being written in Rust). The cxx crate is neat and a good start but it’s still too immature and ultimately you are limited to anything that can be hidden behind thin interfaces.
Doesn't C++ not have a stable ABI? Doesn't that kind of make it difficult to interop with it? The ABI is an implementation defined thing by the compiler, right?
You don’t need a stable ABI per se if you’re working with source-level interop. Also, while it doesn’t have one in theory, it does in practice on each platform if I recall correctly.
Isn’t this as much a problem with C++ as it is with Rust? Both tend to need to drop to C for FFI. So you’d need a C++ stable ABI as well as one for Rust.
Look at the cxx crate. I don’t care that there’s a C FFI in the middle. Just that it needs to look like magic. In other words, most or all c++ types, including templates, without any real complexity on the part of the user. Conversely Rust types are accessible from c++ without complexity. I think the latter part is mostly true although some patterns need some TLC. The former is still extremely immature.
I have Steves book on paperback. Haven't had time to read it all and given the rate things are moving now I am afraid that some of it could be outdated.
As a developer, what I really want to hear is that Rust 2022 will be basically Rust 2021 with some bug fixes and performance improvements.
Isn't that the goal of the Rust editions¹ that are released roughly once every three years? Rust had a 2015, 2018, and now a 2021 edition, so if that pattern is followed you can probably expect a new edition in 2024.
Stable Rust 2022 will include all of Stable Rust 2021, just with some more bug fixes, performance improvements and features. If anything from Rust 2021 becomes outdated then that happens because new features or syntax allow a much better way to do the same thing, not because the old thing no longer works.
That happens to most actively used languages. C# has seen some major evolutions in recent years and is 22 years old now, Java is 26 years old and has some major changes compared to what it was 7 years ago, and you can no longer discuss C++ (37 years old) without mentioning C++11 along the way.
Java today looks nothing like Java 5 however it's largely backwards compatible. I hope that Rust isn't afraid of making larger changes to stay relevant. Java 8 is what brought a lot of people back after looking at more functional jvm languages such as Scala
Is there any indication that Rust is not the new C++ in terms of language and ecosystem complexity? I just can't bring myself to learn languages like C++ and C# because they are changing at such rapid and complex paces, versus other languages like F#, Elixir, Clojure that are essentially feature complete. I'd like to learn Rust, but it just seems like a huge time investment.
I think Rust has already failed in its mission to become a replacement for the existing entrenched systems programming languages. The reason is simple - it does not offer safety without spending an inordinate amount of up front complexity. In order to replace C/C++ a language must first and foremost be simple to learn and get started with. Even though Go is 90% a rehash of other languages, it's success comes down to embracing the foibles of programmers and our need for tools that can be ramped up simply and quickly.
Rust is perhaps the language that people SHOULD be using, but likely won't. Until someone can offer something as simple and easy to learn as C and also can automatically do the things Rust provides without asking the programmer to give double in mental effort, I don't think we will replace C in a major way.
As a full time c++ developer that just started a rust side project (with rocket.rs) to learn the language, I fully disagree. Coding is actually fun again, and it is becoming increasing harder to code c++ at my job. I constantly get reminded that gb free languages can do better. Damn rust, you ruined c++ for me :(
Edit: Ok maybe a bit dramatic, but I really hoped we would get working modules with c++17 and here we are still years away...
Oh please. Preaching about safety in a globally inter-connected world devoid of privacy.
Newsflash, it's not a language's job to make software safe. It's job is to make programmer's job as simple as possible: ie. writing new software. If your language fails to do that, people will not use it, plain and simple.
How else could you explain the popularity of languages such as Python and Go?
HTTPS took off when Let’s Encrypt (and to some degree Caddy) made it easy to be secure. Rust is more like, I dunno, openssl: easier than doing everything yourself by hand, but not even remotely easy.
IMO rust is much easier to learn than both C and C++ for anyone who is not already familiar with those languages. I suspect it will pick up adoption merely because people don’t want to deal with C or C++.
The learning curve of Rust is extremely front loaded compared to C or C++, even though C++ might be more complex overall than Rust, that is the issue. C is simple, and I don't think anyone who has read K&R would honestly say it's harder to learn than Rust.
It's not as simple as Python though, most people who are writing C++ are doing so because they already know it (e.g. from school or past work) or they have no option (building on an existing C++ codebase). Being in the position of "I need to learn a first systems language, should I pick C++ or Rust" is not very common, IMO.
You casually mention C++ along with C but you can't really put them in the same bucket. C++ is terribly, mindbogglingly, utterly, complex, its main selling points being zero-cost abstractions and compatibility with C. Perhaps we have different experiences but I don't see Rust as complex to learn with respect to C++. In C++, coming from C, the syntax is deceptively similar but you have to track in your head where the memory is, and seemingly simple operators like "=" or "()" can mean a whole lot of different stuff. Not to mention the craziness of the more advanced features.
Rust is first a system programming language with zero-cost abstractions with the least possible pain, then it is a safe language, way safer than C++.
In any case I am following the community and I have a hard time finding people saying C++ is nice for them. There are few people who have been coding C++ for 20+ years and "love" it but they are far and between. Almost nobody tried both Rust and C++ and continued using C++ for new projects.
So I predict Rust won't replace C, they have different use cases, but it will make a dent in C++.
Rust isn't nearly as hard as it seems. Most people who think it is hard went up against it once or twice for a week or so and gave up. What they didn't realize is unlike some other hard languages (ie. C++) once you are over the initial learning curve, it is pretty smooth sailing, and it codes quite fast - almost like a higher level language. It has a very nice payback for the effort I think.
I recommend the 2nd edition Oreilly book + writing lots of code for about a month or possibly two. After that, I think many will agree it isn't nearly as hard to write as they initially thought it would be.
The biggest bonus: Writing Rust is very fun. I can't pinpoint why this is, but I totally understand why it keeps getting voted favorite language. A total joy to write.
There is a way in which Rust reduces mental effort: a compiled program is more likely to work in the way you expect. It cuts out a swathe of post-compile testing and prodding, or at least, it does in my experience. I can't speak for the other people who have voted it "most loved language" six years running, but that's one of the reason why I love it.
It was the phenomenal Rustlings course that got me over the learning hump.
I continue to be surprised by this despite logging some good number of Rust hours. Cargo run and it just works as expected even with complicated data sharing code etc.
Of course most of the work gets done by the compiler safe guarding and guiding during development. People make noise about lifetimes etc but once you are ready to pay the penalty of Arc (and in most cases if you are using lifetimes you are already on the verge of using Arc). Same with using cloning as needed. End of the day, these incur a predictable and acceptable performance penalty than many other languages do while providing good safety.
Rust was created to replace C++ in Firefox. Today, lots of Rust code in Firefox, replacing C++, and no Go code in Firefox. Therefore, for this goal, Go failed and Rust already succeeded.
I think it's too early to say it's failed to replace the existing systems programming languages and its trajectory looks positive. For example, in the 2019 Stack Overflow developer survey[1] only 3% of professional developers reported using Rust. A year later[2] it was 4.8% and a year after that[3] it was 6.4%. So in two years professional developer use doubled, by that metric. For reference, in the SO surveys C++ and C use was about 20% and 16%, respectively and, if anything, slowly declining (as a percentage of respondents, of course).
If I where to write a small command line tool utility that needs to be fast, safe and lean I would definitely write it in Rust. It's got the tooling C++ don't (cargo), the ability to statically compile a minimal binary that small and fast (because we don't pay for abstraction like C++) and allow me to write reasonably clean code using functional paradigm. It is reasonably easy to interface with C code (did that recently to access libelf and fuse). Unit testing and documentation is embedded with the language.
So, I agree with you, it will probably not become a replacement, but it succeeded in providing a credible alternative that has been used by many already.
It’s hard to imagine what an officially supported GUI framework would be. And I’m focusing on the official.
There are toolkits out there and game engines picking up steam.
My guess is that for a GUI in Rust to truly shine it will have the hard task of working both in native OSes and WASM on the Web. People are working on these frameworks, but most are pretty limited at the moment depending on needs. (If folks believe it’s better than that, please share, it’s only a space I dabble in sometimes)
That's not a job for stdlib. Language needs to be flexible, with a small core.
Rust is already hard to learn, even the language itself is packed with features.
Add the stdlib and you have plenty of confused faces who after some time fail to see the point.
Does anyone have any idea as to how many C++ shops have adopted Rust or how many C++ projects have been converted to Rust? That's what I want to know in 2022.
I think at this point, Rust will not really replace C++ just like how C++ never replaced C.
Given the learning curve of Rust and the lack of tools it's still a bit of a gamble to choose Rust over C or C++ IMHO. Why take that risk when the benefits aren't entirely clear cut.
Inventing programming languages is super-fun, but aren't we almost post programming language?
In 30 years, do we really expect to be programming in some machine-human intermediate language? I hope that we'll be having an open ended conversation with the machines to iterate our intent, with working software at most stages along the way.
> In 30 years, do we really expect to be programming in some machine-human intermediate language? I hope that we'll be having an open ended conversation with the machines to iterate our intent, with working software at most stages along the way.
This is actually entirely feasible, although perhaps not open-ended conversation. Instead it could be that you feed the machine training data which describes how to solve a particular task, and the output is a program that solves that task. So we would all end up being ML engineers.
Perhaps more modestly - how far are we from just being able to translate from one high level language to another, assuming the ability to refine the translation as opposed to a one-shot job that has to correctly interpret the intent?
I.e. will it matter what language anyone uses? Here, take this software renderer I wrote in Python, and translate it to C++. "Conversation" about choices and ambiguities ensues...
Maybe there is the possibility of a meta high level language capable of describing/encompassing all the others without exceeding human cognition capabilities. Instead of compiling to a common low level target like assembler, transpiling all the existing sources to a very high level one optimized for human understandability.
Great post by Nick offering a very interesting fresh perspective from someone who was an active member of the Rust core team in the past, then took a break for couple of years and now comes back working on Rust full time (at Microsoft). Great overview of outstanding issues and priorities as he sees them.
My other big beef with Rust is its lack of a comprehensive stdlib, unlike Go. Having to pull in tons of external crates of varying quality and with varying degrees of dependency chains is not particularly pleasant.
Having a decent, well maintained, stdlib that contains "the basics" that one would expect in any 21st century programming language is sorely missing from Rust, and from my personal perspective is something that would draw me back to Rust for another go at learning it.
Go just dodges that trend and does the 20th century thing, as it does for many other design decisions. Just as it has common data structures as hardcoded language features, instead of the ability to build them as abstractions.
To be clear: One can take the position that the trends go in the wrong direction and Go is right to reverse them -- that's a matter of opinion. I just don't think it's fair to argue Go is the language that does the more modern thing.
The main reason I've wrote so much python in the last 10 years is due to it's stdlib being comprehensive enough to do 95% of the tasks I need without adding any dependency.
This despite the fact that I never was super-fond of python's syntax and ideology, although I just learned to accept it. I was writing a ton of perl before that, and with python I could do more with less "CPAN". I would have _never_ made the switch without.
A good stdlib ensures decent performance, stability and overall code quality to your project. Without that, you need tons of dependencies along with version pinning (as developers nowdays understand semver even less than 20 years ago) and duplication due to your dependencies picking different packages as their own base due to the lacking stdlib.
I hate the sort of ecosystem which is built around this pattern. See npm for one extreme, although I see cargo not too far away in the horizon.
Take HTTP, for example: the decision of the data type to use for storing headers is easy, because there are really only four possibilities, two binary decisions to make: ① do you use string or []byte; and ② do you use map[T][]T, or join values with commas and special-case that pesky Set-Cookie header somewhere and use map[T]T? And so map[string][]string was fairly obviously the best choice from the start, and I think still is—in Go.
Meanwhile, in Rust, are you going to go Vec<(Vec<u8>, Vec<u8>)>, can you get away with HashMap<String, Vec<String>>, do you store a central buffer and work with slices for fewer allocations, or do you say “no, that’s stupid, headers aren’t strings, they’re just serialised as strings” and go all fancy typey in one of a variety of ways, some the most efficient of which depended on GATs which are only recently stable?
Go could have net/http from the start. I don’t know if there’s something better now (I don’t use Go), but I expect that the better would still be very similar in API.
If Rust had had a std::net::http at 1.0, it would certainly have been deprecated by now. Probably even over four years ago.
(Disclosure: I wrote the first de facto standard HTTP library in Rust, rust-http, back in 2013. Then in 2014, realising its design was a dead end, I went to write a new one from scratch, Teepee, but never finished it because of decision paralysis, others took up much of my work and finished the concept off in Hyper, and I’m glad I got out of the critical path and I’m glad they took it up.)
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.
With respect to mainstream 21st century programming languages, I’m only familiar with Go, Rust, and C#, of which C# and Go certainly have pretty comprehensive standard libraries. Other mainstream 21st century languages I can think of run atop either JVM or .Net and I believe they have access to the Java or C# standard libraries, respectively but I’m not sure if it would be fair to say they inherit those standard libraries or not.
The go stdlib has the compatibility promise. Managing ANY external dependencies is exactly what causes breaking changes to be introduced over time. Think of it as a long term support plan on all your packages.
python had a HUGE stdlib, which was its downfall. Go's stdlib is quite small in comparison. I'd say the kitchen-sink batteries included is the 20th centry idea, Not the approach go has taken.
I think many of us are feeling these days that the rust standard library might already be too large and it's better to be very conservative adding stuff there or only after an extended period of time of independent vetting. I have yet to not experience that standard libraries turn into very stale and outdated things relatively quickly that carries an enormous maintenance burden.
Let's face it, what will your average dev do in the absence of something being in stdlib ?
They will (semi)randomly pick some third-party crate which in all likelihood is totally unvetted.
The crate that they selected could equally turn stale and outdated quickly if its a small one-man-band Github party (a not unfamiliar story these days).
Hence, having a standardised baseline available in stdlib is no bad thing IMHO. It brings "sane defaults" and forces anyone wanting to do different to make a thought-out decision, not just grab whatever Crate "looks good" so they can get on with coding.
[1]: https://twitter.com/steveklabnik/status/1367854800193413126
In most GCed languages it wouldn't matter so much because you'd return a boxed `Iterator` or `Future` or what have you. But in Rust you generally want to avoid the allocation.
How could you ever possibly, gasp, write it yourself? Oh the horrors of computer science.
Seriously, many times I find myself needing only a fraction of some provided library.
Maybe. I think .NET's core libs are excellent. So are Go's. I'm sure it's a maintenance burden, but man... It's so nice to be able to build a project with maybe 1-2 dependencies instead of 100s (as in my typical Node and Ruby projects, if you count transitive dependencies). It's hard to overstate how much of a strength I think a good stdlib is.
(For some context, interested in Rust since 2009, similar as with Go, but not involved at all, whereas contributor to Go pre-1.0.)
First thing, is that I was frustrated with lack of simplicity vs. Go for a long time as well. Finally, recently I got it: AFAIU it's a case of different priorities. In the triangle of simplicity-safety-performance, Go loves all of them, but in case of conflict, chooses simplicity (thus, most notably/infamously, we get GC and nil). Rust also loves all of them, but in case of conflict chooses safety AND performance. What's freaking crazy IMO is the "AND" here, which I see as a huge thing. And it instantly also explains to me a tension in the Rust community between safety and performance camps, infamously most visible around usage of the 'unsafe' keyword. Yet in a barely-managed marriage between safety and performance, simplicity is the heartily beloved friend, who still just gets silently shown out of the room when a serious row starts between the couple, until they're ready to open the door back, and with patient smiles listen to some friendly suggestions.
Secondly, I bumped my head into a wall a few times until recently I tried the O'Reilly "Programming in Rust (2nd ed.)" on some recommendation from Reddit. The "2nd ed." part is important here, because it covers a few relatively recent important additions to Rust, that I found I was teeth-gnashing frustrated without before (coming from Go), namely: anyhow, thiserror, and (to a lesser extent) async. Edit: Two bonus personal recommendations for the book: (1) I got a job in Rust after going through it and then testing my abilities on some personal project, where I finally felt I'm managing to do regular non-fancy-shmancy (i.e. web, sqlite, GUI via iced, but no macros and avoiding lifetimes whenever possible - if curious, the project is: https://github.com/akavel/backerrs) coding, and can work around lifetime issues (somewhat faster or slower but can, and often just falling back to .clone()/Rc); though in all honesty, they kind of didn't really test my Rust skills, to my huge surprise, and trusted my smarts shown in Go & C++ experience + passion for the project; (2) I'm carrying the book with me to workplace every day and definitely checking things in it from time to time.
However, the garbage collection process itself sometimes introduce a noticeable pause in execution, which can be unacceptable in certain applications. Especially in critical real-time applications.
(That GC pause won't be a problem if your program mostly just waits for user input the majority of the time).
For an extreme example, you don't want your car's airbag controller to be paused for garbage collecting during a crash.
Maybe unified interface to work with DB.
Cryptographic functions while useful age poorly, and require constant change.
Serde while extremely useful won't fit every usecase. Sometimes you want something smaller or faster.
Http(s) clients also tend to age poorly. Python also had http client/server in std lib that aged like warm milk.
For a thing to be in std, it needs to be imo something you don't want implented in several different ways. Something that is essentially solved and will change very little over time.
What would you like to see in that? Genuinely curious, I've considered putting something together that's just a meta-crate that pulls in some others.
Some other candidates include: logging, anync runtime (Tokyo), random generator, regex
I see someone else has got there before me and my answer would not be dissimilar.
Stuff to be able to talk to web services (because let's face it, any modern software will be doing that) is the obvious low hanging fruit, i.e. HTTP, JSON, Crypto etc.
Beyond that (if its not there already) basic tools to enable out-of-the-box CLI writing (e.g. flags etc.)
There are so many different idiomatic ways to instantiate a type in rust that a crate with a common calling convention for most data structures would be very useful.
Deleted Comment
As a developer, what I really want to hear is that Rust 2022 will be basically Rust 2021 with some bug fixes and performance improvements.
Let's hope we get there next year.
1: https://doc.rust-lang.org/book/appendix-05-editions.html
That happens to most actively used languages. C# has seen some major evolutions in recent years and is 22 years old now, Java is 26 years old and has some major changes compared to what it was 7 years ago, and you can no longer discuss C++ (37 years old) without mentioning C++11 along the way.
Rust is perhaps the language that people SHOULD be using, but likely won't. Until someone can offer something as simple and easy to learn as C and also can automatically do the things Rust provides without asking the programmer to give double in mental effort, I don't think we will replace C in a major way.
Edit: Ok maybe a bit dramatic, but I really hoped we would get working modules with c++17 and here we are still years away...
Granted the only way to fully enjoy them is being on Microsoft ecosystem, but hey plenty of us are.
It is not about how easy is it to write rust. It is about how, as a C programmer you are going to explain that your code is safe.
I know that as a long time C programmer, I still make occasional mistakes that lead to memory corruption.
In production code, there are still way to many pointer bugs. Use after free, etc. That needs to end.
Newsflash, it's not a language's job to make software safe. It's job is to make programmer's job as simple as possible: ie. writing new software. If your language fails to do that, people will not use it, plain and simple.
How else could you explain the popularity of languages such as Python and Go?
And I hope that people stop preaching and would live and let live.
Rust is first a system programming language with zero-cost abstractions with the least possible pain, then it is a safe language, way safer than C++.
In any case I am following the community and I have a hard time finding people saying C++ is nice for them. There are few people who have been coding C++ for 20+ years and "love" it but they are far and between. Almost nobody tried both Rust and C++ and continued using C++ for new projects.
So I predict Rust won't replace C, they have different use cases, but it will make a dent in C++.
I recommend the 2nd edition Oreilly book + writing lots of code for about a month or possibly two. After that, I think many will agree it isn't nearly as hard to write as they initially thought it would be.
The biggest bonus: Writing Rust is very fun. I can't pinpoint why this is, but I totally understand why it keeps getting voted favorite language. A total joy to write.
It was the phenomenal Rustlings course that got me over the learning hump.
Of course most of the work gets done by the compiler safe guarding and guiding during development. People make noise about lifetimes etc but once you are ready to pay the penalty of Arc (and in most cases if you are using lifetimes you are already on the verge of using Arc). Same with using cloning as needed. End of the day, these incur a predictable and acceptable performance penalty than many other languages do while providing good safety.
C is neither simple nor easy to learn. Incorrect and buggy C is simple and easy to learn.
If you think C is "simple" and "easy to learn", your C code is almost certainly full of undefined behavior bugs and security holes.
1. https://insights.stackoverflow.com/survey/2019#technology-_-...
2. https://insights.stackoverflow.com/survey/2020#technology-pr...
3. https://insights.stackoverflow.com/survey/2021#technology-mo...
So, I agree with you, it will probably not become a replacement, but it succeeded in providing a credible alternative that has been used by many already.
There are toolkits out there and game engines picking up steam.
My guess is that for a GUI in Rust to truly shine it will have the hard task of working both in native OSes and WASM on the Web. People are working on these frameworks, but most are pretty limited at the moment depending on needs. (If folks believe it’s better than that, please share, it’s only a space I dabble in sometimes)
Add the stdlib and you have plenty of confused faces who after some time fail to see the point.
Given the learning curve of Rust and the lack of tools it's still a bit of a gamble to choose Rust over C or C++ IMHO. Why take that risk when the benefits aren't entirely clear cut.
In 30 years, do we really expect to be programming in some machine-human intermediate language? I hope that we'll be having an open ended conversation with the machines to iterate our intent, with working software at most stages along the way.
This is actually entirely feasible, although perhaps not open-ended conversation. Instead it could be that you feed the machine training data which describes how to solve a particular task, and the output is a program that solves that task. So we would all end up being ML engineers.
Scary I know...
I.e. will it matter what language anyone uses? Here, take this software renderer I wrote in Python, and translate it to C++. "Conversation" about choices and ambiguities ensues...
Just as when people asked this 30 years ago, yes, though from our perspective today the tooling may seem near magical.