Zig's new LinkedList API (it's time to learn fieldParentPtr)

New intrusive API and Zig’s design goals

  • New std linked lists are intrusive: user structs embed node fields and use @fieldParentPtr to recover the parent.
  • Several commenters say this matches Zig’s “low-level, explicit, data‑oriented” ethos and the community’s existing use of @fieldParentPtr (including for inheritance-like patterns).
  • Others feel it’s a “net negative” for higher-level application code, preferring generic, encapsulated containers with simpler APIs.

Type safety and @fieldParentPtr

  • Major thread around whether @fieldParentPtr is “typesafe”.
  • Consensus: it’s only partially safe. The compiler can check that the type has a field of that name and matching type, but cannot verify that the pointer actually came from that field; misusing it causes unchecked illegal behavior.
  • Example: passing a pointer to an unrelated i32 compiles but is illegal per the language reference.
  • This is seen as a serious footgun, especially now that std lists require it for iteration. Some note there are plans to make it safer, but not yet.

Generics, comptime, and functional-style APIs

  • Old list was generic SinglyLinkedList(T); new one is not.
  • People ask how to write reusable functions like map/filter or list-parameter APIs.
  • Answers: use comptime type parameters, pass field names as comptime []const u8, and operate imperatively with loops.
  • Some argue Zig intentionally discourages generic, functional-style abstractions (no closures, weak lambda ergonomics); others find “you just don’t” an unsatisfying answer and point out first-class functions do exist.

Performance and memory layout arguments

  • Pro-intrusive camp:
    • Fewer allocations when objects already exist; node is inside the object.
    • Better cache locality vs separate node allocations; easy to put the same object in multiple lists via multiple node fields.
    • Smaller code size because list APIs are no longer generic.
  • Skeptics counter:
    • The old generic list already embedded T in the node, so layout and allocation count were often identical.
    • Real performance win is mainly multi-list membership and some niche patterns; claims about “higher performance” lack concrete benchmarks.
    • Intrusive design couples data types to specific containers and can pollute structs with multiple node fields.

Use cases and prevalence of linked lists

  • One side: linked lists should be niche; arrays, vectors, and hashes are usually better on modern hardware (cache locality, simpler semantics).
  • Other side: they are widely used in kernels, event loops, allocators, schedulers, and other systems code (often intrusive), especially where allocations are constrained or objects live outside the container.
  • Several examples are given: OS kernels, network stacks, coroutines, wait-free / lock-free queues, LRU structures, allocator internals.

API ergonomics and abstraction

  • Some wish Zig exposed a typesafe generic wrapper atop the intrusive primitive, keeping @fieldParentPtr internal for most users.
  • Others argue Zig intentionally uses “friction” to steer people away from linked lists unless they really need them, and towards simple loops and more conventional containers.