4 ms·
Weak pointers in Go: why they matter now
- Attummm 2y agoGreat in-depth article, unveiling a lower level of Golang previously unknown to me.
- stevugnin 2y agoHow to shoot yourself in the foot
- SwiftyBug 2y agoIn the end of the article the author addresses some of the pitfalls of using weak pointers. You'll only shoot yourself in the foot if you don't fundamentally understand weak pointers and why you're using them in the first place.
- usrnm 2y ago"It's only a problem when programmers make mistakes". Gee, I wonder where I've heard it before
- sethops1 2y agoI lost track of the number of WeakReference bugs I've had to fix in a legacy Java codebase. Not looking forward to doing the same in Go.
- sapiogram 2y agoAs someone who has never used weak references in either language, what are the common pitfalls in practical usage?
- sethops1 2y agoThe most common is if you create a reference to a field of a struct that is itself weak. The GC will gc the struct and your var can go from non-nil to nil under the hood despite having zero concurrent code (that you wrote). The good news is the vast majority of code using Weak semantics is gratuitous - "clever" code that is actually broken premature optimization, and the fix is to just Don't Do That.
- masklinn 2y agoAFAIK the biggest issue is the nondeterminism ("inconsistency"), especially in languages which have a weaker type system and make upgrading easy (which is the case of both Go and Java) - you need to remember to check the result for nil/null, but the type system won't tell you - if you upgrade twice in a row, you can have both fail, both succeed, or the first one succeed and the second one fail It can also be tricky to use them as building blocks for weak collections, if you want to avoid unbounded growth.
- jbverschoor 2y agoWhy? You just have to understand how they work, and it’s not like they’re invisible.
- sethops1 2y agoYou could make the same argument about writing in C/C++ and managing memory. You just have to understand how it works, right?
- cube2222 2y agoIt’s still memory-safe, so not that big of a gun.
- gf000 2y agoUnlike the language, which can segfault on race conditions with e.g. maps..
- pdimitar 2y agoDon't forget panics on sending to closed channels. /facepalm
- 0x696C6961 2y agoGo is considered a memory safe language.
- judofyr 2y agoGo without concurrency is fully memory safe. However, once you start using goroutines there can be memory corruption and segfaults: https://github.com/golang/go/issues/37484 https://github.com/golang/go/issues/37484. Note that these are not recoverable panics (such as "writing to a close channel"), but causes completely arbitrary behavior: runtime: pointer 0xc00379ac60 to unused region of span span.base()=0xc001794000 span.limit=0xc001795e00 span.state=1 fatal error: found bad pointer in Go heap (incorrect use of unsafe or cgo?) runtime: nelems=8 nalloc=5 previous allocCount=4 nfreed=65535 fatal error: sweep increased allocation count
- mananaysiempre 2y agoSome things are plain unimplementable in a nonleaky way without weak pointers (or even something stronger like ephemerons[1,2] or weak maps or the like), so at some point you have to face the music. Event / observer / dependency-graph / reactivity systems are one cluster of those. [1] https://wingolog.org/archives/2022/10/31/ephemerons-and-finalizers https://wingolog.org/archives/2022/10/31/ephemerons-and-fina... [2] http://lists.squeakfoundation.org/pipermail/squeak-dev/2022-June/220899.html http://lists.squeakfoundation.org/pipermail/squeak-dev/2022-...
- aatd86 2y agoHow do they intervene in the reactivity? Genuinely curious as I have implemented one such system in Go. Maybe I could improve in some stuff. I did use some kind of weakreference substitute (using an integer map) but that was because I was lacking a feature (some kind of dependent type).
- mananaysiempre 2y agoI guess that wouldn’t be necessary if your dependency graph is static, but if dependencies can themselves change during change propagation, you do need weak references. Imagine input A affects node B affects output C. Then you probably want B to be collected if C becomes garbage. So the strong references need to go C→B→A. But the way a simple push strategy would actually proceed if A changes would be that A triggers a reevaluation of B, which then triggers a reevaluation of C. But A could be either immortal for semantic reasons (e.g. “the left mouse button was clicked” can’t really become garbage) or perhaps kept alive by some entirely unrelated dependent D. So A needs to be able to refer to B if it’s still alive but must not hold B alive, and similarly for the edge between B and C. The way to deal with this is to have store dependents in a weak set. (I don’t actually see how to implement one with plain weak references without finalizers.) Alternatively, just give up and say the dependency graph needs to be specified up front and only dies as a whole. My own dependency-graph/reactivity thing is not ready to see the light of day, so if you want some references I guess I can direct you to the author of the Sodium FRP library (not to be confused with the libsodium crypto library) and an FRP book mentioning[1] he implemented a cycle collector as a workaround for the lack of weak references in JavaScript (at the time). [1] https://web.archive.org/web/20240507181526/http://sodium.nz/t/sodium-internals-and-differences-between-language-implementations/464 https://web.archive.org/web/20240507181526/http://sodium.nz/...
- lolive 2y agoIs that WeakReference in Java?
- pwdisswordfishz 2y agoYes.
- masklinn 2y agoJava and most(*) other GC'd languages yes. (*) though not all e.g. I think lua doesn't have straight up weakrefs, though tables can be made weak in key or value.
- njtransit 2y agoThe article doesn’t actually explain how they work… How does the indirect pointer get set to nil? Does it use runtime.SetFinalizer?
- usrnm 2y agohttps://cs.opensource.google/go/go/+/refs/tags/go1.23.4:src/internal/weak/pointer.go;l=62 https://cs.opensource.google/go/go/+/refs/tags/go1.23.4:src/... https://cs.opensource.google/go/go/+/master:src/runtime/mheap.go;l=2068 https://cs.opensource.google/go/go/+/master:src/runtime/mhea... Looks like most of it is implemented directly in the runtime.
- binary132 2y agoPeople imagining that “adding the missing features” is what Go needs should be paddled.
- pwdisswordfishz 2y agoWell, good news, it's not a new feature at all: > Interestingly, it used to be more of an internal tool, but recently there’s been a push to make it public I think your anti-intellectual bubble should be safe.
- binary132 2y agoI’ve left Go behind for some years now. I wish them all the best, but I do not approve.
- welder 2y agoAlso have to watch out for nil pointer dereferencing: https://wakatime.com/blog/48-go-desperately-needs-nil-safe-types https://wakatime.com/blog/48-go-desperately-needs-nil-safe-t...
- deleted 2y ago[deleted]