3 ms·
> When people move from C++ to another language for more safety, Rust is not their only option. That's arguably missing the point. For a very long time, manage
by 0815test 7y ago
> When people move from C++ to another language for more safety, Rust is not their only option.
That's arguably missing the point. For a very long time, managed, GC-based languages like Java or Go were the only option for workable memory safety! (Yes, I'm ignoring a lot of stuff because it's practically irrelevant. No need to tell me about ATS and the like, thank you so much.) Cyclone and now Rust have changed that, which makes for a real paradigm shift in the industry, at least potentially. Rust even contributes meaningfully to thread safety by getting rid of simple data races, which are a huge can of worms not just in C/C++ but managed languages as well!
- Const-me 7y ago> which are a huge can of worms not just in C/C++ but managed languages as well Multithreading with mutable shared state is harder in general. That's language agnostic. But it's easier to do correctly the way managed languages do. They don't usually create threads, they use thread pool and post messages to each other. This is language-agnostic too, I've tried doing same in C++ and it works, e.g. https://github.com/Const-me/vis_avs_dx/blob/master/avs_dx/DxVisuals/Hlsl/Async/CompileWorker.h https://github.com/Const-me/vis_avs_dx/blob/master/avs_dx/Dx... but with a GC and async-await it's much easier. > which makes for a real paradigm shift in the industry, at least potentially I think for most people, getting stuff done is more important than shifting paradigms. Rust is less productive than managed languages (GC helps, BC interferes), compiles slow, slightly less safe. For network people, golang is quite popular already, .NET core wants there, too. Game developers use too much C++ libraries, don't need security (console games are sandboxed or run under HW hypervisor), their most painful C++ issue is build time, and Rust is even worse. Low-level embedded, driver, linux OS kernel developers need C, too much integration and too many weird target platforms. HPC and ML people need manual SIMD and corresponding libraries. CUDA people need nVidia support. Open a job board, type C++ and press search. Do you see many positions except listed above, where people are still writing C++?
- ComputerGuru 7y ago> But it's easier to do correctly the way managed languages do. They don't usually create threads, they use thread pool and post messages to each other. C# certainly never worked like that. `System.Threading.Thread` was the backbone of its concurrency model, together with everyone’s favorite auto/manual reset events, mutexes, and semaphores. While with .NET Core there are some libraries providing channels seeing adoption, the majority of the decline of threads in both legacy and Core .NET is from the move to async everything, which really obviates most of the need the casual developer has for dealing with concurrency primitives (at the cost of being absolutely dumbstruck when the abstraction leaks, obviously). Redmond did an incredible job updating basically every single API in the BCL for async (contrast to the pathetically slow going in the world of nodejs).
- Const-me 7y ago> C# certainly never worked like that. https://docs.microsoft.com/en-us/dotnet/api/system.threading.threadpool.queueuserworkitem?view=netframework-4.8 https://docs.microsoft.com/en-us/dotnet/api/system.threading... scroll to the bottom and you'll see it's from .NET 1.1. That's 16 years ago. In modern world, Task.Run does approximately same. > together with everyone’s favorite auto/manual reset events, mutexes, and semaphores. When I'm not sending messages, I prefer lock() keyword. A syntactic sugar over Monitor class. Unlike events and semaphores, it's not a wrapper around an OS sync.primitive, but implemented on the VM level. Pulse and TryEnter APIs are nice. > incredible job updating basically every single API in the BCL for async The important job was done much earlier then that. Before .NET 1.1 MS decided the fundamental IO class, Stream, needs async API, exposed BeginRead/EndRead, and the rest of them. That's how updated to async-await that fast, they are thin wrappers over the underlying async API which was in standard library for years already, tested and debugged. Few people used them before because callback hell was bad.
- Matthias247 7y ago> The important job was done much earlier then that. Before .NET 1.1 MS decided the fundamental IO class, Stream, needs async API, exposed BeginRead/EndRead, and the rest of them. I think the reasoning for this goes back even further. Windows NT already offered a set of comprehensive async APIs in term of IO completion ports and overlapped operations. The .NET APIs are merely wrappers of those. They are too good to omit them.
- 0815test 7y ago"Mutable shared state" is precisely what the Rust compiler checks for. Mutable state (in sequential code), no problem. Shared immutable data, OK. But as soon as you inadvertently mingle both the compiler will notice, and demand that you deal with the issue (by explicitly serializing access, and/or by using lightweight runtime checks that ensure you're not "sharing" anything that shouldn't be - this is what happens when you use Rust's 'interior mutability' facilities). And because these places are explicitly marked in the code, it's easier to audit them for bugs, same as with 'unsafe'. "Posting messages" is just another way of sharing non-mutable data, Rust has facilities to help you do that as well. By the way, this is why the "borrowck interferes" quip is only true if you haven't internalized the things BC checks for. Once you have done so, you understand how it helps. The slow compiler is an issue unfortunately, but that only affects code generation - the static checks Rust does are quick and easy. Besides, "if it compiles it works", right?
- Const-me 7y ago> is precisely what the Rust compiler checks for. Mutable shared state is required in many real-life cases. CPUs suffer heavy penalty for random RAM reads, random writes are free (especially when using MOVNT* instructions to bypass caches). When working on computational code you want to optimize for read access. This often means write patterns are random, i.e. you can’t slice arrays per compute thread. > because these places are explicitly marked in the code, it's easier to audit them for bugs C# has very good OOP support. All class members are private by default. Wrap that mutable shared state into a class with thread safe public API, will be equally easy to audit.