5 ms·
The GC made sense in comparison to C style memory management. But with with Swift, Rust and modern C++ the argument can be made that GC doesn't bring anything t
by tjoff 4y ago
The GC made sense in comparison to C style memory management. But with with Swift, Rust and modern C++ the argument can be made that GC doesn't bring anything to the table.
In the beginning the biggest drawback seemed to be performance, so people have been hell-bent on fixing that for decades now. Completely ignoring that the "don't need to care about memory" mindset is flawed. You always need to think about memory, and if you do you might as well do it yourself. It doesn't take more time to do in the long run and you are forced to design a better system because of it.
For scripts it is a really nice have. But for a proper language writing large-scale applications? No thanks.
- zozbot234 4y ago> But with with Swift, Rust and modern C++ the argument can be made that GC doesn't bring anything to the table. GC will always be needed to solve problems dealing with general graphs containing possible cycles. Not coincidentally, this describes many of the GOFAI problems for which GC (in the context of LISP) was first developed.
- ninkendo 4y agoI mean, what you’re saying is probably technically true for very specific problems that are contrived specifically to show shortcomings in refcounting, but in practice I’ve never seen it matter. Weak and unowned pointers are pretty simple to deal with, and I’ve never seen a situation where it’s really confusing whether a pointer should be strong or weak in swift. Everything mostly just works, and if you need to point back to the object that owns you, it’s usually pretty clear by the abstraction you’re building that you need a weak/unowned reference to do it.
- deleted 4y ago[deleted]
- zozbot234 4y ago> and if you need to point back to the object that owns you That's not the interesting case; that is indeed easily addressed by "weak" pointers. What's interesting is the case of a spaghetti reference graph where none of the objects definitely "owns" any other, and even the choice of GC roots might be dynamic.
- ninkendo 4y agoThe specific point I’m making is that the “interesting case” is rare. Rare enough that I’ve never seen it in person.
- xigoi 4y ago> But with with Swift, Rust and modern C++ the argument can be made that GC doesn't bring anything to the table. With Rust and C++ (don't know about Swift), you still have to spend a lot of time thinking about memory.
- zozbot234 4y ago> With Rust and C++ (don't know about Swift), you s still have to spend a lot of time thinking about memory. You don't think about memory, you just think about how to ensure that you're always referencing live objects. And you need that kind of thinking anyway to deal with non-memory resources, where a GC won't help you at all.
- tptacek 4y ago"You can't garbage collect file descriptors" is a very weak argument.
- tjoff 4y agoMy argument is that you always need to think about memory - even in GC languages. Being able to not think about memory is not a feature, it is a problem.
- xigoi 4y agoWhy? It's a low-level implementation detail. Should you also always think about registers and jumps?
- pjmlp 4y agoSwift is a GC language, reference counting is a GC algorithm as per CS literature. Modern C++ unfortunely still has too much people writing classical C with classes, to make it properly safe. Rust, yes, affine types are great, but their usability is only justified in scenarios where having any kind of automatic memory management isn't acceptable.
- kaba0 4y ago> But with with Swift, Rust and modern C++ the argument can be made that GC doesn't bring anything to the table. Well, it would be a bad argument :D A reference counter is arguably the slowest option, so Swift is out of the picture (besides it leaks circular dependencies). Rust is a good idea, but it is a tradeoff. Quite a lot of programs can’t be expressed with strictly tree-like lifecycles, and then you are either left with the yet again slower (A)RC, or unsafe. C++ is in pretty similar shoes. They are good for the niche they were made, systems/low-level programming. Let me quote from the Garbage collector handbook: “above all, memory management is a software engineering issue. Well-designed programs are built from components [..] that are highly cohesive and loosely coupled. [..] modules should not have to know the rules of the memory management game played by other modules. [..] GC uncouples the problem of memory management from interfaces.” It says nothing about not thinking about memory, you are free to optimize it where you need it. EDIT: Oh and dynamic allocation is much faster with a modern GC than with malloc and friends, plus a moving GC can defragment heap.
- zozbot234 4y ago> A reference counter is arguably the slowest option, so Swift is out of the picture It's not that simple. Obligate refcounting has lower throughput than obligate tracing GC but offsets that with more predictable latency, which might be good for the Swift use case. Rust uses a mix of stack-based allocation, manual heap allocation and RC - and the RC only needs to manage "owners" as determined via the borrowck, as opposed to ephemeral references. So is way more efficient than something like Swift ARC, where refcounting is essentially ubiquitous and any operations via references will incur slow atomic RC updates.
- kaba0 4y agoWell, ever seen a C++ program that seemingly finished execution, but still haven’t exited? That’s shared pointers recursively freeing up their reference trees. There is a great paper showing that RC tracks object death, while tracing GCs track object “liveness”, so its essentially two sides of the same coin. As for RC, sure, at compile time many of the work can be omitted, but atomic writes needed for the counters are fundamentally slow operations on modern architectures.
- amelius 4y ago> The GC made sense in comparison to C style memory management. But with with Swift, Rust and modern C++ the argument can be made that GC doesn't bring anything to the table. Haskell needs a GC too. You can't do ergonomic functional programming without GC (it has been attempted).
- zozbot234 4y agoHaskell needs a GC because it can't figure out whether a closure might outlive any of the variables it references. This can be addressed by a Rust-like borrow checker. (In the rare general case where multiple independent pieces of code need to keep some object alive, this can be done via refcounting which of course is a kind of GC.)
- amelius 4y agoType based memory management has been done in FP languages. The point is that it completely breaks the experience.
- deleted 4y ago[deleted]
- efficax 4y agogc makes it easier to conceive of and program algorithms that use cyclical graphs, a pretty broad problem. try and implement these structures in rust and you quickly run into headaches. solveable headaches but headaches all the same. they’re trivial in a gc language