5 ms·
This has been my problems with Rust for the last 10-12 months. Lifetime elision seems thoroughly broken or extremely limited in functionality, and now when I'm
by dave_ops 11y ago
This has been my problems with Rust for the last 10-12 months.
Lifetime elision seems thoroughly broken or extremely limited in functionality, and now when I'm writing (sometimes seemingly trivial) solutions in Rust I'm spending at least as much time and mental energy explicitly annotating lifetimes as I would be if I was just managing malloc and free in C.
As a result the pain vs. benefit curve doesn't bend nearly as far toward Rust as it theoretically should.
- Manishearth 11y agoI'm interested in seeing your use cases where lifetime elision isn't helping. I've found that it's helpful in the vast majority of cases, and when it isn't working (for functions, at least) there's a decision to be made. It also could be a programming style thing; I've seen newcomers from C++ often trying to program in the C++ style and having lifetime troubles because the C++ style isn't really amenable to Rust's model. (I feel this might be the issue since you mentioned "sometimes seemingly trivial" -- almost every time someone has said something like that about Rust it's a matter of a programming pattern not translating directly) Also, really, lifetimes don't do away with the effort required in manual memory management, they just confer it to compile time, so at least you can be sure that your code works and will not break in the future. They're not really a new concept, you think about them anyway in C++, just in a different way.
- dave_ops 11y agoI'm a functional programmer (Lisp, OCaml, Erlang), and I only touch C++ when I have to wrap it in something to interface with a higher-level language. Most of the cases where I run into this problem and end up feeling like I didn't gain much, if anything, from doing a straight C implementation are situations with deeply nested data structures. I get that the thinking is that the benefit is that once I've made the compiler stop complaining, my memory management model should at least be sound and safe, and that is a win. Though immediately following that I start to have dream-like fantasies where this entire static analysis stage is simply bolted onto C instead of being a whole new language. Afterall you can do some pretty impressive stuff with nothing but a pile of preprocessor macros (see Objective C).
- Manishearth 11y agoFunctional idioms don't translate cleanly either :) If you're using Rust for FFI from functional languages (or any language, really) you need to use a fair amount of unsafe code to get the interface correctly. There's not much benefit for simple things (aside from cases like these: https://gist.github.com/steveklabnik/1a3ec0ca676aaddf766e https://gist.github.com/steveklabnik/1a3ec0ca676aaddf766e), but for more complex things it works out pretty nicely.
- pcwalton 11y ago> Most of the cases where I run into this problem and end up feeling like I didn't gain much, if anything, from doing a straight C implementation are situations with deeply nested data structures. Your feeling doesn't line up with what has been observed in practice. Empirically, people do not get the memory management right in C. They mess up, again and again and again. In Rust, however, the compiler enforces that you get it right. > Though immediately following that I start to have dream-like fantasies where this entire static analysis stage is simply bolted onto C instead of being a whole new language. I don't think it's really possible to bolt Rust's semantics onto C. Too much will break: in particular C code is not written with inherited mutability, which is critical to Rust. You could maybe do something like the proposed lifetime stuff in C++, which still requires lots of annotation, enough to effectively be a whole new language. Rust has a lot better ergonomics anyway. > Afterall you can do some pretty impressive stuff with nothing but a pile of preprocessor macros (see Objective C). Objective-C isn't "a pile of preprocessor macros", and it would be completely impossible to implement the lifetime system using the preprocessor.
- Animats 11y agoThat can be a problem. Some common C/C++ idioms do not translate to Rust. In particular, a function which creates and returns an object is difficult to express in Rust. In Rust, you have to create the object before the call, then pass it to a function to be filled in. Either that, or go with a reference-counted type.
- comex 11y agoAre you referring to objects that contain inner pointers? Otherwise you can just return T or Box<T>.
- Manishearth 11y agoYeah, at some level of complexity you do start needing some Cell/RefCell/Rc, but it's not much.
- ryeguy 11y agoWhat makes you think you can't create and return an object? This is how every constructor function in rust works.
- shadowmint 11y agoI believe this is referring to '...and keep a mutable reference to it' ie. A singleton, and many overseer style observe-and-update-on-change data binding patterns. Basically, shared ownership is pretty central to many C++ patterns, which means they translate poorly into rust.
- pcwalton 11y ago> Lifetime elision seems thoroughly broken or extremely limited in functionality Do you have examples? Have you filed bugs?
- laughinghan 11y agoBut there's no compile-time validation of malloc() and free()---there aren't even strict run-time checks, right, it's possible for freeing an invalid pointer to quietly corrupt memory instead of segfaulting, right? So if these annotations took the same amount of effort as manually managing malloc() and free(), they'd still be strictly better because they're validated at compile time, no?