logoalt Hacker News

tremonyesterday at 2:49 PM1 replyview on HN

I don't think that "infer operator" is a special case of field access, to me it feels like regular known-type elision similar to how C# and C++ use the var keyword if the data type can be inferred from the rhs expression:

    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 }

Replies

coxmiyesterday at 5:36 PM

Thanks for the detailed answer :)

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.