Function in a weird place. Normal practice is for the specific implementations to have a getLogger function to create the logger. For example, the allocators in Zig have you instantiate the top level and then call .allocator() on them to get the vtable + pointer to self.
It manages sanity a lot better, and the function implementations in the vtable can be private.
I did it this way so that the implementation doesn't need to know about the interface at all. The programmers can string the interface and implementation together with,
const intf = interface.implBy(implementation)
This makes it possible to write an interface against any implementation objects. E.g. I can write an interface against the standard hashmap's get() and put() methods. Why would I do that? Let's say I have my custom hashmap with get() and put(), but I want to use the standard hashmap as fallback. A common interface working against my custom hashmap and the standard hashamp is possible.
Would it truly kill Zig to add native interface support ? All that ceremony is quite heavy and also somewhat error prone.
If nothing else, maybe they can add some helpers in the standard lib or codegen in the standard tooling to make stuff like this easier ? So one need not manually code all the function pointer types for methods and the dispatch in the interface type .
Yes, Zig is meant to be a low-level programming language, but stuff like this is basic table stakes nowadays. People will just make custom code generators after Zig 1.0 to do this exact thing - and they will likely be dozens of such custom code generators with subtle differences.
Even Ada, Modula-2, Object Pascal eventually got them.
Zig is trying to fix C, by delivering stuff already present in Modula-2, minus comptime, in a C like clothing.
The judge is still out there if it will become something unavoidable in some industry circles, or just yet another programming language to talk about.
From my point of view, being stuck in the past of systems languages design, during the AI age where the actual language becomes slowly irrelevant, it will mean the latter.
I think it will turn out that even for AI some language will be much more easily to code systems in than others. We maybe even get languages optimized for this in due time. So I'm not at all on board with languages becoming irrelevant with AI age. I can even see it happening that extreme typing like lean will be best. Sure it will probably take more compute to design a system using it, but that may be offset by the additional mistakes it prevents. No company likes to code in lean, since you require highly skilled people and it takes ages. But AI can defeat both of those while still getting the advantages.
I don’t find the lack of built-in interface in Zig to be a big problem. Yes. It has some boilerplates to roll in by hand, but all of the work are confined in the interface and only required to be done once.
The benefits of the language outweigh the minor inconvenience.
This is like the inverse of the normal C++ vtable. Normally the whole point of having a separate vtable (as opposed to just a bunch of function pointers directly in the struct) is so that you can share a single one between all instances, at the cost of one extra indirection. But here a copy of the vtable is instead attached to one individual instance, and yet it still does this one extra indirection to get to the implementation object.
The extra indirection is a reasonable tradeoff in Zig because it enables heterogeneous collections of implementations while maintaining type safety without requiring inheritance.
The first version is faster (one pointer indirection) with more memory consumed. The second version is more memory efficient sharing a single vtable for all instances, a bit slower (two pointer indirections).
14 comments
[ 574 ms ] story [ 3708 ms ] threadAnd using vtable in code feels cleaner compared to using generics
pub fn implBy(impl_obj: anytype) Logger
Function in a weird place. Normal practice is for the specific implementations to have a getLogger function to create the logger. For example, the allocators in Zig have you instantiate the top level and then call .allocator() on them to get the vtable + pointer to self.
It manages sanity a lot better, and the function implementations in the vtable can be private.
If nothing else, maybe they can add some helpers in the standard lib or codegen in the standard tooling to make stuff like this easier ? So one need not manually code all the function pointer types for methods and the dispatch in the interface type .
Yes, Zig is meant to be a low-level programming language, but stuff like this is basic table stakes nowadays. People will just make custom code generators after Zig 1.0 to do this exact thing - and they will likely be dozens of such custom code generators with subtle differences.
I think it is table stakes for higher level programming language. Zig wants to be somewhat like high level assembly.
There is still someway to go before 1.0 so may be something will be done. I mean I am still uneasy with them focusing so much on async.
Zig is trying to fix C, by delivering stuff already present in Modula-2, minus comptime, in a C like clothing.
The judge is still out there if it will become something unavoidable in some industry circles, or just yet another programming language to talk about.
From my point of view, being stuck in the past of systems languages design, during the AI age where the actual language becomes slowly irrelevant, it will mean the latter.
The benefits of the language outweigh the minor inconvenience.
I wrote a second blog for the C++ style vtable. https://williamw520.github.io/2025/07/17/memory-efficient-zi...
The first version is faster (one pointer indirection) with more memory consumed. The second version is more memory efficient sharing a single vtable for all instances, a bit slower (two pointer indirections).
Do all code bases use the same pattern? Or does it not matter for interoperability, e.g. between an app and the libraries it consumes?
We see:
Camel case Snake case Mix of camel case and snake case whatever that is