Relevant doc here and here and, from an earlier thread, the maybe-zen: “avoid repetitive namespacing” (like foo.bar.bar, but maybe even foo.bar.Bar - debatable).
So, for my generic structs, I’ve been using:
fn Baz(comptime T: type) type {
return struct {
Great. No problem. But I confess that I like the source file struct motif, especially because I think I’d like to break my structs into files of their own anyway, for this project.
If they weren’t generics, this would be a no-brainer, and I’d be able to avoid repetition in namespace (like foo.bar.Bar), as well, because Bar.zig would be a file, rather than bar.zig having a struct named Bar.
But… how… with generics? I know it’s pretty idiomatic to cap-name the function if it’s a function that returns type (as above, Baz), but I’m wondering about a different approach, such as:
foo/
bar.zig
where bar.zig contains a lowercase function, factory-ish, but to generate the specific type (not shunt to creating an object simultaneously). So:
//bar.zig
fn makeType(comptime T: type) type {
return struct {
//...
//main.zig
const Bar = bar.makeType(u8);
// for some simple app that only needs one kind of Bar
// or, more likely, for an app that needs variants:
const TransmitterBar = bar.makeType(Zag);
const ReceiverBar = bar.makeType(Zug);
Note, this Bar is not intended to be super general-purpose, like std data structures - these generic structs are pretty specific to the domain, so there’s slightly less incentive to be bound to do it “the std/general way”, in every regard.
I should also say: when I have these cases where I want to “make” a specific type, like Bar(u8), and const-NAME it, I don’t love naming it BarT or BarType or or even BarU8 (though this is what I often do currently)… this only crops up in the top usage, above, where the program (or whatever) really just thinks of this as “this program’s Bar”, so a specific name like TransmitterBar doesn’t lend itself naturally. IF I use a lowerCaseFunction() maker, I can just name the ultimate type Bar, as there’s no conflict. (I know, another way to do that would be const Bar = foo.bar.Bar(u8) or something of the sort, and just make a local version of the name, but even though it’s scoped, I don’t love this.)
So, 1) is the above proposal heinous for some reason I’m overlooking?, 2) is there another way I should consider - a way that might not be as common, but is clever to my hopes and possibly more idiomatic?