#A common case of identifier duplication in generics

1 messages · Page 1 of 1 (latest)

charred wolf
#

When programming generics, I very commonly stumble across the situation like following:

pub fn Pair(First_: type, Second_: type) type {
    return struct {
        // It's more important to have properly named public decls,
        // so use the underscores for the generic's parameters rather than here.
        pub const First = First_;
        pub const Second = Second_;
        first: First,
        second: Second,
    };
}

Using underscores looks ugly, but it is the best solution pattern which I have managed to invent so far. E.g. using FirstType and SecondType for the generic's parameters looks just like a longer version of the underscore, more confusing than adding to the readability. I was wondering whether there any better approaches?

dapper ether
#

i think you will find yourself not really needing a Pair(T, U) type since zig has annonymous structs

#

but to plainly answer your question, better names

#

for generics, i start with T, U, V... etc and from what ive seen it is common

#
pub fn Pair(comptime T: type, comptime U: type) type {
    return struct {
        // It's more important to have properly named public decls,
        // so use the underscores for the generic's parameters rather than here.
        pub const First = T;
        pub const Second = U;
        first: First,
        second: Second,
    };
}

is what i'd do

charred wolf
ionic glacier
charred wolf
#

I don't really think there's a way to fix this.
I was afraid that's the case. However I'm also wondering about the patterns that people developed to mitigate the problem.

ionic glacier
charred wolf
#

I actually had an idea of a language extension, specifically allowing the shadowing of this kind. I'm not 100% sure it can be done 100% reliably, but one probably could think of smth like this?

ionic glacier
#

It would be nice if Zig introduced a separate namespace for declarations in the same way it does for members, but I think that would make some comptime operations more complex.

charred wolf
ionic glacier
#

Maybe comptime shadowing could be more permissive or compile time functions could be namespaced. I dunno.

dapper ether
#

the simplest solution would be better names

charred wolf
charred wolf
dapper ether
#

can you give a concrete example of a more complicated case?

charred wolf
charred wolf
dapper ether
#

you could possibly rename default to default_decl

charred wolf
dapper ether
#

also why do you want to store ValueType in Property when you can use @TypeOf?

dapper ether
charred wolf
#

I'm not storing the types, I'm reexporting them as public decls.

dapper ether
charred wolf
#

Because a) reflection is possible but pretty involved and b) I might not want to access the internal member of the struct for reflection purposes from the outside, as that might introduce unnecessary dependencies into the code

#

What I want to do is

const MyProperty = Property(.plain,i32,0);
......
// somewhere else e.g.:
fn func(ptr: *MyProperty.ValueType) void { ...
dapper ether
charred wolf
#

And call it GetValueType()? Not sure I like that more than underscores 😄

dapper ether
#

no i meant

pub fn Property(kind: Kind, ValueType: type, default: ValueType) type {
  return struct {
    // ..
    fn func(ptr: *ValueType) void ...
#

keep the generic code together

#

and then you wouldnt need to reexport the decl

charred wolf
dapper ether
#

wouldnt it be generic since Property is generic

#

func depends on the generic of Property

#

you could call MyProperty.func just fine