For comparison, C has designator lists (see 6.7.11 Initialization in the C standard), which means you can do what in Zig would be
const baz: Baz = .{ .bar.foo.value = 42 }; // does not work
I think this would be much nicer and easier to read. Has something like this already been discussed? It would also be useful for zon files, I think toml has a similar shortcut.
As far as I can tell, the syntax change for this would be small and not cause any problems/ambiguities. Just replace FieldInit <- DOT IDENTIFIER EQUAL Expr in the grammar with something like
I bet the Zig team is sick and tired by now hearing about how awesome C99 designated init is, and I’m probably responsible for that
I guess some of the features that make C99 designated init so damn convenient will collide with the way the Zig parser works and how types are inferred. IMHO I would prioritize convenience and readability over ‘conceptual purity’, but I also understand that this philosophy can be dangerous and turn the language into a kitchen-sink.
Things get worse if we define const Pos = struct { x: u32, y: u32 = 0 }; instead. Or const Foo = struct { p: ?Pos }; (what would Foo{ .p=null, .p.y = 16 } do? Probably error. what about const Foo = struct { p: ?Pos = null }; const f = Foo{ .a.x = 16 }?)
It seems easier to read in the micro, and harder to read in the macro. I wouldn’t be able to trust that any initialization is really the full initialization unless I read everything.
From what I saw there, it was rejected because the default value isn’t clear.
Personally, I think something like this would be very hard to argue against in terms of ambiguity:
if you don’t have an [else] it could detect if you exhausted all possible indeces and emits a complie error (like a switch).
For me the problem with status quo blk: is the declaration of the type, where I have to find both the length and the type name (happened to me while using sokol, unsurprisingly), where the designated initialization would skip having to declare the length and the type.
The ergonomic of blk: are only 1 line less, so it’s pretty good in that regard.
In C, later assignments in the initalizer list simply replace earlier ones, although gcc generates warnings if explicitly specified values are overridden. In Zig it probably makes more sense to not allow this.
I would suggest to just disallow touching any field more than once, instead of allowing initializers to mix together. This removes the ambiguities and is consistent with how initilizers currently work: const f: Foo = .{.value = 2, .value = 3}; is already an error, unlike in C where the order matters and 3 would override 2.