Date: Wed, 28 Sep 2022 18:33:07 +0000
> Yes, it's fairly common, and getting more so as previously callback-style code (that could use lambda explicit template syntax) moves to coroutines. It's frustrating when a nicely deduced, constrained and/or pattern matched parameter becomes a coroutine local variable that now can only be matched using the meagre `auto` syntax.
Would love to see an example just for my own curiosity, but I'll take your word for it anyhow. I think your 'using { ... }' syntax would be fine for named deduction for normal variable declarations, though I wouldn't mind e.g. 'auto<class T>' either, though I think the 'using' version is better and more clear. I feel though that that would only solve one aspect of this problem, and not the aspect of deduced function parameter types. Really I just want something that would give me the type that 'auto' would otherwise name in the abbreviated function template syntax, so for me something like
void named_auto(T{auto} &&to_be_forwarded);
is perfectly acceptable to me. Maybe these separate aspects of this problem should be given separate solutions? That runs the risk of having more than one good way to do named deduction, at least for deduced types, but I feel that may be a fine enough situation.
------- Original Message -------
On Wednesday, September 28th, 2022 at 12:48 PM, Edward Catmur <ecatmur_at_[hidden]> wrote:
> On Wed, 28 Sept 2022 at 17:56, Keenan Horrigan <friedkeenan_at_[hidden]> wrote:
>
>>> We already have syntax for function template parameter named deduction; we don't need another. What we don't have is a syntax for block scope named deduction.
>>
>> Well, we also currently have ways to get the types deduced through your syntax suggestions, they're just suboptimal (using decltype, remove_cvref etc.).
>
> Pattern matching the type is very much suboptimal as well; it requires creating helper metaclasses, alias templates etc., or abusing lambdas.
>
>> Similarly, I find the current state of named function parameter deduction suboptimal. We have the normal 'template<...>' syntax, and then we have the terse syntax with auto-parameters. Right now I steer away from the terse syntax because when I deduce a type for a function parameter, I very often want to also name that deduced type, so I might as well use the 'template<...>' syntax. However, the terse syntax is more concise, and I would argue more readable were it not for the fact that it necessitates some use of decltype to name the type, and similarly may require remove_cvref etc. to be applied. I find this suboptimal, and would very much enjoy being able to use the terse syntax and some form of "named auto".
>
> There's no reason that `auto<class T> T x` couldn't be accepted in function template parameter position as well; it just feels redundant.
>
> Also there's the issue that when supplying function template argument explicitly (as f<A...>(a...)) to a terse function template it's not entirely obvious which template argument corresponds to which argument. But then again, named deduction wouldn't exactly worsen this issue.
>
>> Truthfully as well, I cannot recall a time where I've wanted to name a deduced type of a variable that wasn't a function parameter. Is this a common occurrence for others? It of course would be better to have syntax that allows for it, but I personally don't find a solution that doesn't allow named deduction with the abbreviated function template syntax appealing.
>
> Yes, it's fairly common, and getting more so as previously callback-style code (that could use lambda explicit template syntax) moves to coroutines. It's frustrating when a nicely deduced, constrained and/or pattern matched parameter becomes a coroutine local variable that now can only be matched using the meagre `auto` syntax.
>
>> ------- Original Message -------
>> On Wednesday, September 28th, 2022 at 10:39 AM, Edward Catmur <ecatmur_at_[hidden]> wrote:
>>
>>> On Wed, 28 Sept 2022 at 16:24, Keenan Horrigan <friedkeenan_at_[hidden]> wrote:
>>>
>>>> My issue with the 'using' syntax was that it seems redundant when used with function parameter type deduction (because why wouldn't you just type out the normal 'template<...>'), I don't see how your 'auto<class T> T var' syntax addresses that beyond maybe putting the deduced entities closer to their source? Not a hugely compelling reason to use it over normal template parameters in my opinion.
>>>
>>> We already have syntax for function template parameter named deduction; we don't need another. What we don't have is a syntax for block scope named deduction.
>>>
>>>> ------- Original Message -------
>>>> On Wednesday, September 28th, 2022 at 10:08 AM, Edward Catmur via Std-Proposals <std-proposals_at_[hidden]> wrote:
>>>>
>>>>> On Wed, 28 Sept 2022 at 15:14, Jason McKesson via Std-Proposals <std-proposals_at_[hidden]> wrote:
>>>>>
>>>>>> On Wed, Sep 28, 2022 at 10:06 AM Sébastien Bini via Std-Proposals
>>>>>> <std-proposals_at_[hidden]> wrote:
>>>>>>>
>>>>>>> How about a syntax similar to that of parameters then?
>>>>>>>
>>>>>>> template <class T> T var = foo();
>>>>>>> template <class K, class V> std::pair<K const, V>& kv = *map.begin(); // or [k, v]?
>>>>>>> template <std::copyable T, auto I> std::array<T, I> arr = getArr();
>>>>>>> template <std::size_t... I> [[maybe_unused]] std::index_sequence<I...> seq = std::index_sequence_for<Args...>();
>>>>>>>
>>>>>>> Then we don't need to reinvent the syntax for parameters.
>>>>>
>>>>> That syntax is already in use for variable templates. Maybe named deduction is at block scope and variable templates are at namespace scope, but that kind of overloading of meaning is pretty horrible - `static` is bad enough.
>>>>>
>>>>>> Let's re-examine the problem that people seem to want to solve.
>>>>>>
>>>>>> My understanding was that the principal problem was that you want to
>>>>>> gain access to the actual typename that the placeholder deduction
>>>>>> syntax yields, and sticking a `using name = decltype(var_name);` is
>>>>>> both wordy and error-prone (I deliberately did that wrong, for
>>>>>> example).
>>>>>>
>>>>>> The main reason people deduce types is because they don't want to have
>>>>>> to type out the full name of the type
>>>>>
>>>>> or because the type is unnameable, or because it's dependent, or because the code you're calling could change its return type and so typing it out is a hostage to fortune.
>>>>>
>>>>>> (or because it's already
>>>>>> mentioned in the initializing expression).
>>>>>
>>>>> If you're using AAA with types on the RHS then you don't need to deduce them again, so you wouldn't need named deduction.
>>>>>
>>>>>> So it seems to me that
>>>>>> injecting a bunch more words into such a declaration is...
>>>>>> counter-productive.
>>>>>>
>>>>>> Yes, any of these declarations might be useful. But... are they really
>>>>>> *that* useful? So useful that we want to type out (and read) all of
>>>>>> that?
>>>>>
>>>>> We are proposing that a single statement introduce not just potentially multiple entity names, but also potentially multiple type aliases (also, maybe, packs, templates, concepts). This is a novel challenge for compilers and other tools, and it needs *some* introducing syntax to shunt the parser down the new code paths; lexing is difficult enough as it is.
>>>>>
>>>>> If `using` is too much typing, how about the introducer being `auto <`? It seems that the lexer should be able to detect that pretty much immediately.
>>>>>
>>>>> auto<class T> T var = foo();
>>>>> // etc.
Would love to see an example just for my own curiosity, but I'll take your word for it anyhow. I think your 'using { ... }' syntax would be fine for named deduction for normal variable declarations, though I wouldn't mind e.g. 'auto<class T>' either, though I think the 'using' version is better and more clear. I feel though that that would only solve one aspect of this problem, and not the aspect of deduced function parameter types. Really I just want something that would give me the type that 'auto' would otherwise name in the abbreviated function template syntax, so for me something like
void named_auto(T{auto} &&to_be_forwarded);
is perfectly acceptable to me. Maybe these separate aspects of this problem should be given separate solutions? That runs the risk of having more than one good way to do named deduction, at least for deduced types, but I feel that may be a fine enough situation.
------- Original Message -------
On Wednesday, September 28th, 2022 at 12:48 PM, Edward Catmur <ecatmur_at_[hidden]> wrote:
> On Wed, 28 Sept 2022 at 17:56, Keenan Horrigan <friedkeenan_at_[hidden]> wrote:
>
>>> We already have syntax for function template parameter named deduction; we don't need another. What we don't have is a syntax for block scope named deduction.
>>
>> Well, we also currently have ways to get the types deduced through your syntax suggestions, they're just suboptimal (using decltype, remove_cvref etc.).
>
> Pattern matching the type is very much suboptimal as well; it requires creating helper metaclasses, alias templates etc., or abusing lambdas.
>
>> Similarly, I find the current state of named function parameter deduction suboptimal. We have the normal 'template<...>' syntax, and then we have the terse syntax with auto-parameters. Right now I steer away from the terse syntax because when I deduce a type for a function parameter, I very often want to also name that deduced type, so I might as well use the 'template<...>' syntax. However, the terse syntax is more concise, and I would argue more readable were it not for the fact that it necessitates some use of decltype to name the type, and similarly may require remove_cvref etc. to be applied. I find this suboptimal, and would very much enjoy being able to use the terse syntax and some form of "named auto".
>
> There's no reason that `auto<class T> T x` couldn't be accepted in function template parameter position as well; it just feels redundant.
>
> Also there's the issue that when supplying function template argument explicitly (as f<A...>(a...)) to a terse function template it's not entirely obvious which template argument corresponds to which argument. But then again, named deduction wouldn't exactly worsen this issue.
>
>> Truthfully as well, I cannot recall a time where I've wanted to name a deduced type of a variable that wasn't a function parameter. Is this a common occurrence for others? It of course would be better to have syntax that allows for it, but I personally don't find a solution that doesn't allow named deduction with the abbreviated function template syntax appealing.
>
> Yes, it's fairly common, and getting more so as previously callback-style code (that could use lambda explicit template syntax) moves to coroutines. It's frustrating when a nicely deduced, constrained and/or pattern matched parameter becomes a coroutine local variable that now can only be matched using the meagre `auto` syntax.
>
>> ------- Original Message -------
>> On Wednesday, September 28th, 2022 at 10:39 AM, Edward Catmur <ecatmur_at_[hidden]> wrote:
>>
>>> On Wed, 28 Sept 2022 at 16:24, Keenan Horrigan <friedkeenan_at_[hidden]> wrote:
>>>
>>>> My issue with the 'using' syntax was that it seems redundant when used with function parameter type deduction (because why wouldn't you just type out the normal 'template<...>'), I don't see how your 'auto<class T> T var' syntax addresses that beyond maybe putting the deduced entities closer to their source? Not a hugely compelling reason to use it over normal template parameters in my opinion.
>>>
>>> We already have syntax for function template parameter named deduction; we don't need another. What we don't have is a syntax for block scope named deduction.
>>>
>>>> ------- Original Message -------
>>>> On Wednesday, September 28th, 2022 at 10:08 AM, Edward Catmur via Std-Proposals <std-proposals_at_[hidden]> wrote:
>>>>
>>>>> On Wed, 28 Sept 2022 at 15:14, Jason McKesson via Std-Proposals <std-proposals_at_[hidden]> wrote:
>>>>>
>>>>>> On Wed, Sep 28, 2022 at 10:06 AM Sébastien Bini via Std-Proposals
>>>>>> <std-proposals_at_[hidden]> wrote:
>>>>>>>
>>>>>>> How about a syntax similar to that of parameters then?
>>>>>>>
>>>>>>> template <class T> T var = foo();
>>>>>>> template <class K, class V> std::pair<K const, V>& kv = *map.begin(); // or [k, v]?
>>>>>>> template <std::copyable T, auto I> std::array<T, I> arr = getArr();
>>>>>>> template <std::size_t... I> [[maybe_unused]] std::index_sequence<I...> seq = std::index_sequence_for<Args...>();
>>>>>>>
>>>>>>> Then we don't need to reinvent the syntax for parameters.
>>>>>
>>>>> That syntax is already in use for variable templates. Maybe named deduction is at block scope and variable templates are at namespace scope, but that kind of overloading of meaning is pretty horrible - `static` is bad enough.
>>>>>
>>>>>> Let's re-examine the problem that people seem to want to solve.
>>>>>>
>>>>>> My understanding was that the principal problem was that you want to
>>>>>> gain access to the actual typename that the placeholder deduction
>>>>>> syntax yields, and sticking a `using name = decltype(var_name);` is
>>>>>> both wordy and error-prone (I deliberately did that wrong, for
>>>>>> example).
>>>>>>
>>>>>> The main reason people deduce types is because they don't want to have
>>>>>> to type out the full name of the type
>>>>>
>>>>> or because the type is unnameable, or because it's dependent, or because the code you're calling could change its return type and so typing it out is a hostage to fortune.
>>>>>
>>>>>> (or because it's already
>>>>>> mentioned in the initializing expression).
>>>>>
>>>>> If you're using AAA with types on the RHS then you don't need to deduce them again, so you wouldn't need named deduction.
>>>>>
>>>>>> So it seems to me that
>>>>>> injecting a bunch more words into such a declaration is...
>>>>>> counter-productive.
>>>>>>
>>>>>> Yes, any of these declarations might be useful. But... are they really
>>>>>> *that* useful? So useful that we want to type out (and read) all of
>>>>>> that?
>>>>>
>>>>> We are proposing that a single statement introduce not just potentially multiple entity names, but also potentially multiple type aliases (also, maybe, packs, templates, concepts). This is a novel challenge for compilers and other tools, and it needs *some* introducing syntax to shunt the parser down the new code paths; lexing is difficult enough as it is.
>>>>>
>>>>> If `using` is too much typing, how about the introducer being `auto <`? It seems that the lexer should be able to detect that pretty much immediately.
>>>>>
>>>>> auto<class T> T var = foo();
>>>>> // etc.
Received on 2022-09-28 18:33:15