As someone who came to Zig from high-level, memory-managed languages (mostly Python and Bash), Zig and its community made it surprisingly easy for me to become familiar (and fall in love) with managing own memory. One thing I find hard to wrap my head around is that I see tendency of “softly” distinguishing between arena allocators and general allocators.
As I understand it, in theory there is an infinite amount of possible memory allocation strategies, and the main (or most obvious) feature of Zig’s favorite std.mem.Allocator interface is to allow code that is not strictly dependent on details of memory allocation.
But then I’m confused when people write code like this:
fn append(self: *Foo, gpa: std.mem.Allocator, thing: Thing) !void {
// ...
}
or
fn append(self: *Foo, arena: std.mem.Allocator, thing: Thing) !void {
// ...
}
where it’s assumed that using different name for the allocator implies usage pattern of the allocator.
I find myself asking, what exactly is being communicated here? Naively, it means “use arena allocator” but that somehow does not really answer enough.
There are two assumptions that I hold right now that seem to clash with this pattern:
-
Allocation strategy should be “per type”, ie. a type can require, or support certain allocation strategy.
Then for me it feels weird that the pattern can technically be applied inconsistently across the type, eg. a data structure with multiple (de)allocating methods could say
gpain one method andarenain another, while clearly a poor design style, it would not be trivial to prove that. -
There’s an infinite amount of possible strategies.
But whenever I see this pattern I only see it with
gpaandarena. Is there an assumption that “arena” and “general” are fundamentally special categories that will always exist?For example if a library needed a specific allocation strategy “quux”, would the idiomatic way to write API be
fn append(self: Foo, quux: std.mem.Allocator, thing: Thing)or would any strategy necessarily fit into the wider category “gpa” or “arena”? If the latter, isn’t there a better way of naming these categories?
I suspect that these “clashes” are mostly due to my weak understanding of the pattern (and overview of the problem space), so please correct my misconceptions and/or point me to some resources on this.