It’s not my intention to misquote anyone, especially someone who I respect a great deal, and I apologize to the extent that I have.
I think the disagreement is much more about tonality than the critical importance of the details, for context: I’m a former Rust hater who became a reluctant Rust advocate when I learned (a modern iteration of) it well and would like to be an enthusiastic Rust advocate. For every comment thread where I lose my temper with some of the more, zealous, Rust advocates you can find three where I’m advising someone to look at using it or arguing with the C++ or Haskell folks that they are being unfair to Rust.
My main obstacle to being an enthusiastic Rust advocate is (what is, in my opinion) a self-defeating extreme of enthusiasm and tribalism around Rust most concretely manifested in a “one language” philosophy.
Rust is very cool, and probably the best low-cost abstraction / performance-sensitive language with meaningful traction today.
But C++ has a place, and Python has a place, and Haskell, etc., etc. still have a place. One key example of where C++ and Python and Haskell have a place is that code still builds and still works after decades. This is a weak point of Rust: today a modest weakness, very recently a glaring weakness. So even if I misquoted you in particular: a mistrust around the semantic stability of Rust is a completely legitimate and merited concern, and it is not helped by saying anything other than “yeah, we’re less backwards compatible than alternatives, that makes sense because X”.
As someone who wants Rust to succeed (what 25-year C++ veteran wouldn’t): with the utmost respect, I strongly implore you to say that instead of bringing up an RFC.
So to the first chunk: absolutely. I don't really know what to do about it. You can find oodles and oodles of people with persistent misunderstandings about Rust and various aspects on both sides. Lots of people overstate what it can do, and lots of people understate what it can do. The overstatements tend to look like this:
* The Rust Project, as a whole, will literally never break your code.
* Rust's safety means that "once you compile it, it works." (A funny meme that I remember from my Haskell days. But now people also use it when talking about Rust.)
* Rust makes undefined behavior completely impossible.
Those are all overstatements. The most persistent understatement I see is, "well if Rust has 'unsafe' and everything boils down to using 'unsafe', then what's the point of Rust at all?"
I've spent time correcting all of these misunderstandings in various online forums.
I honestly do not know what the root of it is. I do not see people involved in the Rust project trying to push the overstatements. Most of the documentation materials I see maintained in the Rust project are sufficiently nuanced. It is just not obvious to me where "the Rust project is failing at communication" ends and "communication is heavily lossy and the general population is just going to fundamentally misunderstand most things because nuance has been stripped by the time the content filters down to them" begins.
I have my own mini-problems with this and ripgrep for example. Just the other day someone was trying to say that ripgrep was a "grep replacement" and so wasn't as suitable to code search as ack or ag. Like... wut? I don't see how it's possible to even skim ripgrep's README for less than 20 seconds and come away with that misunderstanding. Upon further prodding, I discovered:
* Their google-fu failed them.
* They "just assumed" from the name, because "grep" was in it.
* They were still a student and ultimately admitted they should have said they weren't "sure."
One of the most important lessons anyone can learn---especially an engineer---is to be clear about their certainty. I think it is just a fact of life that people aren't because they don't want to or maybe more likely, never learned the skill. (And it's even worse outside of engineering.) We could "fix" this by ensuring that everyone commenting online was always labeled with their experience level in a way that was true 100% of the time. Imagine if we could do that, hah. (And if we could, I'm not saying we should, but let's indulge.) I sometimes wonder just how strong the inverse correlation is between "says obviously wrong things with certainty" and "years of experience."
Anyway... sorry... Got off on a bit of a ramble there. Bottom line is that I agree it's a problem, but I don't know how it can be fixed. And there are other factors in play here, given that, ultimately, Rust really is trying to unseat some very old and very entrenched technologies. It is a complex sociological and cultural process.
OK, as to your second chunk... I want to quote the comment I was originally responding to:
> As always when I see this claim, I feel compelled to point out that the Rust team’s claim is simply not true, since they don’t regard adding new functions to existing impls in the standard library as a breaking change, even though it can make working code stop compiling or even do something different.
I am pretty sure that the ideal answer to this comment has to include some mention of our API evolution RFC. It is essential context for how we make decisions. What is less clear is that we don't really have (AFAIK) a solid written document describing how we deliberate on things that are permissible under API evolution, but break code in practice. There is a lot of grey area there. If the breakage is super rare, we might go fix that crate or issue a deprecation notice, wait some time and then make the change. That has happened. If the breakage is not so rare, then it's nearly guaranteed that we'll just drop it. Or find a way to smuggle it in over an edition boundary so that there is no breakage at all (you have to opt into it, and new Rust compilers still support the old behavior on the old edition).
I also note that in your second chunk, you go from talking about "in C++/Python/Haskell, decades old code still builds and works." But you then go on to talk about semantic stability in Rust. Why not compare apples with apples? Rust doesn't have decades of existence to leverage here.
To be quite honest, I would be very interested in analysis of actual decades old code of C++, Python and Haskell. For Python at least, we're talking about pre-2.7. And there were definitely breaking changes introduced in 2.7 when compared to 2.6. And that's just one release. For C++, they break stuff too! For example: https://stackoverflow.com/questions/6399615/what-breaking-ch...
I really truly believe that Rust is no worse than other programming languages when it comes to backcompat. More than that, I think it's better than most.
I appreciate that you likely don't want to name and shame the documentation materials that aren't sufficiently nuanced, but do you think that any appreciable portion of the problem of over-zealous advocacy originates from those materials?
remembers that the rust-lang.org web site changed quite a bit a few years ago and checks it again...
Yeah, there are some broad statements on the Rust home page that, if it were fully 100% up to me, would either not be there or be re-phrased. Unfortunately, commentary on the Rust homepage tends to get sucked into a black hole for reasons that I am not going to elaborate on. (And I'm not trying to say I 100% know all of the reasons. Some elude me.) It is definitely a problem. I don't know how to fix it. I've seen enough people try to suggest changes to the homepage and flounder that I just have zero interest in trying.
The other problem is that most of the re-phrasings I can come up with would use more words than what is there. It's hard to balance pithiness and precision.
Other than that one though, nothing is really coming to mind.
The other issue, perhaps, is testimonials. People can write their own lived experience, and sometimes it looks like a broader claim than it is. For example, I'd say this is generally true of my experience:
> Writing Rust is a very liberating experience, particularly compared to C, because I never have to worry about undefined behavior.
Here, "never" is hyperbole. It would be more precise to say, "99% of the time, I do not have to worry." For many people, it might actually be 99.9% of the time. It is empirically rare for me to need to write `unsafe` in application code, for example. As a similarish example, I use Go at work, and we just never ever use the `unsafe` package. That's not an apples-to-apples comparison, but it's not totally nutso either.
The issue here is that there are some people who use Rust who have to worry about UB quite a bit because that's the nature of the work they do in the context of Rust. So my experience is not universal. Even myself, I would guess that I use `unsafe` quite a bit more than the median programmer, because I tend to work on performance critical core libraries. But even then, it's a vast minority of the time.
So now let's say someone reads my experience and then goes and tells their friend:
> Hey have you seen Rust? It makes it completely impossible to have undefined behavior.
Now we've gone from lived experience to a claim about the language. Rust's goal isn't to make undefined behavior literally impossible. Rust's goal is to make it possible to build safe abstractions that are themselves impossible to use in a way that leads to undefined behavior. This is a deeply nuanced thing and it is super easy for it to get dropped from the context when discussing the language. Yet, the two claims are really quite different. And if the wrong claim is repeated in the wrong context, it really looks like over-promising and marketing-speak, which, rightfully, give people a bad taste in their mouths.
I'll again invoke ripgrep here, which has its own mini-problem with this too. The silver searcher does too. How many times do you hear people say things like, "grep took 2 hours to search my files, but ripgrep did it in 5 seconds!" Or "ripgrep is sooooo much faster than grep."
Like, there are sooooo many problems with saying that!
* Which grep? The performance profiles of GNU grep and BSD grep are radically different.
* Is this an apples-to-apples performance comparison?
* Is the comparison actually about the user experience? (ripgrep might skip that 10GB build artifact in your directory tree where as grep might not. So, if ripgrep isn't doing the same task, is it really fair to say it's faster? Well... yes, it is and no, maybe it isn't. Really depends on the context.)
* They might just have a measurement error. Maybe they tried grep first, which ended up measuring mostly disk I/O. Then tried ripgrep while everything was still warm in their file system cache. Oops. Benchmarking greps is hard.
What to do? I dunno. I try to fix things like this, but like, I can't respond to every tweet that says, "wow ripgrep was so much faster than grep."
I'm guessing most of those people don't have the same level of respect within the Rust community that you do. I could be wrong, though.
> It's hard to balance pithiness and precision.
IMO Rust itself favors precision, so the website should as well.
On the one hand, I think Rust's momentum, including adoption by big industry players, is now strong enough that the website team could afford to avoid even the slightest appearance of over-aggressive marketing. There have been successful programming languages without marketing campaigns, after all; perhaps the best example is C (unless there's some aspect of its history I don't know). On the other hand, maybe discussions on message boards like this one make this problem look more important than it is, and the website is doing the right thing. I don't know.
Good points about testimonials being misunderstood and distorted.
Thanks for taking time to write a thoughtful response.
I’m the spirit of Postel’s Law I decided to actually learn Rust well before becoming truly dedicated to clowning on super fans.
I’m into basically anything if we go all out, as long as Rust is sponsored by a KPop group and a league team fuck hating: let’s make an NFT!
I can't add a lot to what is clearly a thoughtful and passionate analysis from someone who has spent serious time in the trenches of trying to keep both the haters and the zealots at least somewhat on the rails of reality and I applaud your efforts to do so.
Rust is an interesting phenomenon in many senses including this one: it gets hackles up on hackers like me who on average kind of already went through that phase. I think this is because I can already see that it's going to be a Really Big Deal™ for the rest of my entire career, and so at any present-day level of participation, before I hang up the keyboard the culture of Rust is going to be a big part of my world.
And I am far and away more concerned about the former "chunk" than the latter: any remaining loose ends (if there even are any) on Rust's backcompat story will no doubt be tidied up quite soon. I am not only willing but eager to concede the entire latter "chunk" because it's a distraction at best from the importance of the former one.
I'll sort of leave it here: I know that the core team is composed of serious, tenured, hardass hackers who know both C++ and Haskell and made all the decisions that C++/Haskell people criticize thoughtfully and deliberately, that is obvious from reading GitHub. With that said, technically amazing things (like Rust) routinely "fail to achieve their potential" because of culture/vibe/tone factors, and I regard this as the only serious risk to Rust's long-term success. You want the zillion people like me wholeheartedly rather than reluctantly advocating it.
My suggestion, however clumsily phrased initially, is to use your influence in the community to put downward pressure on the zealot stuff even if that requires you to err on the "under-promise and over-deliver" side of things in places like HN.
In the big picture view, this is detail stuff: you folks won, from here it's execution.
P.S. as an `rg` fanboi: I <3 @burntsushi
I think that the Rust community has a tendency to highlight the wrong selling points. Great selling points of Rust right off the top of my head:
* True innovation in memory management, others have done credible experiments with linear and/or affine typing, but Rust has made it work, at scale and in production, this is the first time anyone ever has, and it affords a very compelling compromise between more manual approaches and less performant approaches.
* "Just Works" package management and build: Cargo and the package ecosystem work by default, instead of "work via incredible effort" like C++ or (nowadays) Python. Rust insulates you from stupid platform idiosyncrasies in a way that seriously help you get shit done. There is a tradeoff here, you build a lot of stuff and so the advantage over C++ build times isn't what it could be, but it's basically impossible to overstate how much the rubber meets the road here on both getting started and shipping industrial strength stuff. It's massive.
* A vastly superior type system vs. C++ in basically all the hot paths. Rust has sensible, ergonomic, and pragmatic ways to express parameterized types, to pattern match on them rather than some 1970s `switch`-statement bullshit, to detect more unsafe casts, and to save you from quandaries (return value or out reference? ahh wtf do i do?) that some modern languages cough continue to punt on to the developer to this day. Interface vs. implementation sits in a very sweet spot between all the various directions that question gets tugged in. Bottom line: it's harder to write logic bugs in Rust. You can do it, but Rust helps you here a lot.
* Bundled static analyzer: yes, you can get much if not most of the static analysis that `rustc` gives you by cranking `clang-tidy` up all the way: but first you have to install it, and maintain that installation, and argue with your colleagues about which checks should be on, and, and, and. Rust mandates a sane, curated list of good static checks that come for free and by default. This is also hard to overstate in terms of the practical defect count in many shops.
A few bad selling points of Rust right off the top of my head:
* Memory Safety: Rust does in fact nudge you away from some memory safety issues and reduce the tooling effort involved in `clang-tidy` and `ASAN` effort to get memory safe programs, but it's just not that big of a deal outside of security critical stuff. C++ evolved a good story here while Rust was busy chest-thumping about memory safety, while malicious actors simultaneously evolved their techniques far past buffer overrun. Seriously, mention memory safety in passing or not at all: people like me want to throw something when they hear some JS -> Rust emigree mouth off about it.
* The "Right" Type System: People who know and care about exploiting types well (and understand they are going to pay in runtime performance) are now arguing about Haskell vs. Idris vs. PureScript -> WASM. Rust has a competent and pragmatic type system, but it's Haskell-lite at best in this regard. Compare Rust to C++ on typing, not serious math stuff.
Developer Efficiency in All Cases: Rust has serious developer velocity advantages over it's competitors, i.e. C++, not against all other languages. If you want something working ASAP, Python is better, if you are willing to pay runtime cost and learn shit to go faster over time, Haskell is better. Rust sits in an awesome sweet-spot of fast execution, way above average developer velocity, and quite good tooling. It's not faster than Python for "who cares" and it's not faster than Haskell for raw power. Being the best tradeoff in many cases is plenty, claiming to be the "best" full stop is ridiculous.
Rust's selling points are extremely compelling, and it has a very clean shot at being the "new C". This is plenty, don't overreach. It's a good thing that Rust will never be as expressive as Haskell, as good for numerics as Julia, as good for quick and dirty as Python, or as good for world-wide interop as C: being any of those things would make it worse at what it is!
That's not what I said. What I said was to clarify the situation and to note that actual practice matters.
I explicitly talked about the different meanings of "break" and acknowledged both of them as valid. And yet your portrayal of what I said makes it looks like I'm playing definitional games.
I fucking hate definitional games. I do not play them. I am not saying "that's not what it means" and then sticking my fingers in my ears and saying "la la la I can't hear you." What I'm saying is that there are multiple meanings to the word and talking about those meanings is a requirement for untangling the knot.
So when the libs-api team talks about "not breaking code," we do actually mean that in the literal sense. We care about not breaking code even if the change is compatible with our API evolution policy. But we still need a policy to outline what kinds of changes we can make because some of those changes can break code.
The intersperse method the others brought up is a perfect example of this. It's a change allowed by our API evolution, but we've specifically held back on it because it literally breaks code.