Date: Wed, 8 Apr 2026 05:05:36 +0500
Summary of my points (to keep it simple for those who didn't understand):
***Type Safety is the priority***:
With std::variant, you can assign a float to an object that should only be
an int. That’s not type-safe. My type_set(selector) fixes this—once the
runtime index picks the type, it’s fixed. You can't just swap it later.
****Compiler Freedom = Speed***:
I’m calling for an implementation-defined container. This lets the compiler
decide the best way to move or copy data (registers, stack, etc.) based on
the ABI. It’s faster because the compiler isn’t fighting a rigid library
structure. The compiler has the same freedom on when it instantiates
type_set(selector) into T^. Tuples aren't implementation defined, since
they have to provide some gurrenties and modifying tuples to fix this
breaks the zero cost abstraction principle.
***Hybrid approach:*** I want compile-time known types with runtime
indexing. std::tuple is too stiff for runtime, and std::variant is too
loose. My proposal uses the existing branching/template mechanisms the
compiler already has, just more efficiently. A mix of both of them is still
bad since return variants would still lead to type unsafe code by being
able to assign a float to int, as described in point 1.
On Wed, 8 Apr 2026, 4:59 am Muneem, <itfllow123_at_[hidden]> wrote:
>
> Before my response to Mr.sebistian and Mr. Simon:
> Small correction in my last emai(the change is in point 3):
> 1. The compiler can use a union, which case you have that advantage of the
> feature "potential merging multiple branches" that I talked about in my
> previous email.
> 2. The compiler can cause a function call after each definition
> 3.The compiler can do one of those, the second the variable is used or
> when the element has changed, the compiler can also choose the best point
> for instantion in between the varianle.defintion and when one of the two
> things happen.
> 4.will never do one of those if the list is filled only with const
> qualified types ( don't know if it's a good idea yet because of user
> defined types.
> 5.Again, in usage it will decay into T^, which can turn into at T& or T&&,
> so you can copy or move from it.
>
>
> ****Small recap*****:
> Basically the issue with tuples and this:
> (The mr mr.sebistian thinks it should work for heterogeneous lists):
> class Dispatch
> {
> public:
> Dispatch(tuple<A, B, C> t, int index);
> void op1();
> void op2();
> tuple<A, B, C>& _tupleref;
> int _index;
> };
> tuple<A, B, C> t = { a, b, c }; // initialize
> Dispatch<A, B, C> d(t, i); // select index i
> i.op2(); // call operations
> ***Issues***
> 1.How do you get a tuple elements out, how do you get a tuple elements
> std::plus any type out. One way is to use variants, but then the variant
> returned can be assigned any type, which is again type safe. If I get an
> object of type A from the tuple or after adding the element at index 0 with
> another B, then I should not be able to assign B to it. That's not how type
> safe c++ is supposed to be.
> The same issue exists for a array of variants
> 2.It takes a type T^, why is that an issue?
> Well, I may not be comfortable adding certain types in a list, for example
> for a bunch of representing a http packet, I may not be willing to have
> cookies in this list. The same applies to many users of heterogenous lists.
> Normal tuples won't allow me to put them in tuples and expect a special
> "safe" overload be called for them. In my proposals case, the overload will
> be that if T^; it fixes the downsides of the flexibility that heterogeneous
> lists provide.
>
>
> Response to Mr.Sebistian:
> >Just quickly answering 1)
>
> >Would you rather have the whole tuple copied everytime?
>
> >To the target stack frame?
> >In your proposed solution you can also copy a pointer to the role or the
> whole tuple (as long as the optimizer does not optimize over the function
> call).
> ****Answer****
> 1.No, it would leave it to the compiler, by having a implementation
> defined container for this reason. Sometimes copying a tuple is efficient
> sometimes not. Many times however you would want to move the tuple, and
> return it back.
> 2.In my proposal, since the container is implementation defined hence the
> compiler has a free hand in copying it however it wants and moving it
> however it wants.
> 3. I don't know what you mean by copying a role , but I think you meant
> pointing to an element using a point and copying that point.if yes:
> Then no you can't do that, you can't have pointers to type_set(selector)
> but can have points to T^, just like you can point to any other glvalue(T^)
> is a glvalue.
>
>
>
>
>
> >It will be faster only for small tuples, which perhaps can be passed in
> registers.
> >But it is a simple change for Dispatch to store the tile instead of a
> pointer to the tuple.
> >If you want to use the select to make the tuple smaller for directly
> copying the tuple, then just store the selected element as a variant in the
> Dispatch object.
> ****ANSWER****
> 1. No, my solution would be faster for heterogeneous list of any type
> because the compiler has full say in weather to copy it or not, and how to
> copy it, since the container is implementation defined.
> 2. What's a tile into the tuple? Please elaborate the thing that you mean
> by tile.
> 3. Variants don't have fixed types, hence for heterogeneous lists, they
> aren't an option at all. Even if say a A.dispatch(runtime index,std::plus,
> float{1}) return a variant that can have int, float, and I assign that
> variant to an object X of the same variant type, then object X can hold
> both float, int, but In heterogenous lists, I don't want that, I want the
> type to be fixed. So a tuple of built in types that have fixed types at
> each index is impossible, without the new value type type_set(selector).
> Where as in my solution, object: type_set(selector) X=
> selector(runtime_index)
> Can only hold what runtime_index was fixed to hold. So my proposal makes
> code more type safe and easy for reason about.
>
>
> >With your proposal the compiler has to break down your constructs, too.
> It also has to pass something to functions (if ABI boundary and not
> optimized over function calls). If you can program the same with current
> C++ we can reason about it.
> >I try to distill, what is actually new in your proposal.
> >That it also cannot be provided by one layer of C++, which would lead to
> the same assembly anyway, if it is equivalent to your proposed language
> extension.
> >Perhaps we find one small new language feature and another thing which
> can be expressed with some syntactic sugar.
> >A language feature can be interface like ad-hoc relationships between
> types with common member function signatures.
> >Otherwise perhaps 1 or 2 hints for the optimizer
> ****ANSWER****
> 1.thats why I proposed new value types, so that the compiler can use the
> existing branching and template instantion mechanisms. The compiler won't
> have to do anything other than use the existing mechanisms more efficiently
> to index the heterogeneous list. It basically uses the existing features
> compilers have. Like it does not have to break down constructs, just
> implementation defined container to get the type_set(selector), and
> instnatiate it into every possible T^. Like again, we have a million
> branching techniques the compilers already have.
> 2. It's not just 2 or 3 optimizations:
> 1. It's better type safety :
> Type_set(selector) X= selector(runtime index)
> The element at runtime index was int then you CANT assign float to X. This
> is an issue that std::variants fails to address. You may want to modify
> std::variant but that would either need changing how unions work or produce
> new expression type that my proposal already does.
> 2. Extended metaprogramming capabilities by simply merging current
> branching and template mechanisms.
> 3. This can be provided by one layer of c++ because c++ already has
> templates and branching facilities.
>
>
>
>
> You want to move code generation to the location of the final op call, you
> don't want to use pointers, but want to send only the needed information
> through function call or even ABI boundaries.
> ****ANSWER****
> 1. I want code generation when ever type_set(selector) is used, and the
> compiler can merge the branches generated if it wants. I don't want to use
> pointers because again, they don't provide copy/move without having to
> allocate a new object all together or have the risk of slicing.
> 2. It's up to the compiler on what information to send for each branch.
>
>
> My response to Mr.Simon:
> JSON and XML where the examples I have provided before. However, these
> only work if we have a runtime heterogeneous list. Until now (especially
> with your example from the Turing virtual machine) we were talking about
> heterogeneous lists known at compile time. The solutions to these problems
> differ a lot: at compile time we can just use std::tuple. However, if we
> want to modify a list at runtime we are back to std::vector<std::variant>
> (or something similar). With your most recent explanations we are closer to
> the latter. However, the most efficient solution in your case would work
> with a std::tuple rather than with a std::vector<std::variant>. If the
> types are fixed at compile time the compiler can optimize much better.
>
> So, which one do you want? Compile time lists or runtime lists? (Runtime
> indices would be allowed in both cases.)
> ****ANSWER****
> I want a compile time known implementation defined container of type
> type_set(selector for the reasons described in the "Small recap" recap
> section.
>
>
> On Tue, 7 Apr 2026, 5:01 pm Simon Schröder via Std-Proposals, <
> std-proposals_at_[hidden]> wrote:
>
>>
>>
>> On Tue, Apr 7, 2026 at 10:58 AM Muneem via Std-Proposals <
>> std-proposals_at_[hidden]> wrote:
>>
>>> You may disagree for the need of T^ but again considering that
>>> heterogeneous lists will mostly be ever used in networking protocols,
>>> JSONs, XMLs, you want as the programmer to have a freehand in providing
>>> (application) safety, when you let a user index your list with any index he
>>> wants.
>>>
>>
>> JSON and XML where the examples I have provided before. However, these
>> only work if we have a runtime heterogeneous list. Until now (especially
>> with your example from the Turing virtual machine) we were talking about
>> heterogeneous lists known at compile time. The solutions to these problems
>> differ a lot: at compile time we can just use std::tuple. However, if we
>> want to modify a list at runtime we are back to std::vector<std::variant>
>> (or something similar). With your most recent explanations we are closer to
>> the latter. However, the most efficient solution in your case would work
>> with a std::tuple rather than with a std::vector<std::variant>. If the
>> types are fixed at compile time the compiler can optimize much better.
>>
>> So, which one do you want? Compile time lists or runtime lists? (Runtime
>> indices would be allowed in both cases.)
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>
>
***Type Safety is the priority***:
With std::variant, you can assign a float to an object that should only be
an int. That’s not type-safe. My type_set(selector) fixes this—once the
runtime index picks the type, it’s fixed. You can't just swap it later.
****Compiler Freedom = Speed***:
I’m calling for an implementation-defined container. This lets the compiler
decide the best way to move or copy data (registers, stack, etc.) based on
the ABI. It’s faster because the compiler isn’t fighting a rigid library
structure. The compiler has the same freedom on when it instantiates
type_set(selector) into T^. Tuples aren't implementation defined, since
they have to provide some gurrenties and modifying tuples to fix this
breaks the zero cost abstraction principle.
***Hybrid approach:*** I want compile-time known types with runtime
indexing. std::tuple is too stiff for runtime, and std::variant is too
loose. My proposal uses the existing branching/template mechanisms the
compiler already has, just more efficiently. A mix of both of them is still
bad since return variants would still lead to type unsafe code by being
able to assign a float to int, as described in point 1.
On Wed, 8 Apr 2026, 4:59 am Muneem, <itfllow123_at_[hidden]> wrote:
>
> Before my response to Mr.sebistian and Mr. Simon:
> Small correction in my last emai(the change is in point 3):
> 1. The compiler can use a union, which case you have that advantage of the
> feature "potential merging multiple branches" that I talked about in my
> previous email.
> 2. The compiler can cause a function call after each definition
> 3.The compiler can do one of those, the second the variable is used or
> when the element has changed, the compiler can also choose the best point
> for instantion in between the varianle.defintion and when one of the two
> things happen.
> 4.will never do one of those if the list is filled only with const
> qualified types ( don't know if it's a good idea yet because of user
> defined types.
> 5.Again, in usage it will decay into T^, which can turn into at T& or T&&,
> so you can copy or move from it.
>
>
> ****Small recap*****:
> Basically the issue with tuples and this:
> (The mr mr.sebistian thinks it should work for heterogeneous lists):
> class Dispatch
> {
> public:
> Dispatch(tuple<A, B, C> t, int index);
> void op1();
> void op2();
> tuple<A, B, C>& _tupleref;
> int _index;
> };
> tuple<A, B, C> t = { a, b, c }; // initialize
> Dispatch<A, B, C> d(t, i); // select index i
> i.op2(); // call operations
> ***Issues***
> 1.How do you get a tuple elements out, how do you get a tuple elements
> std::plus any type out. One way is to use variants, but then the variant
> returned can be assigned any type, which is again type safe. If I get an
> object of type A from the tuple or after adding the element at index 0 with
> another B, then I should not be able to assign B to it. That's not how type
> safe c++ is supposed to be.
> The same issue exists for a array of variants
> 2.It takes a type T^, why is that an issue?
> Well, I may not be comfortable adding certain types in a list, for example
> for a bunch of representing a http packet, I may not be willing to have
> cookies in this list. The same applies to many users of heterogenous lists.
> Normal tuples won't allow me to put them in tuples and expect a special
> "safe" overload be called for them. In my proposals case, the overload will
> be that if T^; it fixes the downsides of the flexibility that heterogeneous
> lists provide.
>
>
> Response to Mr.Sebistian:
> >Just quickly answering 1)
>
> >Would you rather have the whole tuple copied everytime?
>
> >To the target stack frame?
> >In your proposed solution you can also copy a pointer to the role or the
> whole tuple (as long as the optimizer does not optimize over the function
> call).
> ****Answer****
> 1.No, it would leave it to the compiler, by having a implementation
> defined container for this reason. Sometimes copying a tuple is efficient
> sometimes not. Many times however you would want to move the tuple, and
> return it back.
> 2.In my proposal, since the container is implementation defined hence the
> compiler has a free hand in copying it however it wants and moving it
> however it wants.
> 3. I don't know what you mean by copying a role , but I think you meant
> pointing to an element using a point and copying that point.if yes:
> Then no you can't do that, you can't have pointers to type_set(selector)
> but can have points to T^, just like you can point to any other glvalue(T^)
> is a glvalue.
>
>
>
>
>
> >It will be faster only for small tuples, which perhaps can be passed in
> registers.
> >But it is a simple change for Dispatch to store the tile instead of a
> pointer to the tuple.
> >If you want to use the select to make the tuple smaller for directly
> copying the tuple, then just store the selected element as a variant in the
> Dispatch object.
> ****ANSWER****
> 1. No, my solution would be faster for heterogeneous list of any type
> because the compiler has full say in weather to copy it or not, and how to
> copy it, since the container is implementation defined.
> 2. What's a tile into the tuple? Please elaborate the thing that you mean
> by tile.
> 3. Variants don't have fixed types, hence for heterogeneous lists, they
> aren't an option at all. Even if say a A.dispatch(runtime index,std::plus,
> float{1}) return a variant that can have int, float, and I assign that
> variant to an object X of the same variant type, then object X can hold
> both float, int, but In heterogenous lists, I don't want that, I want the
> type to be fixed. So a tuple of built in types that have fixed types at
> each index is impossible, without the new value type type_set(selector).
> Where as in my solution, object: type_set(selector) X=
> selector(runtime_index)
> Can only hold what runtime_index was fixed to hold. So my proposal makes
> code more type safe and easy for reason about.
>
>
> >With your proposal the compiler has to break down your constructs, too.
> It also has to pass something to functions (if ABI boundary and not
> optimized over function calls). If you can program the same with current
> C++ we can reason about it.
> >I try to distill, what is actually new in your proposal.
> >That it also cannot be provided by one layer of C++, which would lead to
> the same assembly anyway, if it is equivalent to your proposed language
> extension.
> >Perhaps we find one small new language feature and another thing which
> can be expressed with some syntactic sugar.
> >A language feature can be interface like ad-hoc relationships between
> types with common member function signatures.
> >Otherwise perhaps 1 or 2 hints for the optimizer
> ****ANSWER****
> 1.thats why I proposed new value types, so that the compiler can use the
> existing branching and template instantion mechanisms. The compiler won't
> have to do anything other than use the existing mechanisms more efficiently
> to index the heterogeneous list. It basically uses the existing features
> compilers have. Like it does not have to break down constructs, just
> implementation defined container to get the type_set(selector), and
> instnatiate it into every possible T^. Like again, we have a million
> branching techniques the compilers already have.
> 2. It's not just 2 or 3 optimizations:
> 1. It's better type safety :
> Type_set(selector) X= selector(runtime index)
> The element at runtime index was int then you CANT assign float to X. This
> is an issue that std::variants fails to address. You may want to modify
> std::variant but that would either need changing how unions work or produce
> new expression type that my proposal already does.
> 2. Extended metaprogramming capabilities by simply merging current
> branching and template mechanisms.
> 3. This can be provided by one layer of c++ because c++ already has
> templates and branching facilities.
>
>
>
>
> You want to move code generation to the location of the final op call, you
> don't want to use pointers, but want to send only the needed information
> through function call or even ABI boundaries.
> ****ANSWER****
> 1. I want code generation when ever type_set(selector) is used, and the
> compiler can merge the branches generated if it wants. I don't want to use
> pointers because again, they don't provide copy/move without having to
> allocate a new object all together or have the risk of slicing.
> 2. It's up to the compiler on what information to send for each branch.
>
>
> My response to Mr.Simon:
> JSON and XML where the examples I have provided before. However, these
> only work if we have a runtime heterogeneous list. Until now (especially
> with your example from the Turing virtual machine) we were talking about
> heterogeneous lists known at compile time. The solutions to these problems
> differ a lot: at compile time we can just use std::tuple. However, if we
> want to modify a list at runtime we are back to std::vector<std::variant>
> (or something similar). With your most recent explanations we are closer to
> the latter. However, the most efficient solution in your case would work
> with a std::tuple rather than with a std::vector<std::variant>. If the
> types are fixed at compile time the compiler can optimize much better.
>
> So, which one do you want? Compile time lists or runtime lists? (Runtime
> indices would be allowed in both cases.)
> ****ANSWER****
> I want a compile time known implementation defined container of type
> type_set(selector for the reasons described in the "Small recap" recap
> section.
>
>
> On Tue, 7 Apr 2026, 5:01 pm Simon Schröder via Std-Proposals, <
> std-proposals_at_[hidden]> wrote:
>
>>
>>
>> On Tue, Apr 7, 2026 at 10:58 AM Muneem via Std-Proposals <
>> std-proposals_at_[hidden]> wrote:
>>
>>> You may disagree for the need of T^ but again considering that
>>> heterogeneous lists will mostly be ever used in networking protocols,
>>> JSONs, XMLs, you want as the programmer to have a freehand in providing
>>> (application) safety, when you let a user index your list with any index he
>>> wants.
>>>
>>
>> JSON and XML where the examples I have provided before. However, these
>> only work if we have a runtime heterogeneous list. Until now (especially
>> with your example from the Turing virtual machine) we were talking about
>> heterogeneous lists known at compile time. The solutions to these problems
>> differ a lot: at compile time we can just use std::tuple. However, if we
>> want to modify a list at runtime we are back to std::vector<std::variant>
>> (or something similar). With your most recent explanations we are closer to
>> the latter. However, the most efficient solution in your case would work
>> with a std::tuple rather than with a std::vector<std::variant>. If the
>> types are fixed at compile time the compiler can optimize much better.
>>
>> So, which one do you want? Compile time lists or runtime lists? (Runtime
>> indices would be allowed in both cases.)
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>
>
Received on 2026-04-08 00:05:53
