C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Named auto

From: Edward Catmur <ecatmur_at_[hidden]>
Date: Thu, 29 Sep 2022 12:46:22 +0100
On Wed, 28 Sept 2022 at 19:33, Keenan Horrigan <friedkeenan_at_[hidden]>
wrote:

> > 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.
>

Here's a couple of examples in just one file:

https://github.com/fmtlib/fmt/blob/0ccaed3a6c745ed2a625b8d6531111ba668e4fea/include/fmt/compile.h#L206-L207
https://github.com/fmtlib/fmt/blob/0ccaed3a6c745ed2a625b8d6531111ba668e4fea/include/fmt/compile.h#L317-L318
https://github.com/fmtlib/fmt/blob/0ccaed3a6c745ed2a625b8d6531111ba668e4fea/include/fmt/compile.h#L541-L542
https://github.com/fmtlib/fmt/blob/0ccaed3a6c745ed2a625b8d6531111ba668e4fea/include/fmt/compile.h#L600-L601

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.
>

The issues I have with that syntax are:
* looks like it would be difficult/ambiguous to parse/lex (by compilers,
editors, etc.)
* excessively terse - nowhere else do we introduce a type name into scope
without a keyword preceding it
* can't pattern match, deduce non-types or more than one type

For that last point, it means that that syntax would not be a complete
replacement for explicit function template syntax, nor for decltype (+
worse!) at block scope, so we'd have yet more syntax to teach. I don't
think much of the claim that C++ is overly complex, but I do feel that
additions should try to simplify the "modern" subset of the language, i.e.
those parts that are sufficient to write new code.

------- 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-29 11:46:35