The blog post about "Why strings seem hard in Rust" was not met with excited reactions.
The blog post about "Why strings seem hard in Rust" was not met with excited reactions.
Rust does not force you to do this. You can in fact pass around `String`, `Vec<…>` etc, and Rust will use move semantics to make it reasonably efficient. Of course using &str and &[…] is the proper "zero overhead" solution, but it does require some extra effort.
Some expect String while others expect &str.
Once you understand why, it’s easy to intuit which one should be used where, but it was a day 1 speed bump for me.
Like, if you have fn f(s: &str), you can do:
let x: String = String::from(something);
f(&x);
You can see this in playground here [1] (click "Run")To explain: both String and &str is essentially a pointer plus metadata, but &String is a double pointer (a pointer to a pointer). Rust knows how to convert double pointers to pointers, using the Deref trait. This implicit conversion is applied only in a handful of places, and only if it doesn't lead to any ambiguity (if f received a generic parameter it wouldn't work for example).
If you wanted to convert String to &str explictly, you would need to write &*x, like this (see in the playground here [2]):
let x: String = String::from(something);
f(&*x);
That's because if x has type String, *x has type str (because String impls Deref<Target = str> [3]) and &*x has type &str. This means that auto-deref changed your &x into &*x automatically.[0] https://doc.rust-lang.org/book/ch15-02-deref.html#implicit-d...
[1] https://play.rust-lang.org/?version=stable&mode=debug&editio...
[2] https://play.rust-lang.org/?version=stable&mode=debug&editio...*
[3] https://doc.rust-lang.org/alloc/string/struct.String.html#im...
Personally I wouldn't be writing web services with Rust, I don't think the language was really designed with that problem set in mind.
As a replacement for Go if you want a comprehensive type system instead of a skinny one.
If you are into MS or AWS ecosystem there are also SDKs available for their clouds.
But there are a lot of people in IT with experience in other fields that gets on into the marketing sales pitch that is trendy since the Java days, and i'm not blaming the community of doing anything wrong here, giving its the expected behavior of tech communities nowadays. But there is this noise into how Rust is sugared that i dont think its true, in that its the first system language that is as productive as a mid-level normally GCed language like Java or Go while giving more control and performance.
I think there is no language into that spot yet, but i think that something that follows Rust could achieve this (Its something in the middle of Rust and Swift).
The control and performance are there, as happens to C++, but the productivity is basically the same, which is not very good as compared to other languages that target more of being productive than being in control.
The control level pay out in the end in the quality of the final product, but it s not the best option for things that dont require the amount of control that C++ and Rust gives you.
But the thing with Rust, C++, Zig, etc.. is that, when you need it, you need it. There are things that can only be done with those kind of languages, and often are very complex and high-performant piece of software.
Its not for everyone, and you need a sort of commitment that you would only pay if you really need. So writing things like 'web services' on them is not optimal, and you should use languages like Go, Java et al. for this.
Tech people should be able to navigate hype and marketing lingo and see the things for what they are, i think is the same that is happening with 'web3' right now.
This is not very fair to Rust. It's absolutely more productive than C++ when you account for the productivity benefits of "not shooting yourself in the foot" with pesky memory-safety bugs. Let's not even talk about scripting tools like Python, Ruby or JS that were never designed for "programming in the large" yet have somehow become popular in that role (with predictable consequences wrt. technical debt and lack of long-term maintainability).
The proper, challenging comparison is with correctness-oriented GC languages like Haskell, OCaml, possibly F#. And Rust might nonetheless have the better community, since it can address systems-level and performance concerns out of the box unlike those.
For a 'stable' production implementation after prototyping, I agree that the benefits Rust provides (if it compiles, it will either panic or work) are well worth it, and so longer-term, I buy that you probably will spend less time, but in my experience, things like not being able to specify default field values inline (you need to provide a 'new' function, or 'default' impl, meaning you then have very tightly-coupled parts in different places in the code) compared to C++11's member variable inline initialisation is very fustrating when in the early stages of prototyping, when things are changing a lot.
Similarly, as mentioned above - string handling, with as_str(), to_string(), String::new(), from(), etc, I think make some sense at a full production level when you might care about ownership / copies / allocations, and want them to be explicit, but when you're just prototyping stuff to work out data structures and relationships, it's increadibly annoying IMO when you're refactoring.
Rust's "struct update syntax" can be reused to do this. `MyStruct { my_field: 42, ..my_local_defaults }`, where my_local_defaults is an instance of MyStruct that's in scope.
In C++, you can set the default at the same time as you declare the member variable, meaning the three things (variable type, variable name and variable default) are in exactly the same place in the code on the same line.
In Rust, you can't do this, you need to implement new() or default() (or manually specify all field items when declaring the struct), which is normally in another place in the code, so you have tightly-coupled code in two places, which is as bad as C++ headers and implementation files which is what a lot of Rust evangelists seem to complain about on here about C++ (it's a valid complaint, but I don't think Rust completely gets it right, as is complicates / makes things more verbose in other ways like this one).
I’m cautiously optimistic that Rust will get this at some point. There’s quite a lot of demand for this in the Rust community (although some opposition too)
The key reference on "modern" C++ is the "C++ Core Guidelines". They're pretty comprehensive but quite complex as well, and they don't really manage to establish a "sound" or "safe" idiom for the language; they're more focused on avoiding the most common pitfalls.
Once upon a time C++ was supposed to produce "code bloat". Now it doesn't, without any changes to address that.
I have spent strictly more time in the last five years filing compiler bugs than chasing memory usage errors in my C++ code. So, whatever benefits the extra work needed to make rustc happy, and time waiting on slow, slow builds is supposed to deliver, it fixes no problem I have.
The same is probably true for anybody coding C++ using modern library facilities. There is just no temptation to do anything dodgy. It would be more work than the safe thing.
So, the marketing insists on these benefits, but I don't see them. It is likely old code was more prone to such bugs, but we are talking about coding now, not then.
Rust has lots of nice features to make coding pleasant, and you can evidently get used the nannying, so it seems like an OK choice for a project that nobody else will need to maintain.
std::string_view is but the latest example of a "modern" C++ facility that turns out to be a dodgy footgun, due to the lack of safeguards around lifetime errors. C++ still lacks a general equivalent to string_view for arrays (what Rust calls a slice) for the same reason. These seem like significant drawbacks to me.
maybe because your code isn't worth having people actively attack?
It makes sense. A common use case for C++ today is writing high-performance software, where the software architecture is likely to be schedule-driven (e.g. thread-per-core, userspace I/O, etc). In these cases, you see minimal heap allocation, shared structures, or locking. Modern C++ is pretty safe by default for this; it allows you to do unsafe things, and to do safe things that the Rust compiler deems unsafe, but there isn't a cabal forcing people to write non-idiomatic unsafe C++ code in software architectures where the code is naturally almost entirely single-threaded and with few heap allocations.
The most insidious bugs I see in modern C++ code bases are scheduling bugs e.g. logical or behavioral edge cases due to pure async execution, which can be very subtle. Rust doesn't help with that.
Apart from that, everyone even half competent would know that and make a trade-off involving other factors. Being dogmatic about a single facet isn't helpful.
When doing generic application level programming: use STL containers, iterators and algorithms properly and you won't have any of those pesky bugs. Does not require much efforts.
If you do want to shoot yourself C++ will of course offer thousands of ways for you to do so. But with modern C++ it has to be your choice. Unless of course you are working on some specialized system type code, libraries like STL and other similar tasks.
I'm pretty sure that a lot of people will be more productive with Rust as compared with C++ as with others will be the opposite. So i guess in by making an average over those two crowds, i doubt they will differ that much.
The sort of bugs Rust will avoid that are kind of hard to debug, giving it doesn't happen that often is the problem of shared state in a multi-thread environment.. the other kinds are often easy to spot in C++, the only difference is that they are caught in runtime.
Conscientious programmers aren't going to spend too long in the shooting themselves in the foot phase.
To me the awful compilation model and horrendous compile times are much bigger productivity bummers.
I enjoy helping folks debug memory safety bugs that stumped them. It takes the drudgery out of the day. And it's usually an opportunity to teach them something.