7 ms·
> And who likes doing this to themselves anyway? Isn't it a very frustrating experience? How is this the most loved language? The thing is, these dependencies
by ghosty141 3y ago
> And who likes doing this to themselves anyway? Isn't it a very frustrating experience? How is this the most loved language?
The thing is, these dependencies do exist no matter what language you use if they stem from an underlying concept. In that case rust just makes you explicitly write them which is a good thing since in C++ all these dependencies would be more or less implicit and everytime somebody edits the code he needs to think all these cases through and get a mental model (if he sees it at all!). In Rust you at least have the lifetime annotations which make it A: obvious there is some special dependency going on and B: show the explicit lifetimes etc.
So what I'm saying, you need to put in this work no matter which language you choose, writing it down is then not a big problem anymore. If you don't think about these rules your program will probably work most of the time but only most of the time, and that can be very bad for certain scenarios.
- throw10920 3y ago> So what I'm saying, you need to put in this work no matter which language you choose This is very false. Managed-memory languages don't require you to even think about lifetimes, let alone write them down. Yes, I understand that this is for efficiency - but claiming that you have to think about lifetimes everywhere is just wrong, and irrelevant when discussing topics (prototyping/design work/scripting) where you don't care about efficiency.
- jjnoakes 3y agoLifetimes are still important in managed languages. You just have to track them in your head, which is fallible. The difference is that if you get it wrong in a managed language, you get leaks or stale objects or other logic bugs. In rust you get compile time errors.
- throw10920 3y ago> The difference is that if you get it wrong in a managed language, you get leaks or stale objects or other logic bugs. Can you provide concrete examples of this? I've literally never had a bug due to the nature of a memory-managed language.
- OvermindDL1 3y agoCMEs in Java are a constant thorn to many Java programmers as a lifetime violation bug. Hell even NPEs are too for that matter, lol.
- astrange 3y agoYou can certainly get memory abandonment, which is like a leak but for memory that's still referenced and is just never going to be used again.
- tsimionescu 3y agoI will note that in GC literature at least, that is still considered a leak. In an ideal world, we could have a GC that reclaimed all unused memory, but that turns out to be impossible because of the halting problem. So, we settle for GCs that reclaim only unreachable memory, which is a strict subset of unused memory. Unused reachable memory is a leak.
- zdragnar 3y agoOnce upon a time (at least through IE7) Internet Explorer had separate memory managers for javascript and the DOM. If there was a cycle between a JS object and a DOM object (a DOM node is assigned as a property of an object, and another property was assigned as an event handler to the DOM node) then IE couldn't reclaim the memory. Developers of anything resembling complex scripts (for the time) had to manually break these cycles by setting to null the attributes of the DOM node that had references to any JS objects. Douglas Crockford has a little writeup here[0] with a heavy-handed solution, but it was better than doing it by hand if you were worried another developer would come along and add something and forget to remove it. Other memory managed languages also have to deal with the occasional sharp corners. Most of the time, this can be avoided by knowing to clean up resources properly, but some are easier to fall for than others. Oracle has a write up on hunting Java memory leaks [1] Microsoft has a similar, but less detailed article here[2] Of course, sometimes a "leak" is really a feature. One notorious example is variable shadowing in the bad old days of JS prior to the advent of strict mode. I forget the name of the company, but someone's launch was ruined because a variable referencing a shopping cart wasn't declared with `var` and was treated as a global variable, causing concurrent viewers to accidentally get other user's shopping cart data as node runs in a single main thread, and concurrency was handled only by node's event loop. [0] https://www.crockford.com/javascript/memory/leak.html https://www.crockford.com/javascript/memory/leak.html [1] https://docs.oracle.com/en/java/javase/17/troubleshoot/troubleshooting-memory-leaks.html https://docs.oracle.com/en/java/javase/17/troubleshoot/troub... [2] https://learn.microsoft.com/en-us/dotnet/core/diagnostics/debug-memory-leak https://learn.microsoft.com/en-us/dotnet/core/diagnostics/de...
- nine_k 3y agoWhile this is correct, it's still much easier to think about lifetimes in managed languages. The huge majority of allocated objects gets garbage-collected after a very short time, when they leave the context (similar to RAII). Mostly you need to think about large and/or important objects, and avoid cycles, and avoid unneeded references to such objects that would live for too long. Such cases are few. The silver lining is that if you make a mistake and a large object would have to live slightly longer, you won't have to wrangle with the lifetime checker for that small sliver of lifetime. But if you make a big mistake, nothing will warn you about a memory leak, before the prod monitoring does.
- pkolaczk 3y ago> The huge majority of allocated objects gets garbage-collected after a very short time, when they leave the context (similar to RAII). Those objects are also virtually no problem in languages like Rust or C++. Those are local objects whose lifetimes are trivial and they are managed automatically with no additional effort from the developer.
- pkolaczk 3y ago> Managed-memory languages don't require you to even think about lifetimes, let alone write them down. Memory is only one of many types of resources applications use. Memory-managed languages do nothing to help you with those resources, and effectively managing those resources is way harder in those languages than in Rust or C++.
- throw10920 3y agoWhat? Rust doesn't do anything to "help you with those resources", either - you can still create cycles in ARC objects or allocate huge amounts of memory and then forget about it. In both languages you have to rely on careful design, and then profile memory use and manage it. However, Rust requires you to additionally reason about lifetimes explicitly. Again - great for performance, terrible for design, prototyping, and tools in non-resource-constrained environments*.
- Galanwe 3y ago> The thing is, these dependencies do exist no matter what language you use Sure, but in a lot of cases, these invariants can be trivially explained, or intuitive enough that it wouldn't even need explanation. While in Rust, you can easily spend a full day just explaining it to the compiler. I remember spending litteral _days_ tweaking intricate lifetimes and scopes just to promise Rust that some variables won't be used _after_ a thread finishes. Some things I even never managed to be able to express in Rust, even if trivial in C, so I just rely on having a C core library for the hot path, and use it from Rust. Overall, performance sensitive lifetime and memory management in Rust (especially in multithreaded contexts) often comes down to: 1) Do it in _sane_ Rust, and copy everything all over the place, use fancy smart pointers, etc. 2) Do it in a performant manner, without useless copies, without over the top memory management, but prepare a week of frustrating development and a PhD in Rust idiosyncrasies.
- efficax 3y ago> Some things I even never managed to be able to express in Rust, even if trivial in C, so I just rely on having a C core library for the hot path, and use it from Rust. i can’t think of anything you can do in c that you can’t do in unsafe rust, and that has the advantage that you can both narrow it down to exactly where you need it and only there, and your can test it in miri to find bugs
- Galanwe 3y ago> i can’t think of anything you can do in c that you can’t do in unsafe rust That is not my point. There is a world between "you can do it" and "you will do it". Some things in Rust are doable in theory, but end up being so insane to implement that you won't do it in practice. That is my point.
- LegionMammal978 3y agoTo be fair, unsafe Rust has an entirely new set of idiosyncrasies that you have to learn for your code not to cause UB. Most of them revolve around the many ways in which using references can invalidate raw pointers, and using raw pointers can invalidate references, something that simply doesn't exist in C apart from the rarely-used restrict qualifier. (In particular, it's very easy to inadvertently trigger the footgun of converting a pointer to a reference, then back to a pointer, so that using the original pointer again can invalidate the new pointer.) Extremely pointer-heavy code is entirely possible in unsafe Rust, but often it's far more difficult to correctly express what you want compared to C. With that in mind, a tightly-scoped core library in C can make a lot of sense; more lines of unsafe code in either language leave more room for bugs to slip in.