const Sampler = @SpirvType(.sampler);
^
const Image = @SpirvType(.{ .image = .{
.usage = .{ .sampled = u32 },
.format = .unknown,
^
} });
Everything else about zig is quite readable, but this gets me every time. Maybe I'm being dumb though.So ".unknown" is a standin for "SomeEnum.unknown" or "SomeStruct.unknown", depending on what .format is.
I thought it was used in four completely separate ways:
· normal struct field access
· anonymous struct definition
· field definition within structs (for reasons to do with the parser)
· an extra 'infer operator' for syntactic sugar
But there's no support for anonymous structs/fields, and all structs and fields require a type somewhere for it to be inferred. Which is why this is invalid zig:
const test = .{ .x = 0, .y = 1 };
(It would need the type to be specified in the called function definition, or inline when assigning)Correct me if I'm wrong here! (And thank you)
const Enum = enum {one, two, five};
const t: Enum = .one; // Enum.one, but the type was inferred from lhs
std.debug.print("{t}\n", .{t});
Defining an anonymous struct is valid in zig; your example is only invalid because "test" is a reserved keyword. But you are correct that it reifies into a concrete type, and after initialization it doesn't coerce into other types because zig doesn't do structural typing: const anonymous = .{ .x = 0, .y = 1 };
std.debug.print("{}\n", .{@TypeOf(anonymous)}); // will output something like test_0__struct_45138
const Point = struct { x: i32, y: i32 };
const p1 = Point{ .x = 0, .y = 1 }; // valid, explicit struct literal
const p2: Point = .{ .x = 0, .y = 1 }; // valid, anonymous struct will coerce to Point
//const pt: Point = anonymous; // error: expected type 'test_0.Point', found 'test_0__struct_45138'
And then there's fieldless anonymous structs aka tuples. I'm including them because they were used in the print statements above: const tuple = .{ 0, "1", true };
std.debug.print("{}\n", .{@TypeOf(tuple)});
// struct { comptime comptime_int = 0, comptime *const [1:0]u8 = "1", comptime bool = true }All this does for me is raise the question of why they chose to use the `.` for so many different uses. I'd be fine if it was just to infer the type, but it seems very overloaded.
Of course there’s lots of programming that can afford to pay for GC side effects, if there weren’t we wouldn’t have invented GC, but it’s a little less universal, a little less ‘system’.
For me, I came to Zig after horrible cross-platform experiences led me to try going all the way back to C and I found that I was spending way too much time learning to deal with accidental complexity instead of essential complexity. (Respect to the C masters but I failed to adapt.)
But people don't write those in Go, they use Rust for it
To your point though, if Rust is getting it done, go for it. A lot of people still write those in C though.
Which is why TamaGo, TinyGo and gVisor exist.
https://www.erlang.org/docs/25/man/erts_alloc.html
jvm has at least 5:
https://github.com/openjdk/jdk/blob/master/src/hotspot/share...
postgres has at least 8:
https://github.com/postgres/postgres/blob/master/src/backend...
since zig anoints an allocator interface in its stdlib, your (and the stdlib's) data structures which use allocators can be trivially reused across different allocation strategies without rewriting code; and very likely (not guaranteed ofc) if you bring in someone else's code they will cleave to convention.