Cheating the Reaper in Go

https://news.ycombinator.com/rss Hits: 17
Summary

Even though I am a C++ programmer at heart, Go fascinates me for none of the reasons you think. Go has made several interesting design decisions: It has virtually no Undefined Behavior. It has very simple GC semantics that they’re mostly stuck with due to design decisions in the surface language. These things mean that despite Go having a GC, it’s possible to do manual memory management in pure Go and in cooperation with the GC (although without any help from the runtime package). To demonstrate this, we will be building an untyped, garbage-collected arena abstraction in Go which relies on several GC implementation details. I would never play this kind of game in Rust or C++, because LLVM is extremely intelligent and able to find all kinds of ways to break you over the course of frequent compiler upgrades. On the other hand, although Go does not promise any compatibility across versions for code that imports unsafe, in practice, two forces work against Go doing this: Go does not attempt to define what is and isn’t allowed: unsafe lacks any operational semantics. Go prioritizes not breaking the ecosystem; this allows to assume that Hyrum’s Law will protect certain observable behaviors of the runtime, from which we may infer what can or cannot break easily. This is in contrast to a high-performance native compiler like LLVM, which has a carefully defined boundary around all UB, allowing them to arbitrarily break programs that cross it (mostly) without fear of breaking the ecosystem. So, let’s dive in and cheat death. Our goal is to build an arena, which is a data structure for efficient allocation of memory that has the same lifetime. This reduces pressure on the general-purpose allocator by only requesting memory in large chunks and then freeing it all at once. For a comparison in Go, consider the following program: package main import "fmt" func main() { var s []int for i := range 1000 { prev := cap(s) s = append(s, i) if cap(s) != prev { fmt.Println(cap(s)) } } } T...

First seen: 2025-04-21 23:39

Last seen: 2025-04-22 15:41