C++ Logo

STD-PROPOSALS

Advanced search

Subject: Re: [std-proposals] Meta types
From: Gašper Ažman (gasper.azman_at_[hidden])
Date: 2020-02-05 07:19:07


Jake,

Seems to me like doing what you describe well is exactly what the
executors' sender/receiver model is built for. Look at libunifex for an
example.

On Wed, Feb 5, 2020 at 12:27 AM Garrett May via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> On Tue, 4 Feb 2020, 11:27 am Jake Arkinstall via Std-Proposals, <
> std-proposals_at_[hidden]> wrote:
>
> This proposal will likely also include a mechanism for switching on types.
> I'm also thinking of using template/concept syntax in place of var.
>
>
> I don't believe that template/concept syntax would be appropriate here
> unless changes were made to what templates/concepts can do. That's because
> what we have here is return types that are not dependent on templates, nor
> on concepts, but instead on *branches*.
>
> Because this would be designed to be "switching on types", perhaps the
> following would be appropriate syntax:
>
> switch(auto) halve(unsigned int i){
> if(i % 2 == 0){
> // branch for unsigned int
> return i / 2;
> } else{
> // branch for double
> return i * 0.5;
> }
> }
>
> And probably for consistency, a switch(decltype(auto)) would be available.
>
> As for the yielding concept, this seems like a second proposal, because
> its basis is mainly on the ability to yield (a lazy idea) rather than
> "switching on types".
>
> This is just my two pence. It seems along the same lines as more recent
> proposals, such as expansion statements (template for).
>
>
> On Tue, 4 Feb 2020, 4:18 pm Jake Arkinstall via Std-Proposals, <
> std-proposals_at_[hidden]> wrote:
>
>> The '14 version you have provided is exactly what my proposal generates,
>> but without the indirection. Much of my code involves exactly this pattern,
>> stitched together with a pipeline builder struct, cringy use of the >>
>> operator and helper macros for yield, etc. It suffices, but it's crying out
>> for either a new language, a preprocessor, or a new language feature.
>>
>> You'll also note that debugging through the callback approach is nothing
>> less than horrific, especially if any pipeline building code is involved
>> (just like with variants). I can't imagine this changing while the code
>> being written is in the form of callbacks.
>>
>> The reason is that given N components of the pipeline (each yielding a
>> new value to be passed to the next), an unhandled type from component N-1
>> to component N bubbles an error generating from the first call to component
>> 0. Deciphering the message that comes out is fun, to say the least, and
>> while static_assert is unable to add typenames etc there's no real way
>> around it.
>>
>> As a language feature, it's easy. The compiler is aware of what you're
>> trying to do, and can provide useful information when you get it wrong.
>>
>> On Tue, 4 Feb 2020, 15:16 Arthur O'Dwyer via Std-Proposals, <
>> std-proposals_at_[hidden]> wrote:
>>
>>> On Tue, Feb 4, 2020 at 8:16 AM Михаил Найденов via Std-Proposals <
>>> std-proposals_at_[hidden]> wrote:
>>>
>>>> This definitely steps into both "language variant" and Pattern Matching
>>>> territory.
>>>> I am not sure what optimization we can expect from "language variant",
>>>> but PM should give us close to your ideal code
>>>>
>>>> void main(int argc, char const* const* argv){
>>>> inspect(halve(args))
>>>> Numeric x => std::cout << "You passed 2*(" << x << ")
>>>> arguments\n";
>>>> return 0;
>>>> }
>>>>
>>>
>>> The current Pattern Matching proposal doesn't give the programmer any
>>> way to write `halve` so that it can actually return either of two
>>> alternative types (`unsigned` or `double`) depending on a *runtime*
>>> condition (the evenness of the runtime argument).
>>>
>>> However, I don't see anything wrong with the existing C++14 language
>>> solution to OP's problem. It's not worth pursuing any crazy core-language
>>> gymnastics unless you can provide a use-case that isn't already solvable
>>> idiomatically in C++14 (17, 20). Here's the '14 solution:
>>>
>>> template<class F>
>>> void halve(unsigned i, const F& f) {
>>> if (i % 2 == 0) {
>>> f(i / 2);
>>> } else {
>>> f(i * 0.5);
>>> }
>>> }
>>>
>>> int main(int argc, char**) {
>>> halve(argc, [](auto x) {
>>> std::cout << "You passed 2*(" << x << ") arguments\n";
>>> });
>>> return 0;
>>> }
>>>
>>> Short, readable, relatively easy to understand. Certainly easi*er* to
>>> understand than anything proposed in the OP.
>>>
>>> –Arthur
>>> --
>>> Std-Proposals mailing list
>>> Std-Proposals_at_[hidden]
>>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>>
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>



STD-PROPOSALS list run by herb.sutter at gmail.com

Standard Proposals Archives on Google Groups