7 ms·
This comment is just bad and misinformed all over. (1) Automatic Reference Counting doesn't work; its equivalent in interpreted languages is, well, reference c
by tomp 8y ago
This comment is just bad and misinformed all over.
(1) Automatic Reference Counting doesn't work; its equivalent in interpreted languages is, well, reference counting, which can be optimized quite a lot (though has some issues with multithreading), but cannot collect cycles.
(2) therefore, if you want reference counting, you have to either also have GC (for cycles), or program carefully to avoid creating cycles (which is then only marginally better than C++)
(3) your comment on Python vs Perl5 is just nonsense, Python uses reference counting as well (along with the occasional GC to collect cycles)
(4) linear / uniqueness types (not exactly the same, but both can be used to ensure safe memory management) impose significant mental overhead on programmers as they prohibit many common patterns
(5) Rust features a lot of "cheating" - pointers that allow mutation from multiple threads, reference-counted pointers, etc. - so obviously just ownership&borrowing isn't good enough
conclusion: you can't have your cake and eat it too (at least according to current cutting edge research and implementations) - you either have GC or you have to be very careful/restricted when writing code
- StreamBright 8y agoIt is weird, I do not feel restricted when I write non-GC code. Btw. you still need to pay attention with GCd languages no to leak references that cannot be GCd. Java has this sort of problems. Rust made it easy and simple to deal with memory in a non-malloc level while not having GC. Erlang on the other hand has a VM that makes GC much faster than in other languages. I can live with that because if you do it right it does not impact end user latency. For me both Rust and Erlang gives the cake + eat it feeling.
- jerf 8y ago"I can live with that because if you do it right it does not impact end user latency." The vast majority of GC use does not impact end user latency. Thinking otherwise is either the availability heuristic at work, or you work in AAA videogames or another ultra-high-real-time-performance industry and don't realize you're not in the center of programming work, you're on an extreme. (A perfectly valid and sizeable extreme.) This may also be why you don't feel restricted; if you happen to work in any of the many places where a tree of references is adequate, you'll find Rust-style management to be a treat. If you work pervasively with graph structures in the core of your program, though, the experience can change. Pervasively-graph-type-structures are generally just a question of how you want your automated garbage collection to work, because I'm pretty sure getting the manual management correct otherwise is effectively impossible without an algorithm that's going to look a lot like a GC. That said, despite my disagreement, I also disagree with the people who, as of this writing, have downvoted your comment into grey. I feel like I've been seeing a burst of "downvote as disagreement" in the past couple of weeks.
- MrEldritch 8y ago"Downvote as disagreement" is such a pervasive pattern that I Find myself doing it automatically even when I know that's not what downvote is "supposed" to be for. I suspect it's because I'm more likely to view posts that I disagree with as being poorly thought-out. This even extends to platforms where downvoting is not a thing - witness 4chan's struggles with "sage is not a downvote" ("sage" being a function which allowed you to reply to a thread without bumping it to the top and extending its lifespan - again, intended to mark a thread as low qualit) until they finally gave up and made saging invisible. Given how thoroughly inescapable downvoting-to-disagree seems, I wonder if it might not be better to just declare defeat, allow downvotes and upvotes to mean nothing beyond a signal of protest or agreement, and have a separate "this comment is low quality / this comment is high quality" buttons.
- wglb 8y agoPG long ago said that it is ok to use downvotes (in part) to signal disagreement.
- coldtea 8y ago>It is weird, I do not feel restricted when I write non-GC code. Some people don't feel C has any safety issues either -- perhaps they think all others are idiots and their code is mistake proof because they do it right.
- apta 8y ago> still need to pay attention with GCd languages no to leak references that cannot be GCd. Java has this sort of problems. Unless you're doing weird things with class loaders, this is a non-issue. > Erlang on the other hand has a VM that makes GC much faster than in other languages What makes Erlang's VM make GC faster than other languages?
- geocar 8y agoThat's a very loaded question. I don't think it's easy to point to one thing Erlang is doing and say that is why it's faster, partly because I think the way Erlang programmers are encouraged to write their programs also has an effect; The language itself may have a greater effect on its GC performance than the GC implementation itself. As an example: In Erlang, we have function calls like F(X) but we also have message sends like F!X. Message sends get one type of memory treatment, while function calls get another one. The lifetime of objects you send via messaging is going to be different, and yet Java only has function(method) calls, so there's no way to hint this to Java. Maybe this information can be recovered with static/dynamic analysis, but in Erlang we have syntax to tell the VM what's going to happen. If you want to learn more about Erlang's internals, I can recommend Joe's original paper on the subject: http://citeseerx.ist.psu.edu/viewdoc/summary;jsessionid=0397570F246B379399EB5A3FDDFF2C5E?doi=10.1.1.42.7791 http://citeseerx.ist.psu.edu/viewdoc/summary;jsessionid=0397... since it describes a lot of the design that went into Erlang early, and: http://www.it.uu.se/research/publications/lic/2005-001/ http://www.it.uu.se/research/publications/lic/2005-001/ which while long, quite in-depth describes many of the sub-optimisations that can be realised on top of it.
- apta 8y agoThanks for the links. That being said, new developments in GCs on the JVM (like Shenandoah and ZGC) are yielding very impressive results. Things like < 1ms pause times for heaps in the TB range. No other free GC for any other language approaches this as far as I'm aware, including golang's which people claim is fast, but completely gets destroyed for even heaps in the GB range (I did some benchmarks).
- blub 8y agoYou came in guns blazing and then covered yourself in embarrassment already in the first two points you made. The thing you said doesn't work is in use on millions of devices, working just fine. Or maybe you'd like to be more precise than "work". Avoiding cycles and thinking about ownership is not programming carefully, it's merely programming. Really, manual memory management is not rocket science folks, just error prone. And RAII is reliable to the point that anyone that is capable of writing software can wield it.
- coldtea 8y ago>Really, manual memory management is not rocket science folks, just error prone Doesn't have to be rocket science to be a cognitive burden. And we want to eliminate "error prone" factors...
- blub 8y agoAnd we did eliminate them. But no one can seriously claim that GC is a magic bullet, because it's only clearly winning against plain C. Carefully designed, popular languages are choosing RAII and reference counting implementations and those are very competitive.
- mcguire 8y ago? C++ and Objective C inherited C's memory model and thus don't have a good memory management option. Rust is explicitly a systems language, meaning stronger memory models are out of scope, and then inherited most of C++'s idioms. Other than those, what popular languages are specifically choosing reference counting as a primary GC method?
- steveklabnik 8y agoSwift.
- mcguire 8y ago
- deleted 8y ago[deleted]
- pedrocr 8y ago>Rust features a lot of "cheating" - pointers that allow mutation from multiple threads You're confounding GC and synchronization of multi-threaded access here. What rust does with things like Arc other languages will need some other synchronization primitive to enable. Their GC or manual memory management does not guarantee the multi-threaded semantics. That's one of the advantages of the rust memory model, some patterns become multi-threaded without extra primitives (read-only borrows) and all of the primitives are compile-time checked for correctness. >reference-counted pointers, etc. - so obviously just ownership&borrowing isn't good enough In practice ownership and borrowing gets you a long way. I've only had to use a reference counted primitive (Arc) when that was the exactly correct semantics. I had a cache and both the caller and the original owner could drop the value first based on external input. No other static decision can be made and the ergonomics of writing that are very good. Rust seems already quite a bit better than having to be "very careful/restricted when writing code".
- tomp 8y agoNo, Rust is conflating memory safery and multithreading safety. JVM state-of-the-art GC guarantees multithreaded memory safety. AFAIK many wait-free data structures are pretty much impossible without a GC.
- pedrocr 8y agoYou start your response with "No" but don't actually argue against anything I've said. > Rust is conflating memory safery and multithreading safety. Rust doesn't conflate anything. It just gets some multi-threading safety for free as a result of its memory model. And then gets quite a few other multi-threading safety characteristics that no other mainstream language has from the type system. That several features in the language work together well is just a sign of good design. > JVM state-of-the-art GC guarantees multithreaded memory safety. This is where you're mixing the two unrelated concepts. Garbage collection does nothing for multi-threading safety. While the object is live and two threads hold a reference to it you need to synchronize access somehow. GC can't do anything about that. > AFAIK many wait-free data structures are pretty much impossible without a GC. This is unrelated to the previous points I made but isn't true either: https://aturon.github.io/blog/2015/08/27/epoch/ https://aturon.github.io/blog/2015/08/27/epoch/
- cyphar 8y ago> (1) Automatic Reference Counting doesn't work; its equivalent in interpreted languages is, well, reference counting, which can be optimized quite a lot (though has some issues with multithreading), but cannot collect cycles. This is what weakrefs (or better data structures) are for. The Linux kernel uses reference counting incredibly effectively for almost every structure. I think that pretty much discounts any argument that reference counting cannot work. > (5) Rust features a lot of "cheating" - pointers that allow mutation from multiple threads, reference-counted pointers, etc. - so obviously just ownership&borrowing isn't good enough "unsafe" isn't cheating and isn't even related to whether garbage collection is a good idea or not. Yes, Rust's ownership and borrowing model doesn't cover all programs and hence "unsafe" is required -- but "unsafe" doesn't use a garbage collector so the existence of "unsafe" doesn't change that Rust works without one.
- apta 8y agoI think the poster to whom you're responding means things like Cell and/or RefCell, which allow mutation behind the scenes while still being safe.
- cyphar 8y agoRight, but I think their main complaint is that RefCell is implemented using "unsafe" -- hence my point about "unsafe".
- apta 8y agoIt's API is not `unsafe` though. Otherwise, every safe API depends on some `unsafe` call down the call graph.
- cyphar 8y agoI think we're both in agreement, I was phrasing things in a manner which I thought would better reference how GP thinks of unsafe. Obviously the API itself is safe, but the "cheating" GP was referring to was the fact that Rust requires "unsafe" under the hood in order to implement some safe operations (because the memory model doesn't cover all cases). You and I agree that this isn't a problem.
- lmm 8y ago> (4) linear / uniqueness types (not exactly the same, but both can be used to ensure safe memory management) impose significant mental overhead on programmers as they prohibit many common patterns Such as? I've found that linear style is generally just good coding style. When I get caught up on something I can't express linearly, it generally means I was trying to plough through with a dodgy approach; stopping and thinking through would have resulted in better code even in a GCed language.
- dang 7y agoPlease don't call names in arguments here. Your first sentence is clearly against the site guidelines, and was quite unnecessary. https://news.ycombinator.com/newsguidelines.html https://news.ycombinator.com/newsguidelines.html
- geocar 7y ago(1/2): It most certainly does work: q/kdb is an interpreted language and doesn't have cycles. Being an array language, nesting is uncommon, so chasing pointers isn't an issue either. (3): I didn't say otherwise Python doesn't also do reference counting. Python however does have a bytecode and a GC, and perl5 does not and executes the AST directly. And yes perl5 is faster for many problems[†]. I think it's quite common that people believe that GC and bytecode are a win, and this is a simple and accessible example where it is not true. (4): More significant than what? q/kdb is implemented in this style, and it's a huge advantage (reducing bugs) having your library handle allocation/deallocation over having the caller do these things so I tend to do it as well. What exactly are you comparing it to? The mental load of figuring out what's causing pauses is quite high since it requires considering the entire program, but linear programming is very easy and it obviates a lot of need for other kinds of memory management techniques. (5): Good enough for what? Why is mixing static analysis with runtime analysis "cheating"? What would be "fair" in your mind? [†]: https://benchmarksgame-team.pages.debian.net/benchmarksgame/faster/perl.html https://benchmarksgame-team.pages.debian.net/benchmarksgame/...