5 ms·
The biggest hurdle people seem to have with Rust is that it makes you very aware of the difference between stack and heap allocated data. For someone coming fro
by orclev 10y ago
The biggest hurdle people seem to have with Rust is that it makes you very aware of the difference between stack and heap allocated data. For someone coming from a garbage collected language (or even in some cases C) that's a pretty big hurdle to get used to. I've found Rust to be amazing to work with, but it does feel like a struggle sometimes when all I want to do is allocate some structs without having to faff about with Box types.
Honestly I feel like peoples biggest issue with Rust is that they're trying to write things in Rust that don't actually need Rust. They want the ease of use that you get with a garbage collected language and then get annoyed when Rust forces them to worry about allocations and cleaning up after themselves. C++ should have the same issue but its been around long enough that most of those details have safely been wrapped behind STL and other abstractions to the point where most people don't need to worry about them. Perhaps in time Rust will reach that point as well and everyone will be using the equivalent of Boost that abstracts worrying about whether something is a Box<ARC<Foo>> behind a nonthreatening layer of macros.
- weberc2 10y agoGo has the same distinction (stack vs heap), but the GC means you don't need to care about the lifetime of the data. To your other point, it saddens me that Rust isn't well-suited to higher level applications. You need very strict performance requirements before it makes sense to pick Rust over Go (you can squeeze a lot of performance out of Go, and even optimizing Go is friendlier than writing naive Rust IMHO).
- kernelbandwidth 10y agoI think this might depend a lot on how you approach Rust. I find the functional/procedural mixture to work nicely, and find I'm much more productive in Rust than Go (or Python or Java, modulo available libraries). I'm writing web services and code generators, so not particularly low-level code. I've written a decent bit of Go, and I understand why a lot of people like it, but I don't think it's inherently better for application development.
- weberc2 10y agoMaybe, but I think your case is atypical. I came from a C++ background, so I'm well-acquainted with navigating a huge feature matrix and thinking about memory management, but I'm still much more productive in Go simply because the feature matrix is always very small and I only need to think about memory management in hot paths. I want to be comparatively productive in Rust, I just never seem to get there because of the huge volume of decisions (even if the decisions are mostly easy) that need to be made for even straightforward code units. I think what I really want is Rust lite, or Go with generics and abstract data types.
- kernelbandwidth 10y agoI could absolutely be atypical; prior to using Go and Rust as my main tools, I primarily wrote Scala, and I'm sure the functional and type-driven approaches have left deep grooves. But that would still be a way of approaching working with Rust, wouldn't it? None of that is to make a value judgement, just an observation; but I would still argue that the language can be used in a highly productive manner. Nonetheless, it's perfectly reasonable to argue it's not worth adapting to it, especially if Go is already solving your problems and keeping you productive. I switched because Go's design doesn't seem to fit me very well, and I continually tripped on issues that I don't encounter in Rust. (So yes, perhaps I'm quite odd.) I do understand the want for a Rust-lite; the thought has crossed my mind more than once. So far, Swift seems closest in many ways and may get close once the Linux/cross-platform story starts looking good.
- pimeys 10y ago> I could absolutely be atypical; prior to using Go and Rust as my main tools, I primarily wrote Scala. I'm not saying Rust is easy, but I have also a long Scala and some Haskell background which made it easier to learn Rust. For me the hardest part was that I've never really wrote any proper C++ or C, although I could read them quite good. Refereneces and RAII caused some gray hairs, the type system not that much.
- pimeys 10y ago
- pcwalton 10y ago> Go has the same distinction (stack vs heap) No, Go does not have that distinction. This is even in the Go FAQ: https://golang.org/doc/faq#stack_or_heap https://golang.org/doc/faq#stack_or_heap
- weberc2 10y agoYes, it does have the distinction. From your link: > When possible, the Go compilers will allocate variables that are local to a function in that function's stack frame. However, if the compiler cannot prove that the variable is not referenced after the function returns, then the compiler must allocate the variable on the garbage-collected heap to avoid dangling pointer errors. As you can see, Go uses both the stack and the heap; however, unlike Rust, it doesn't require users to know where their variables live to write correct programs.
- rigden33 10y agoI believe, the distinction that orclev mentioned was that in Rust, you specifically have to be aware when something is allocated to the stack or heap, but in Go, you don't have to since the compiler deals with it. Obviously Go allocates to both stack and heap, it's just that the user doesn't need to know which.
- weberc2 10y agoFair enough. I simply meant that Go's semantics let you reason about what lives on the stack vs what lives on the heap much like you can in Rust (though in Rust it's clearer still because there is no escape analysis at all). While you don't need to know from a correctness perspective, you can reliably reason about what will live on the stack vs heap in a way you can't in, say, Java.
- unscaled 10y agoNo, you can't really reason properly about what lives on the stack. As the Go FAQ say, you can safely assume a variable will be allocated on the stack if you never take a reference of it, but that's not always clear as it seems. For instance, if you call a method on your variable, you can't immediately know by looking at the method whether the receiver is by-reference (pointer receiver) or by value. If you're using a pointer receiver, the variable's address may be taken, so the compiler has to perform escape analysis. Once you take the address and escape analysis is performed, you've got no way to easily reason about what's on the stack vs. what's on the heap, without delving into the gory implementation details which may be changed in future versions. Since Go isn't C++ and doesn't have a huge and complicated standard that guarantees compiler optimizations, you can't really reason about what's going on. This is essentially the same situation as Java, although the Hotspot JVM's escape analysis is probably less 'basic'.
- joshuata 10y agoThat is one reason to choose Rust, but that is far from the only reason to prefer Rust over Go. I've found that algebraic data types and pattern matching have become irreplaceable parts of my programming toolbox, to the point it is painful to work without them. Rust also has a powerful macro system that Go cannot match. This is not to say that Rust is better than Go in every way, but performance is far from the only facet when I compare the two.
- civility 10y ago> The biggest hurdle people seem to have with Rust is that it makes you very aware of the difference between stack and heap allocated data. What do you base this belief on? I'm very comfortable with C and assembly. I am very certain I understand the difference between stack and heap allocated data, but I've found lots of other hurdles in learning Rust.
- solidsnack9000 10y agoWhat were the hurdles that you encountered? One difficult aspect of Rust relative to Go must surely be generics and trait bounds. This is something it shares with Haskell and Scala. For people coming from those languages (like myself) the stack/heap thing is the most salient.
- civility 10y ago> What were the hurdles that you encountered? > One difficult aspect of Rust relative to Go must surely be generics and trait bounds. Conceptually this isn't bad at all. I understand the value and mechanism of specifying the required traits for types to a generic function. However, I just posted an example elsewhere in this discussion where there simply isn't a trait for the method I want to call. That was certainly a hurdle for me, and the workaround wasn't satisfying. I mostly understand the semantics of borrowing mutable vs read-only references, and I'm pretty sure I understand the purpose and value of the concept. However, specifying lifetimes is completely different than any other language I've ever used, and I've used a couple dozen languages over several decades in my career. I haven't gotten past that hurdle yet. > the stack/heap thing is the most salient. I'll stick with my statement that I understand the stack and heap well enough (from a C or C++ point of view), but composing Box, Cell, Ref, RefCell, and friends is a non-trivial hurdle.
- orclev 10y agoTheoretically yes, for a C/Assembly programmer you're aware of the difference between stack and heap allocated data, BUT the cognitive load is different because those languages don't differentiate them in a particular fashion, it's all just pointers and offsets at the end of the day. Rust on the other hand, because of the Box type makes it very explicit where exactly some piece of data lives. It's also relatively uncommon to stack allocate any kind of larger structure in C or assembly, almost by default that kind of thing is done in the heap, where Rust makes it really trivial (default even) to do so on the stack even though that's rarely the correct decision. Depending on your background there probably are various hurdles to overcome in learning Rust, I'm not discounting that, but the most uniquely Rust one is the stack vs. heap issue, particularly since that combined with issues around shared state are the sources of most of the headaches you'll run into when fighting with the borrow checker. Pretty much every other feature of Rust is similar enough to another language that if you have experience elsewhere you won't find it particular troublesome. References are easy to understand if you know C/C++ (and to a lesser extent C#). The type system is easy to understand if you know Haskell or Scala (and to a lesser extent JavaScript/Python). The generics system is pretty much the same as Java, C#, Haskell, Scala, or C++ (and probably others). Rust IS a complex language, but it also provides a unique feature set and has some fairly unique goals. IF you need or desire the features Rust provides, pretty much ONLY Rust is going to get you what you want. C, C++, or Assembly potentially can deliver the same functionality, although it's questionable whether their ergonomics will be better or worse than Rusts for a given task, and they almost certainly will be more bug and error prone. Rust lets you have all the fine grained performance tweaking (or just plain low level access) you can get with C/C++/Assembly, while also giving a strong peace of mind that your code is correct and error free. It's also arguably easier than C++ although that comparison is a bit Apples and Oranges, C++ has a great many years of tweaking and experimenting behind it so things like Boost go a long way towards providing something like a most optimal (from a ergonomics standpoint) C++ experience that ignores all the languages pitfalls and sandtraps. Rust on the other hand has just barely hit 1.0 and the community hasn't even discussed, let alone come to any kind of consensus on the best way to tackle various issues yet. Rust will get there in time, but it's still early in the process and it shows. Bottom line, if you need the features Rust provides, but aren't comfortable with how young the language is and want more hand holding, C++ (or maybe C) is probably the language you want. This isn't to say Rust is a bad language or you shouldn't use it, I think learning and using a new language is reason enough and the certainty Rusts type system and borrow checker provide is a very strong argument in its favor, but you need to be aware of what you're signing up for when you make that decision.
- usrusr 10y ago> [...] Rust forces them to worry about allocations and cleaning up after themselves. C++ should have the same issue but its been around long enough that most of those details have safely been wrapped behind STL and other abstractions to the point where most people don't need to worry about them. Also, C/C++ comes with the venerable "kill the process GC" that makes it easy for beginners and other mortals to feel good about code even when it not strictly is good. Rust is all about making that kind of quality mandatory.
- moosingin3space 10y ago> Rust is all about making that kind of quality mandatory. This is why I think the best characterization of Rust is "an Anti-Sloppy Programming Language".