Modules are isomorphic to generic functions

You can get most of this same behavior even without introducing new concepts.

Have your types be parametrized in a non-generic way with type parameters that come from other Zig modules, and then use the Zig build system to implement “generics” when composing an output executable (or a test one, or whatever artifact you’re generating).

In concrete (but a bit pseudozig) terms:

// Replica.zig
const StateMachine = @import("StateMachine");
const Storage = @import("Storage");

state: StateMachine,
storage: Storage, 
// ...
// build.zig

const exe = b.addExecutable(.{ 
   .name = "tigerbeetle" 
   // ...
});

exe.root_module.addImport("StateMachine", StateMachine);
exe.root_module.addImport("Storage", RealStorage);

const tests = b.addTest(...);
tests.root_module.addImport("StateMachine", StateMachine);
tests.root_module.addImport("Storage", TestStorage);

I’d be curious to know if you guys considered this approach at all and, if so, what issue you encountered with it that made you avoid it.

10 Likes