My view is that, without understanding and appreciating why Rust exists (memory safety and data race freedom, plus C/C++ level performance, etc), the difficulties in learning Rust will also be misunderstood and magnified. However, that isn't necessarily a reason not to use Rust. That's really an individual decision, and may or may not be related to the question of whether Rust is the right tool for a particular purpose.
@alper I do think it would be best to have a thread per problem you're having. This was a productive thread about the poor error message you encountered. But your issues with RA freezes, macros in RA, and lifetimes really deserve separate threads so they can be explored more thoroughly.
In my opinion memory safety is a highly misrepresented and overrated feature of Rust. Almost all languages in use today are memory safe except for C/C++. The real innovation of Rust in terms of safety is that it is memory safe without a garbage collector. And this allows for minimal overhead and maximal performance while also ensuring data race freedom (which is even more unique I think).
I havenât looked at your fix in detail, so maybe youâve already covered this. But the more complicated case I can think of would be some kind of interaction with match ergonomicsâ The pattern Some(counter) can match either Option<âŚ> or &Option<âŚ> depending on context, and the choice will affect the type of counter inside the match arm.
I think this shows what I was trying to convey before with "it's easier to complain than to fix". While you keep reminding us that you're "just" asking for improvement, your attitude contradicts that.
As you pointed out, there are many who use the language a lot. And that should tell you something about how robust and powerful Rust is. You've pointed out real problems, for which we are grateful! But you keep saying "oh and this, and that, and the other thing are all wrong", which isn't productive, nor very fair. It sounds more like you want to vent about the language and prove why it's bad, rather than improve it - and there are plenty of those people out there, on any topic.
Perhaps part of the problem was us. I've noticed the Rust community, including myself, tends to dogpile on anyone who raises an issue with Rust. Just look at the message count on this thread! Not so much because they feel the person is a threat, but because they feel the concerns they raise are. So we rush to defend, to fix, to validate, to explain... and while we're well intentioned, I can see how that puts people on the defensive. For my part, I'm sorry; I was trying to honestly address what I thought was the core issue. But I was also foolishly trying to be some sort of self-appointed "champion of Rust", defending it from all perceived threats and evils. My ambition obscured my ideals.
So moving forward, I hope we can all be productive and cooperative. There are good reasons why we don't believe some of your complaints are legitimate. Many of them are, though! But we'll never get anywhere by all jumping into one thread and voicing all our concerns, opinions, and advice all at once.
This will always be a bit of an ambiguous case, I think. It's why, for example, the suggestion I posted uses *, whereas the documentation uses &*. There's no way to really tell what the right solution is just based on local information, because we might be using a reference to avoid moving in order to allow some code later down in the function to work.
The suggestion works on a best-effort basis, where the idea of reference vs non-reference is determined by what the code originally did. That is, if the type of the match scrutinee was a reference, then the suggestion will also be a reference. This may lead to cases where the suggested fix leads to a compile error (probably due to the dereference moving the value), which brings up a different suggestion (probably suggesting to borrow after the dereference), which finally fixes the issue.
I mean I know and I keep asking myself whether the 10-50x (I grabbed Svelte and got to the same point as here in 30 minutes) productivity hit is worth it. But since this is a side project, the very point of it is to learn which wouldn't happen if I picked a comfort language.
It's not just Rust. I feel Typescript has many of the same issues but without the performance benefits.
That is indeed very cool. I hope we can do more there.
I think most of my problems would have been much much blunter if RA had worked reliably. I have no idea what the state of it is but it seems that it has a separate development track/team/cycle from the main language. I looked it up and it seems a separate org that releases weekly.
Instead of having the compiler fix these issues, I think there is probably a large design space that's still open to make tools that will support people to make the right decisions. Whether that space gets explored depends on those socio-technical factors.
The intended reading there, AFAICT is "anyone can create (this type of software)" (which was effectively not true before) - that's not to say they can easily or quickly do so, but that they can reliably do so.
The whole point of Rust is that before there were two worlds:
Inefficient, garbage collected, reliable languages
Efficient, manually allocated, dangerous languages
And the mark of being a good developer in the first was mitigating the inefficiency well, and for the second it was it didn't crash, corrupt memory, or be riddled with security issues. Rust makes the trade-off instead that being good means understanding how to avoid the compiler yelling at you. (In reality, these are all eventually the same actual skill: understanding how to design programs to avoid mismatching the hardware.)
In other words, with JavaScript, you need to be a genius aware of a whole bunch of crazy tricks to scrape out the last bits of performance (and that's one of the better cases!), while with C you need to be a genius aware of every possible angle of undefined behavior to be reliable, with Rust you just need to be patient
This does not mean Rust is ideal, not even that it's great - if the explosion of interest around GCed languages in the 90s and the current interest in Rust are reflections, then we should see a lot of competitors popping up over the next 20 years or so - we're already getting the "actually the old way can do this fine" now with "memory safe C forks" that are actually just adding a GC, and C++ is looking at adding borrow checking - but there's not any clear precedent that borrow checked languages will completely replace the use of unsafe or GC languages no matter how smooth the experience is made (hopefully, though, it replaces unsafe languages for at least security relevant code!)
I say much worse things about Typescript (which we use at work). And I'll be damned if I go back to Apple's haphazard development of Swift.
So that's why I'm here: I think Rust has a good shot at being a (somewhat) general purpose language for a (somewhat) significant audience.
That said there are still lots of issues and I'm not sure whether I'll ever get to use this language professionally.
Anyway thanks everybody. I've gotten a lot of clarification, my frontend is near shipping and I look forward to see many more improvements in the Rust language.
I saw this bit of Hashimoto comparing Rust and Zig and his take that the Rust type system a lot of the time becomes soul crushing resonated a lot with me.
I feel here I was trying to come to a similar point.
It seems to me that all languages have the problem of dealing with types. Unless the language is so simple it only has one type, but that would be hard to work with and hardly a "high level" language.
Indeed life itself has a problem with types. If I order a coffee at the coffee shop and they give me a pint of gasoline instead I might not be so happy.
I'm curious to know what you feel the "fix" should be? For example if a function expects an array as a parameter but you call it with a structure what do you think should happen?
I only see three possibilities:
The compiler ignores ones mistake and tries to generate some code to handle it. Almost certainly the resulting program would not produce the results you expect and lead you to do a lot of tuning, testing and debugging work to find such errors. C and C++ for example will silently coerce different types of ints and try to do something with them, often leading to subtle errors.
The compiler generates code that detects the type mismatch mistakes at run time and halts the program, hopefully with a meaningful error message. That has the down side that run time checks would degrade performance and increase code size significantly.
As the compiler knows the types of things you have created in your program it could detect such type errors at compile time. As Rust and others do.
So, given dealing with types is a problem and we would rather have types to describe our solutions rather than try and do everything with a single type it becomes something of a philosophical question or personal preference as to how a high level language should deal with them. Would you prefer to deal with your type errors as compile time or spend time finding and fixing them at run time?
I have seen that video you linked to. Although I know nothing of Zig. I don't see Rust's fussiness at type errors at compile time as anymore "soul crushing" than having to deal those same mistakes by testing and debugging.
Rust became a lot easier when I realized how a lot of its pain points, not all of them, are just things you'll need to deal with anyway. That mindset also made be better and happier with other languages too. Sometimes you just gotta do what you gotta do.