9 ms·
I find it interesting because of the novel approach to memory management. It is deterministic and zero-overhead like C, C++ and similar, while at the same time
by olavk 8y ago
I find it interesting because of the novel approach to memory management. It is deterministic and zero-overhead like C, C++ and similar, while at the same time safe like garbage collected languages. I think of it like a compile-time garbage collection.
I wouldn't use it as an alternative to garbage collected languages since garbage collection is just simpler overall, but I would consider using it as a safer alternative to C or C++.
- danieldk 8y agoI wouldn't use it as an alternative to garbage collected languages since garbage collection is just simpler overall, I do not disagree, but I think one could argue to the contrary as well. Since most garbage collected languages do not guarantee that objects are actually (timely) garbage collected, you cannot tie the lifetime of other resources (file descriptors, sockets, locks) to object lifetimes. So, the burden is on the programmer to ensure that resources are correctly finalized. Whereas in RAII languages you can properly tie all finalization to object lifetimes. Note: I am not arguing that GC-ed languages cannot do RAII. AFAIR D has a GC and supports RAII.
- olavk 8y agoThis is true - for example, C# has the `using` block to ensure resources are deterministically released when they go out of scope, not when they at some point later are garbage collected. I would still argue C# is much simpler than Rust since for most object you don't have to worry about this. But I guess there is a certain extra complexity in C# because you actually have to know if a class owns some external resource or not, while this distinction is not necessary in Rust.
- moomin 8y agoIn practice that's rarely an issue, because a) if it has a resource it'll implement IDisposable and b) my IDE screams when I don't dispose an IDisposable. This is not as good as the Rust model, but it's not awful, either.
- olavk 8y agoYes but that is just the compiler offloading some of the static analysis to the IDE. The difference might not matter if you are always in an IDE anyway, but the language would be safer if this was an actual compiler error.
- jerf 8y agoIn most modern languages, there is some way to tie object cleanup to a scope, even for a GC'd value. Note I say "cleanup", as in "I closed the file handle" or something, not "finalization" which is a GC-specific term. It isn't necessarily as rigorous as RAII but it works in principle in much the same way. "with" in Python, for instance, "defer" in Go (less automatic but if used properly fits the 80/20 nature of Go), Haskell has a motley crew of solutions, most other languages you can put something together yourself if nothing is provided. Where things get complicated is when you don't have a clear scope to tie lifetime to and so you can't use these, but then, that applies to RAII too. I'm not saying C++ doesn't have a bit of an advantage here, but I think it often gets oversold as "C++ has RAII and other languages have nothing even remotely resembling it", which isn't true. In practice this isn't a problem that I encounter in GC'd languages anywhere near often enough to justify even a slight preference for a "true RAII" language.
- danieldk 8y agoIt isn't necessarily as rigorous as RAII but it works in principle in much the same way. I would say that in principle they work very differently ;). They work superficially in the same way in that if you tie a particular object to the current scope in a RAII language, the cleanup happens at the same point as defer, with, try-with-resource, etc. would. However, there are cases where you really want cleanup to be tied to the object's lifetime. For example, I have a Tensorflow binding for Go. However, I cannot pass Go-allocated memory (e.g. memory allocated to a slice), because Go does not allocate slice memory on 32-byte boundaries (using Go memory would cause an allocation + memcpy in Tensorflow to align the memory). So, you allocate memory in C-land and have Go structs that wrap your pointers. However, now cleanup becomes interesting. You do not want to rely on finalizers, since they are not guaranteed to run. However, using a Close method is also an annoyance. For tensors that live for the duration of a graph run, it is fine (you can use defer), but other tensors live longer and are reused between runs, shared by models, etc. It becomes unclear pretty quickly who is responsible for closing the model. I also use a Tensorflow binding for Rust, which is drastically more convenient in this respect. Since ownership is clear, the lifetime of a tensor is bound to the scope or object that owns it. If the owner is dropped, the tensor is also dropped. If you need to share a tensor, you make an Rc/Arc the owner.
- Const-me 8y ago> I would consider using it as a safer alternative to C or C++ I would, too. But there’re problems for which C or C++ is just faster because of language/compiler extensions like SIMD intrinsic or OpenMP. Also Rust can’t be used for GPU code; strictly speaking C can’t either, but practically CUDA, C++ AMP, OpenCL are very close to C and/or C++. Also if you have to deal with lots of pointer-based data structures (trees, graphs, etc)., and it’s not just on the lowest level you can abstract away behind a safe API, I don’t think Rust is safer. To get performance comparable to C++, it’s necessary to use unsafe rust for raw pointers, and IMO modern C++ is safer that unsafe Rust.
- steveklabnik 8y agoSIMD is coming in eight weeks, incidentally.
- Const-me 8y agoGood to know! But even if it’ll become available in 2 months, it’ll take some time to develop Rust libraries on top of them. E.g. in various performance-critical C++ projects I have used https://github.com/Microsoft/DirectXMath https://github.com/Microsoft/DirectXMath and https://eigen.tuxfamily.org https://eigen.tuxfamily.org Both are quite large projects with many man-years spent to develop, they saved quite a lot of my development budget.
- steveklabnik 8y agoYes and no, a lot of libraries have been built on top of the feature while it was unstable. It’s been in nightly for quite a while at this point. Of course, more libraries are needed as well, but there’s already some higher level stuff. See https://github.com/AdamNiederer/faster https://github.com/AdamNiederer/faster for example. And const generics, coming to nightly near the end of the year, will be another step up. It's true overall that numeric stuff is a weakness, but we'll get there!
- pcwalton 8y agoHow is modern C++ safer than unsafe Rust? In Rust, the borrow check is still active even in unsafe blocks. In C++, however, the complex rules around when destructors are called, combined with references, are a constant use-after-free footgun that you can never eliminate. Rust projects that use unsafe code are empirically safer than C++ projects. See, for example, the Servo style system as used in Firefox.
- SomeHacker44 8y ago> It is deterministic and zero-overhead I wouldn't say zero-overhead. I would say O(1) overhead in the best case, and equivalent to C-style manual memory management in the typical (which again isn't zero-overhead and isn't even necessarily always O(1) overhead with heavy allocation and deallocation). But, yes, it isn't GC'd with the attendant challenges GC poses (or benefits it brings).