I was initially very skeptical about Juicy main, however I have found myself warming up to the idea over time. That said, I’m still waffling on its granularity.
Like, it could work like this:
main.zig
pub const init_options: std.process.InitOptions = .{
.args = true,
.gpa = true,
.arena = false,
// etc.
};
pub fn main(init: std.process.Init) void {
// init has args and gpa, but arena is void.
}
std/process.zig
pub const InitOptions = struct {
args: bool = false,
gpa: bool = false,
arena: bool = false,
// etc.
};
pub const Init = struct {
const init_options = @import("root").init_options;
args: if (init_options.args) std.process.Args else void,
arena: if (init_options.arena) std.mem.Allocator else void,
gpa: if (init_options.gpa) std.mem.Allocator else void,
}
With a setup like this, the options provided could be things other than true or false in the event additional configuration is desired. Such as hinting to io where it should target on the balance between resource usage and speed. A parsed_args field on InitOptions could be a ?type, removing the need for start looking to see if main has a second argument for that purpose and allowing that to sit inside the main init structure.
The advantage of the above is that it would make it significantly more likely to be configurable to target the actual ideal. As it stands, I find it likely that as a project progresses it will want to move stuff out of juicy main and into the actual main, and there is little granularity for doing that.
The disadvantage of the above is that it’s more complicated than the current implementation, and might still not actually solve the problem of proper granularity. Eg, if you have an argument that might affect parameters when setting up your io instance. Which leads me back to my original suggestion of having it be a template.
So, all in all, I do feel that Juicy main’s design space is a slippery slope towards more complexity. Where I’ve warmed to it is that it’s a reasonable way for most projects to start, which is pragmatic. There are a bunch of things about Zig where being pragmatic wins over purity; They tend to get attention from people outside the core team (eg, files only being structs), but they do make the language productive to use by keeping simplicity and ignoring cases which have reasonable alternative solutions.
tl;dr: I’m about to init a new project, and I’m going to use Juicy Main, even if I don’t think it’s perfect, which is pretty awesome.