#Oboi

1 messages · Page 1 of 1 (latest)

rigid rivet
#

I thought zig was structurally typed ?

src/util.zig:32:12: error: expected type 'util.Map(.{ "blogs/index.html", "blogs/subdir/index.html" },[]const u8)', found 'util.Map(.{ "blogs/index.html", "blogs/subdir/index.html" },[]const u8)'

context code ```cpp
const std = @import("std");
const t = std.builtin.Type;

pub fn Map(comptime keys: []const []const u8, comptime V: type) type {
var fields: [keys.len]t.StructField = undefined;

for (keys, 0..) |key, i| {
    fields[i] = t.StructField{
        .name = key,
        .type = V,
        .default_value = null,
        .is_comptime = false,
        .alignment = 16,
    };
}

return @Type(.{
    .Struct = .{
        .layout = .Auto,
        .fields = &fields,
        .decls = &.{},
        .is_tuple = false,
    },
});

}

pub fn MapWith(comptime keys: []const []const u8, comptime V: type, comptime values: []const V) Map(keys, V) {
var map: Map(keys, V) = undefined;
inline for (keys, 0..) |key, i| {
@field(map, key) = values[i];
}
return map;
}

#

they have the exact same type

plush glacier
#

Not entirely sure what you mean

#

But two structs with the same layout will have distinct types, unless they are tuples

#

i.e: struct { i: i32, f: f32 } != struct { i: i32, f: f32 }

rigid rivet
#

really

plush glacier
#

But std.ArrayList(i32) == std.ArrayList(i32)

rigid rivet
#

the more you know

#

can I coherce a tuple to an array ?

#

or iterate a tup;e

#

tuple *

urban pond
rigid rivet
#

yeah actually that should apply

urban pond
#

does it not work for reified types

rigid rivet
#

although keys is an instance of a type

rigid rivet
plush glacier
#

Might be something weird with comptime []const []const u8 🤔

#

Because I would otherwise expect that to work

rigid rivet
#

its building a new struct

#

thats probs why

#

so the layout will be the same but cause its not just type constraints it will not be the same type

plush glacier
#

Functions that return comptime-only types (like type) will have their results memoized for each combination of values they're given as arguments

#

Which AFAIK means that it shouldn't matter if you use @Type or not

rigid rivet
#

weird then idk

#

any way to add a variable to the scope of the function body with a single declaration of the Map(keys, V)

next junco
#

i wonder what would happen if you made the strings "blogs/index.html", "blogs/subdir/index.html" constants instead of literals and passed those to Map() instead? could that possibly allow them to memoize as the same type?

rigid rivet
#

I cant change those strings they are from a option

#

(build option)

bronze pine
#

but you can change whether they're literals or not.

rigid rivet
#

its ok I decided to not use the map for this specific use case

#

gotta finish this tonight

next junco
#

this seems to illustrate the problem:

const ks = [_][:0]const u8{ "blogs/index.html", "blogs/subdir/index.html" };
const M1 = Map(&ks, [:0]const u8);
const M12 = Map(&ks, [:0]const u8);
const ks2 = [_][:0]const u8{ "blogs/index.html", "blogs/subdir/index.html" };
const M2 = Map(&ks2, [:0]const u8);
test {
    try std.testing.expect(M1 == M12);
    try std.testing.expect(M1 != M2);
}
#

this test passes

rigid rivet
#

eyyy

#

you were right

#

so I guess its because they are scalar

#

(kinda)

next junco
#

i think the comptime memoization uses the address of the keys []const []const param.

#

that would explain it

rigid rivet
#

yeah and there are different copys with the same underlying pointers but doenst matter as they are not what is being memoized

#

or maybe it is that it is a double reference is taken when cohercing to the outer slice

#

meaning that you get different "refs to refs"

next junco
#

not sure, but i imagine only the outermost pointer is being used

#

err maybe thats wrong. not sure just a guess.