#Empty structs vs. empty tuples

1 messages · Page 1 of 1 (latest)

coarse shore
#
pub fn main() void {
    const S = struct {};
    const T = @TypeOf(.{});
    @compileLog(
        @typeInfo(S).@"struct",
        @typeInfo(T).@"struct",
    );
}

According to compile log output, the first is a struct, the second is a tuple. How reliable is this? Is it likely to change?

fading bolt
#

well, .{} is the syntax for writing literal, and empty literal is just a tuple, no reason for this to change

#

drop the ., and you get the syntax for void literal

coarse shore
#

Well, .{ .... } is the syntax for both struct and tuple literals and struct { .... } is a syntax for both struct and tuple types. The first being empty resolves to a tuple, the second - to a struct. So no obvious logic here (could be hidden, though), hence my question.

#

I could guess that since .{} needs to coerce to arrays, and structs cannot coerce to arrays, it must be a tuple. But not sure what is the reason for struct {} being a struct? Maybe to allow one to define incompatible empty struct types? And then one still can define an empty tuple type with @TypeOf(.{}). These are my thoughts, but no idea how much they are in line with the core team's thinking.

fading bolt
#

well, .{...} turning to a struct or a tuple depends on the literal having field names or not, i guess the logic here is since there's no field names, it's a tuple

coarse shore
#

Yes, and my question is whether this is a random status quo, which could change "any minute", or something more thought through and fixed.

fading bolt
#

not sure what you mean struct {} being the a struct, you're defining a struct, what else can it be?

coarse shore
#

A tuple? With an empty struct it's not clear if I'm "supplying field names" or not, so could be both.

fading bolt
#

ah, ok, got it

coarse shore
#

You made exactly the same argument for .{} being a tuple, didn't you?

fading bolt
#

well, one is a literal and one is a type definition

#

but i can see why you are reasoning like that

#

i guess it's just a pathological case, and I haven't seen any argument to change the current behavior (i don't see any reason myself)

#

especially with 0.16, creating an empty tuple is @Tuple(&.{})

coarse shore
#

Oh, I didn't upgrade to 0.16 dev yet.

fading bolt
coarse shore
#

The reason I'm asking is that I'm doing a bit of metaprogramming and I'm contemplating using different kinds of "default" values with semantics like "not there", "please use default", "don't do anything" etc. The list includes .{}, {} and null literals, so I want to know if it's safe to rely on the .{} syntax.

fading bolt
#

at least for now, i don't see any discussion to change .{} to be a non tuple struct

coarse shore
#

👍