| ▲ | filleduchaos 2 days ago | |||||||
Again to be maybe overly blunt, it's rather strange to call my comment mean-spirited and then simply repeat the exact argument I called out as being wishy-washy. The crux of what you're saying seems to be > You copy everything between threads, or try to adapt every structure that needs to be threaded with Sync, Send, Arc etc. Not very efficient use of ones time. You have not actually articulated any real problem with "Sync, Send, Arc, etc" beyond what just sounds like "but I don't wanna". Even leaving aside Sync and Send, which are constructs fairly unique to Rust, the fact that your other example of a construct you have to "try to adapt" your multithreaded code to use is Arc - quite literally the equivalent of std::shared_ptr - on its own casts heavy doubt on the seriousness of your complaint. Like, "oh no! I have to use an atomic reference counted smart pointer in my multithreaded program" is quite simply unserious as a complaint about a programming language. How exactly you think pointers should be shared between threads, then? Just passing raw pointers around, and taking responsibility any use-after-free bugs that arise because you know what you're doing and definitely aren't going to write one? Well guess what, you can do that in Rust, too (and I have done that in a few non-trivial projects), but you have to mark that obviously unsafe operation with `unsafe`. For some reason, this six-letter keyword is apparently enough to get people who allegedly know what they're doing to break out in hives, and I just do not understand it. And coming back to Send and Sync, if you understand what those traits are (versus just seeing them as something to slap on code to make the compiler stop screaming), then I'm sure you know that they are automatically derived traits. If you are having to explicitly implement them, it is because something in your structure is dubiously thread-safe - for instance, a raw pointer or a type that has been marked as thread-local. If you are that confident that you are handling whatever it is in a thread-safe manner, then what exactly is the big adaptation in the one-line implementation (each) of Send and Sync? If anything, this whole "I have to write new, explicit syntax expressing my intentions and this is The Worst and the same thing as not being to do anything at all" business just reminds me of dynamic typing diehards' complaints about static typing; just replace "using Sync, Send, Arc, etc" with "writing out type annotations". They also complain about compilers rejecting "non-trivial but correct programs" for the minor sin of not being properly annotated. > These libraries usually contain giant blobs of unsafe Rust, which isn't exactly a win for the language. You simply cannot put up this cowboy coder "I don't want to be nannied" argument and then start calling for a nanny because the keyword for "I have information that the compiler doesn't, so I'm taking the reins here" is `unsafe`. It is profoundly unserious. Same thing with this supposed overwhelming complexity of writing regular/safe multithreaded Rust, it really just sounds like wanting the language to pretend that multithreaded execution isn't complex and just handle everything about it for you as you write code as if it is single-threaded and have it just work, without having to think about the semantics. If you don't want to be nannied in that manner, then I don't understand how one can be so dissatisfied with that the language actually does (i.e. provides "certified safe - terms and conditions apply" constructs to express semantics the user is supposed to understand) that they resort to just copying everything instead and genuinely hold the opinion that the language is no different from JavaScript in that regard (a language that notoriously doesn't even have actual threads). And the comparison is plain dishonest no matter how you spin it. | ||||||||
| ▲ | torginus a day ago | parent [-] | |||||||
Ill be extremely terse. Real world world programs usually have states where you can reach a large amount of objects. This runs into problems since you can borrow too much, and the borrow checker will push you into a corner. The solutions Rust uses to deal with this are Rc, Cell, RefCell which turn compile time borrow checks into runtime ones. However using any of these (either by you or a library you use as a dependency) disqualifies your code from being multithreaded (other than the Js worker way of running multiple copies of it on separate threads). Anyone who has written nontrival applications in Rust has encountered this. This is an issue as threading a program will require a huge rewrite. And I concede the point, multithreading is difficult - but Rust doesn't make it easier, it merely disallows most correct programs and forces you to write code in a very particular way. Thus fearless concurrency is a disingenious statement I don't fear concurrency, I fear the borrow checker. As for the cowboy/nanny argument I think this is not a good way to represent safety. Freedom comes from safety - for example, you can make pretty much anything nowadays in HTML/JS without thinking about limitations, and the end user can still be confident that your website won't compromise his system. Nannying is when you are constantly being told what you cannot do. It might not even ensure safety, but definitely restricts your freedom. And the way you write is extremely rude and condescending, if you do decide to phrase your comments in such a demeaning way (which I don't ever recommend), please at least be right next time. | ||||||||
| ||||||||