Writing widely useful, performant, reusable, correct and stable libraries is very hard. Rust is the easiest language to do that in.
If someone says programming in another language is easier, it's because they are not attempting (or are failing) to do one or more of those things. Those things are not always important so that's fine, but a lot of programmers (myself included) have this dream of being able to solve a problem once rather than over and over again, and that's why Rust appeals to us, and why we argue against Rust being hard - because it's actually easier for our particular usecase, but clearly not everyone has that same usecase.
> Rust provides very substantially less support to library designers than C++ does. Anyone creating ambitious libraries finds Rust a big step down.
Before I used Rust my main language was C++ where I specialized in writing libraries, and this is a ridiculous statement.
It's only recently that the C++ standard library has gained enough functionality to do even some basic things in a portable way, so you're relying on other libraries to provide that, yet there is no standardized way to declare dependencies on those other libraries. There is no module system to ease structuring library code. There is no hygiene - a ton of stuff you include will just pollute the global namespace. There is no standard way to version your code. There is no standard way to update a library. Everyone uses incompatible string types - seriously, if you think Rust has too many string types, wait until you find out that every freaking C++ library represents strings differently, sometimes using the same types though! There is no standard place to publish libraries. Even basic language types like `int` differ massively from platform to platform, or even between different compilers on the same platform. Each compiler's preprocessor behaves slightly differently. The programmer must manually forward declare their functions, types, etc, and the rules are different for inline/templated code. All code is unsafe, and yet the rules for what constitutes UB are informal at best. (Whereas in Rust, the rules for UB are also not fully defined yet, but this is only relevant for the minority of your code which is not safe). All experienced C++ programmers think in terms of lifetimes, and yet cannot express this through the type system, so this must be documented informally. There is no standardized coding style or format.
I'm going to stop now just because I'm bored but this list could go on for a very long time...
What makes UB in C++ is spelled out in its International Standard; there is no specification for Rust, just an implementation. It has been many years since C++ preprocessors differed notably from one implementation to the next. Nothing in C++ is global except what you choose to make global.
In fact today C++ lifetimes are expressed in the type system, and this is an example of what C++ enables a library to provide.
If, working as a library designer, Rust was not a big step down, you were neglecting to provide users of your libraries much of the value you could have offered. Your remarks suggest that libraries you delivered were closer to C than C++.
> What makes UB in C++ is spelled out in its International Standard
That's not true, the standard only specifies that some things are UB, it is not exhaustive, nor is it unambiguous. Furthermore, no current C++ compiler is compliant even with those parts of the standard which everyone agrees on (eg. see proposals to introduce a "bytes" type to LLVM to resolve known miscompilations). There is work to improve this, such as defining an explicit memory model, but Rust is ahead of C++ on this.
> In fact today C++ lifetimes are expressed in the type system, and this is an example of what C++ enables a library to provide.
Do you have an example of this, or are you talking about using smart pointers? Smart pointers are about ownership, not lifetimes.
> Your remarks suggest that libraries you delivered were closer to C than C++.
Most of my remarks were about consuming other libraries from my library, which is not something I have control over. Sure, I can use smart pointers and other modern C++ features in the API I expose... That doesn't change any of the points I mentioned.
If someone says programming in another language is easier, it's because they are not attempting (or are failing) to do one or more of those things. Those things are not always important so that's fine, but a lot of programmers (myself included) have this dream of being able to solve a problem once rather than over and over again, and that's why Rust appeals to us, and why we argue against Rust being hard - because it's actually easier for our particular usecase, but clearly not everyone has that same usecase.