Date: Tue, 7 Apr 2026 11:42:39 +0200
I accidentally took this discussion off the list. Here are my previous
email and Muneem's response:
On Tue, Apr 7, 2026 at 9:16 AM Muneem <itfllow123_at_[hidden]> wrote:
> Hi!
> Thank you for your feedback and interest. I appreciate it a million
> billion times.
>
> Note before my answer:
> I use "T^" to describe the new element type for providing overloads
> because I would not want to refer to it by the long name "element type two"
> and type_set(selector) for the type of every element in the list for this
> exact reason. Providing overloads for T^ is not only useful for the user to
> provide semantics specifically for elements of a heterogeneous list, but
> also because the common use of a heterogeneous list would probably be to
> define JSONs, HTTP packets, tcp packets,other networking information, etc,
> and in these cases, you would want to use any other type that you use in
> your project, but make sure the user has authorization to a type holding
> sensitive information before letting him have it. Basically for a type
> "Cookie", you may have overloads allowing you to use them freely, but if
> accessed from a http packet, it will lead you straight to an overload for
> T^(if exists), in which you can do any checks you want.
>
>
> >It still holds that there is a chance that we can make std::variant as
> type safe as your new type. Suppose we allow references in std::variant,
> e.g. std::variant<int&,float&,std::string&>. By default, references aren’t
> reassignable. If you assign a value it would have to be of the same (or
> compatible) type. You could, in fact, not assign a string to an int. (We
> might be able to rebind references through a member function if we wanted
> to.) As long as the variant points to an entry inside the heterogeneous
> list, we cannot change the type (because the types of the list at each
> index are fixed).
>
> ****ANSWER****
> 1. You can't have references in unions and that's the main the main pillar
> keeps unions type safe, so you can't have them for std::variant. It's like
> if a floating point type didn't exist, and we allow pointers to store
> floating pointing numbers instead of just inventing a float type. Like the
> question is that how do you without a new value type or changing the
> fundamentals of a union change std variant?
> 2. Even with constant pointers, the overhead of gurrentying redirection
> (pointer access) exists every time you use that variant, and the code bloat
> in both cases would be the same because with visit, the compiler still has
> to generate code, so it's just gonna be more verbose and slower(since you
> can't copy by value). Again, it is an incomplete solution.with my proposal,
> I can do so if the destination type is type_set(selector), and that copy
> would be completely independent of the one in the list, and would allow for
> move semantics to move from source to destination.
>
> >If, however, I take a copy from one of the elements in the heterogeneous
> list, you are correct that the type stored inside the std::variant could be
> changed. This gets me thinking if we need a std::variant to behave more
> like a raw pointer. With a raw pointer we can specify the following
> variants of constness:
> int const *
> int *const
> int const *const
> I am not entirely sure if we can change this still (or if std::variant
> already behaves like this), but in the same way we could make the currently
> selected type of std::variant const (but still allow assignment of the same
> type if the contained type is not const).
> ****ANSWER****
> 1. You have a point, a very convincing one, but:
> 1. Even if you make the type of the variant const (which i don't think you
> can cuz it's based of a union), even then, the compiler would gurrentie
> space overhead since it's a union. While in my case the compiler has a
> freehand in how it copies any object object of type type_set(selector), it
> may provide lazy copying where the copy is shared (the compiler thinks it's
> cheaper to do so for that use case) until the object is infact change. The
> compiler can use desperate functions to again avoid space overhead where
> space overheads hurts performance more than function pointers and
> functions. The list goes on and on.
>
>
> >I still don’t fully understand T^ because you are saying that it can
> decay to T, T& or T&&. Is T^ a variant of several types? Or is it just one
> specific type or nothing? What I mean is the following:
> int^ var = hlist.select(0);
> Would I write it like this? Should var be an int only if at index 0 there
> is an int in the heterogeneous list? And otherwise I could not do anything
> with that variable?
>
> ****ANSWER****
> 1.Every element in the heterogeneous list would be of type
> type_set(selector), this type could decay into T^, when ever used in an
> expression, T^ can itself decay into T& or T&&. T^ provides the benefits
> that I talked about in the beginning of my email.
>
>
> >Because in this case we could introduce a new type that internally stores
> a variant but can only be used if the current selection of the variant is
> the specified type.
> ****ANSWER****
> 1. variants are based on unions, and you can't restrict unions without
> destroying their points. To make variants like that, you need a new
> expression value, which sounds like my type_set(selector)
>
> >I don’t agree that T^ must be a different type from std::variant so that
> you spot it from far way that it is the result from indexing into a
> heterogeneous list. If this is important to a programmer he can easily write
> using indexed_from_a_heterogeneous_list = std::variant;
> ****ANSWER****
> 1. The elements of the heterogeneous list is type_set(selector), but it
> instnatiats into a T^, when used. This is something that using
> indexed_from_a_heterogeneous_list = std::variant; can do for a specific T.
> Since every T can have a different overloads.
>
>
> >I see, we cannot yet agree that std::variant could work if we adapt it.
> Can we at least agree that we don’t need a new type for a heterogeneous
> list, but can just use std::tuple for this?
> ****ANSWER****
> You again have a great point on using tuples, but;
> 1. We could use array as a container type of type_set(selector), but then
> how will the type function type_set (array) work?
> 2. How will a compiler store book keeping information, without breaking
> the rule "what you don't use, you don't pay for"?
> 3. To assign from (if tuples were expanded to accept runtime
> index)tupleY[runtime index] to tupleX[runtime index] would need a whole N
> by N checks at the time of the assignment, while in my tool, the compiler
> has a complete freehand to delay the checks to when the compiler knows
> cache would include maximum information related to checks, the delay of
> course is up to the time, the compiler knows it's safe.
>
> >(I’m now really confused that you brought up JIT in another email again
> when you said before that it is not necessary.)
> ****ANSWER****
> It was just an example on why I didn't go too fast with my proposal
> (introducing the details) because I knew that I need access what others
> think. My point was that I may think JIT can avoid code bloat, but I want
> vouch for it and call it unnecessary because the community thinks so.
> Regards, Muneem.
>
>
> On Tue, 7 Apr 2026, 10:23 am Simon Schröder, <dr.simon.schroeder_at_[hidden]>
> wrote:
>
>>
>>
>> > On Apr 7, 2026, at 2:45 AM, Muneem <itfllow123_at_[hidden]> wrote:
>> >
>> > Std::variant can still be used (even after the change in the proposal
>> in my last email to Mr.thiago), but the other type would be more type safe,
>> in that you could not assign a string to an int if select[runtime_imdex]
>> had an int and it was assigned to x. This would make it easier for the user
>> to reason about.
>>
>> It still holds that there is a chance that we can make std::variant as
>> type safe as your new type. Suppose we allow references in std::variant,
>> e.g. std::variant<int&,float&,std::string&>. By default, references aren’t
>> reassignable. If you assign a value it would have to be of the same (or
>> compatible) type. You could, in fact, not assign a string to an int. (We
>> might be able to rebind references through a member function if we wanted
>> to.) As long as the variant points to an entry inside the heterogeneous
>> list, we cannot change the type (because the types of the list at each
>> index are fixed).
>>
>> If, however, I take a copy from one of the elements in the heterogeneous
>> list, you are correct that the type stored inside the std::variant could be
>> changed. This gets me thinking if we need a std::variant to behave more
>> like a raw pointer. With a raw pointer we can specify the following
>> variants of constness:
>> int const *
>> int *const
>> int const *const
>> I am not entirely sure if we can change this still (or if std::variant
>> already behaves like this), but in the same way we could make the currently
>> selected type of std::variant const (but still allow assignment of the same
>> type if the contained type is not const).
>>
>> I still don’t fully understand T^ because you are saying that it can
>> decay to T, T& or T&&. Is T^ a variant of several types? Or is it just one
>> specific type or nothing? What I mean is the following:
>> int^ var = hlist.select(0);
>> Would I write it like this? Should var be an int only if at index 0 there
>> is an int in the heterogeneous list? And otherwise I could not do anything
>> with that variable?
>>
>> Because in this case we could introduce a new type that internally stores
>> a variant but can only be used if the current selection of the variant is
>> the specified type.
>>
>> I don’t agree that T^ must be a different type from std::variant so that
>> you spot it from far way that it is the result from indexing into a
>> heterogeneous list. If this is important to a programmer he can easily write
>> using indexed_from_a_heterogeneous_list = std::variant;
>>
>> I see, we cannot yet agree that std::variant could work if we adapt it.
>> Can we at least agree that we don’t need a new type for a heterogeneous
>> list, but can just use std::tuple for this?
>>
>> (I’m now really confused that you brought up JIT in another email again
>> when you said before that it is not necessary.)
>
>
email and Muneem's response:
On Tue, Apr 7, 2026 at 9:16 AM Muneem <itfllow123_at_[hidden]> wrote:
> Hi!
> Thank you for your feedback and interest. I appreciate it a million
> billion times.
>
> Note before my answer:
> I use "T^" to describe the new element type for providing overloads
> because I would not want to refer to it by the long name "element type two"
> and type_set(selector) for the type of every element in the list for this
> exact reason. Providing overloads for T^ is not only useful for the user to
> provide semantics specifically for elements of a heterogeneous list, but
> also because the common use of a heterogeneous list would probably be to
> define JSONs, HTTP packets, tcp packets,other networking information, etc,
> and in these cases, you would want to use any other type that you use in
> your project, but make sure the user has authorization to a type holding
> sensitive information before letting him have it. Basically for a type
> "Cookie", you may have overloads allowing you to use them freely, but if
> accessed from a http packet, it will lead you straight to an overload for
> T^(if exists), in which you can do any checks you want.
>
>
> >It still holds that there is a chance that we can make std::variant as
> type safe as your new type. Suppose we allow references in std::variant,
> e.g. std::variant<int&,float&,std::string&>. By default, references aren’t
> reassignable. If you assign a value it would have to be of the same (or
> compatible) type. You could, in fact, not assign a string to an int. (We
> might be able to rebind references through a member function if we wanted
> to.) As long as the variant points to an entry inside the heterogeneous
> list, we cannot change the type (because the types of the list at each
> index are fixed).
>
> ****ANSWER****
> 1. You can't have references in unions and that's the main the main pillar
> keeps unions type safe, so you can't have them for std::variant. It's like
> if a floating point type didn't exist, and we allow pointers to store
> floating pointing numbers instead of just inventing a float type. Like the
> question is that how do you without a new value type or changing the
> fundamentals of a union change std variant?
> 2. Even with constant pointers, the overhead of gurrentying redirection
> (pointer access) exists every time you use that variant, and the code bloat
> in both cases would be the same because with visit, the compiler still has
> to generate code, so it's just gonna be more verbose and slower(since you
> can't copy by value). Again, it is an incomplete solution.with my proposal,
> I can do so if the destination type is type_set(selector), and that copy
> would be completely independent of the one in the list, and would allow for
> move semantics to move from source to destination.
>
> >If, however, I take a copy from one of the elements in the heterogeneous
> list, you are correct that the type stored inside the std::variant could be
> changed. This gets me thinking if we need a std::variant to behave more
> like a raw pointer. With a raw pointer we can specify the following
> variants of constness:
> int const *
> int *const
> int const *const
> I am not entirely sure if we can change this still (or if std::variant
> already behaves like this), but in the same way we could make the currently
> selected type of std::variant const (but still allow assignment of the same
> type if the contained type is not const).
> ****ANSWER****
> 1. You have a point, a very convincing one, but:
> 1. Even if you make the type of the variant const (which i don't think you
> can cuz it's based of a union), even then, the compiler would gurrentie
> space overhead since it's a union. While in my case the compiler has a
> freehand in how it copies any object object of type type_set(selector), it
> may provide lazy copying where the copy is shared (the compiler thinks it's
> cheaper to do so for that use case) until the object is infact change. The
> compiler can use desperate functions to again avoid space overhead where
> space overheads hurts performance more than function pointers and
> functions. The list goes on and on.
>
>
> >I still don’t fully understand T^ because you are saying that it can
> decay to T, T& or T&&. Is T^ a variant of several types? Or is it just one
> specific type or nothing? What I mean is the following:
> int^ var = hlist.select(0);
> Would I write it like this? Should var be an int only if at index 0 there
> is an int in the heterogeneous list? And otherwise I could not do anything
> with that variable?
>
> ****ANSWER****
> 1.Every element in the heterogeneous list would be of type
> type_set(selector), this type could decay into T^, when ever used in an
> expression, T^ can itself decay into T& or T&&. T^ provides the benefits
> that I talked about in the beginning of my email.
>
>
> >Because in this case we could introduce a new type that internally stores
> a variant but can only be used if the current selection of the variant is
> the specified type.
> ****ANSWER****
> 1. variants are based on unions, and you can't restrict unions without
> destroying their points. To make variants like that, you need a new
> expression value, which sounds like my type_set(selector)
>
> >I don’t agree that T^ must be a different type from std::variant so that
> you spot it from far way that it is the result from indexing into a
> heterogeneous list. If this is important to a programmer he can easily write
> using indexed_from_a_heterogeneous_list = std::variant;
> ****ANSWER****
> 1. The elements of the heterogeneous list is type_set(selector), but it
> instnatiats into a T^, when used. This is something that using
> indexed_from_a_heterogeneous_list = std::variant; can do for a specific T.
> Since every T can have a different overloads.
>
>
> >I see, we cannot yet agree that std::variant could work if we adapt it.
> Can we at least agree that we don’t need a new type for a heterogeneous
> list, but can just use std::tuple for this?
> ****ANSWER****
> You again have a great point on using tuples, but;
> 1. We could use array as a container type of type_set(selector), but then
> how will the type function type_set (array) work?
> 2. How will a compiler store book keeping information, without breaking
> the rule "what you don't use, you don't pay for"?
> 3. To assign from (if tuples were expanded to accept runtime
> index)tupleY[runtime index] to tupleX[runtime index] would need a whole N
> by N checks at the time of the assignment, while in my tool, the compiler
> has a complete freehand to delay the checks to when the compiler knows
> cache would include maximum information related to checks, the delay of
> course is up to the time, the compiler knows it's safe.
>
> >(I’m now really confused that you brought up JIT in another email again
> when you said before that it is not necessary.)
> ****ANSWER****
> It was just an example on why I didn't go too fast with my proposal
> (introducing the details) because I knew that I need access what others
> think. My point was that I may think JIT can avoid code bloat, but I want
> vouch for it and call it unnecessary because the community thinks so.
> Regards, Muneem.
>
>
> On Tue, 7 Apr 2026, 10:23 am Simon Schröder, <dr.simon.schroeder_at_[hidden]>
> wrote:
>
>>
>>
>> > On Apr 7, 2026, at 2:45 AM, Muneem <itfllow123_at_[hidden]> wrote:
>> >
>> > Std::variant can still be used (even after the change in the proposal
>> in my last email to Mr.thiago), but the other type would be more type safe,
>> in that you could not assign a string to an int if select[runtime_imdex]
>> had an int and it was assigned to x. This would make it easier for the user
>> to reason about.
>>
>> It still holds that there is a chance that we can make std::variant as
>> type safe as your new type. Suppose we allow references in std::variant,
>> e.g. std::variant<int&,float&,std::string&>. By default, references aren’t
>> reassignable. If you assign a value it would have to be of the same (or
>> compatible) type. You could, in fact, not assign a string to an int. (We
>> might be able to rebind references through a member function if we wanted
>> to.) As long as the variant points to an entry inside the heterogeneous
>> list, we cannot change the type (because the types of the list at each
>> index are fixed).
>>
>> If, however, I take a copy from one of the elements in the heterogeneous
>> list, you are correct that the type stored inside the std::variant could be
>> changed. This gets me thinking if we need a std::variant to behave more
>> like a raw pointer. With a raw pointer we can specify the following
>> variants of constness:
>> int const *
>> int *const
>> int const *const
>> I am not entirely sure if we can change this still (or if std::variant
>> already behaves like this), but in the same way we could make the currently
>> selected type of std::variant const (but still allow assignment of the same
>> type if the contained type is not const).
>>
>> I still don’t fully understand T^ because you are saying that it can
>> decay to T, T& or T&&. Is T^ a variant of several types? Or is it just one
>> specific type or nothing? What I mean is the following:
>> int^ var = hlist.select(0);
>> Would I write it like this? Should var be an int only if at index 0 there
>> is an int in the heterogeneous list? And otherwise I could not do anything
>> with that variable?
>>
>> Because in this case we could introduce a new type that internally stores
>> a variant but can only be used if the current selection of the variant is
>> the specified type.
>>
>> I don’t agree that T^ must be a different type from std::variant so that
>> you spot it from far way that it is the result from indexing into a
>> heterogeneous list. If this is important to a programmer he can easily write
>> using indexed_from_a_heterogeneous_list = std::variant;
>>
>> I see, we cannot yet agree that std::variant could work if we adapt it.
>> Can we at least agree that we don’t need a new type for a heterogeneous
>> list, but can just use std::tuple for this?
>>
>> (I’m now really confused that you brought up JIT in another email again
>> when you said before that it is not necessary.)
>
>
Received on 2026-04-07 09:43:20
