>  Ts=<int,int>, Us=<> , but as far as I could tell, Anoop rejects that outcome.

Note that I don't actually reject `Ts={int, int}`, `Us={ }`. What I am objecting is that the program 1.1 is ill-formed with `U` not being { } as per the current wording instead of being

1)  well-formed with `Ts={int, int}`, `Us={ }` assuming packs are greedy(no ambiguity) or
2) ill-formed with `Ts={int, int}`, `Us={ }` assuming this is ambiguous instead of being greedy or
3) ill-formed with `Ts={int, int}`, `Us={}` assuming packs are greedy(no ambiguity). If this point 3 is what the standard currently supports then it doesn't make sense because a parameter pack is allowed to be empty so that Ts={int, int}, Us={ } is an expected output and the program should be well-formed instead of ill-formed. Note again that Ts={int, int}, Us={ } is an expected output in this point 3 because there is no ambiguity interpretation used here in this point. These interpretations are separate from each other as also noted below.

--------------------------------

> Anoop's paper seems to be suggesting that this should become greedy thus unambiguously Ts=<int,int>, Bs=<>, Us=<>.

No, no, no... That is not what I am saying at all in my paper. The example that you gave ` template<class... Ts, bool... Bs, class... Us> void f(); f<int, int>();` should be ill-formed according to my paper. In the above quoted example the template parameter `Us` is of the same underlying type as `Ts` and so this is ill-formed.

--------------------------------

> It asserts that the status quo "doesn't make sense,"

I say that it "doesn't make sense" because the aim of the paper is to handle cases consistently and intuitively and above all logically. I've added two more examples in my revised paper named PnnnnR1.pdf attached at the end of this email. One example is the one that Arthur gave. The other added example is to make more clear the intention of the paper as I think(by reading arthur's comment about consistency) that some things were unclear.

NOTE:

Just to sum up some things, according to the paper `template<typename... T, typename... U> f(){}` is ill-formed because `U` and `T` have the same underlying types(meaning they both are "type" parameter packs) and thus when making a call like `f<int, int>();` there is ambiguity. Note this is the essential difference here. The program is ill-formed due to ambiguity and not due to greediness of a pack. That is, because there are multiple options available and no way to which argument should match which parameter pack's sequence.

The paper also notes that instead of choosing the ambiguity interpretation(which we prefer over IGPs), the other option is to add a separate clause in the standard saying that the packs are greedy and that the error is not due to any ambiguity. Basically, these two interpretations are separate from each other and the standard should clarify which of the two(or if both) the standard supports and if the program `template<typename... T, typename... U> void f(){}` is ill-formed due to interpretation 1(greedy packs) or interpretation 2(ambiguity) or due to both interpretations. In case ``template<typename... T, typename... U> void f(){}` is ill-formed due to IGPs then it wouldn't make sense because the parameter pack U is allowed to be an empty pack and so the more natural/logical outcome is for the program to be well-formed. This  boils down to saying that the 2nd option  for the standard is to make the program ``template<typename... T, typename... U> void f(){}; f<int,int>();` well-formed with T={int,int} and U ={ }.


Below is the revised document(revision 1) of the same. Thanks for giving your input. I appreciate it and will add more examples clearing any misunderstandings of what is being presented in the paper(if any) or my mistakes(if any) in the document.

Regards,
Anoop Rana


On Mon, 14 Nov 2022 at 21:48, Arthur O'Dwyer <arthur.j.odwyer@gmail.com> wrote:
On Mon, Nov 14, 2022 at 8:48 AM Anoop Rana via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
Attached is the proposal [...]

Section 1 (1.1, 1.2) points out the problem with
    template<class... Ts, class... Us> void f();
    f<int, int>();
Is this Ts=<>, Us=<int,int>? or Ts=<int>, Us=<int>? or Ts=<int,int>, Us=<>?
Today it is ambiguous (i.e. ill-formed). Anoop's paper section 1.2 mentions the possibility of making it greedy thus unambiguously Ts=<int,int>, Us=<>, but as far as I could tell, Anoop rejects that outcome.

But then consider this code:
    template<class... Ts, bool... Bs, class... Us> void f();
    f<int, int>();
Is this Ts=<>, Bs=<>, Us=<int,int>? or Ts=<int>, Bs=<>, Us=<int>? or Ts=<int,int>, Bs=<>, Us=<>?
Today it is ambiguous (i.e. ill-formed). Anoop's paper seems to be suggesting that this should become greedy thus unambiguously Ts=<int,int>, Bs=<>, Us=<>.
But why should this case be any greedier than the previous case?  They should be handled consistently, one way or the other.  I think the current Standard does handle them consistently; we should break that consistency only with a really good reason.

Speaking of "good reason": the paper offers no motivation for this change at all. It asserts that the status quo "doesn't make sense," but doesn't present any problems caused by the status quo, either in terms of "I can't write this useful code" or "I can't teach this effectively" or whatever.  Without motivation, a change of this magnitude should have a strong presumption of being-rejected.
Section 3 is currently titled "Motivation and Scope," but it doesn't talk about motivation and doesn't really have to do with "scope" either. I think this was a cut-and-paste/template error.

–Arthur