Re: [lambda] Latest experimental polymorphic lambda patches
Hi Jason, On 23.04.2013 14:42, Jason Merrill wrote: On 22.04.2013 17:42, Jason Merrill wrote: > On 08/10/2009 08:33 PM, Adam Butcher wrote: > > Attached are my latest experimental polymorphic lambda patches > > against the latest lambda branch. > > Polymorphic lambdas were voted in for C++14 at the meeting this past > week; are you interested in resuming this work? > Yes very interested. I have been meaning to get around to remaking the patch against 4.8 (and previously 4.7) for ages now. Though getting the time to do so has been, and will likely continue to be, a problem what with work, fatherhood and other commitments. Since the gcc/cp code base is significantly different now from the old lambda branch where the changes were originally made in 2009, my intent was to remake the changes from scratch implementing the entirety of N3559 (now N3649) and, at least, the explicit template parameter specifier syntax from N3560 (though I'm very interested getting the single expression body syntax working also). I have no problem with someone else getting on with this as I can't guarantee consistent availability for it but I will try to get some time to at least look at my previous aborted efforts to get the changes applied to the more recent mainlines (I have some git repos around here and at work with some incomplete changes). I will see how far I got with these and maybe post a few patches. It is highly likely though that these were just abortive attempts to merge the previous stuff or incomplete restarts. > The proposal will be at > > http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3649.html > It's now been posted at http://isocpp.org/files/papers/N3649.html Cheers, Adam
Re: [lambda] Latest experimental polymorphic lambda patches
On 04/22/2013 12:42 PM, Jason Merrill wrote: The proposal will be at http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3649.html It's now been posted at http://isocpp.org/files/papers/N3649.html Jason
Re: [lambda] Latest experimental polymorphic lambda patches
On 08/10/2009 08:33 PM, Adam Butcher wrote: Attached are my latest experimental polymorphic lambda patches against the latest lambda branch. Polymorphic lambdas were voted in for C++14 at the meeting this past week; are you interested in resuming this work? The proposal will be at http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3649.html once the post-meeting mailing is released, or I can send you a copy if you'd like to see it sooner. Jason
Re: [lambda] Latest experimental polymorphic lambda patches
On Tue, Aug 11, 2009 at 7:05 AM, Jason Merrill wrote: > A few comments: > >> /* XXX: Any way to get current location? */ > > input_location Just a late comment: using input_location is generally not a good idea. Every token in the parser has a location. That should be the source of all location information. Using input_location generally gives you the wrong column and sometimes even gives you the wrong line. We should eventually eliminate it. Ian
Re: [lambda] Latest experimental polymorphic lambda patches
On 08/11/2009 11:20 AM, Adam Butcher wrote: Ah okay. Would it be worth enhancing the tree-vec interface to include block reallocation with size doubling and end marking to allow for more efficient reallocation? I don't think so; I expect that would end up being less space-efficient, since in most cases we know in advance exactly how much space we need. Feel free to add a realloc_tree_vec function to gcc/tree.c, though. Such a structural change maybe hidden by the macro front-end. I wonder how many uses of make_tree_vec don't ggc_free their previous tree-vec when using it in a 'realloc' way. That just means they'll live until the next GC pass, not a big deal. Jason
Re: [lambda] Latest experimental polymorphic lambda patches
Thanks for the feedback. Jason Merrill wrote: >Adam Butcher wrote: >> The following examples produce >> equivalent functions: >> >>1. [] (auto x, auto& y, auto const& z) { return x + y + z; } >>2. [] (X x, Y& y, Z const& z) { >> return x + y + z; } >>3. [] (auto x, Y& y, auto const& z) { return x + y + z; } > > IMO #3 should not be equivalent to the others; the auto template parms > should come after Y. And I believe that's currently the case with your > patch. > Sorry, I wasn't clear. I meant that they generate the same function from the user's point of view, not that their internals are the same. I didn't mean to suggest that the order of their template parameters would be the same. It was meant to demonstrate that using 'auto' and specifying an explicit unique typename are equivalent from a client point-of-view. You are correct that in #3's case the generated lambda is equivalent to: [] (__AutoT1 x, Y& y, __AutoT2 const& z) { return x + y + z; } Which is, from the user's perspective, equivalent to the lambda functions defined by #1 and #2, just that the order of the template arguments are different. I accept that this does give a different function signature in terms of template parameter indexes. I've assumed that explicit specialization of the call operator is not useful and therefore the user would never see the final template parameter list and would not need to understand its ordering. > If you save up all the auto parms until the end and then assign indices > and adjust the parm vector then, that will avoid reallocating the vector > each time. > Yes that would be better. > But don't worry about tidying tree_node_counts; it just tracks how many > of a particular tree code we create, not how many we currently have. > Normal GC throws away lots of stuff without adjusting the counts. > Ah okay. Would it be worth enhancing the tree-vec interface to include block reallocation with size doubling and end marking to allow for more efficient reallocation? Such a structural change maybe hidden by the macro front-end. I wonder how many uses of make_tree_vec don't ggcfree their previous tree-vec when using it in a 'realloc' way. A quick grep for 'make_tree_vec\>' in gcc reveals about 80 uses, many of which with an arithmetic expression as its argument. I wonder how many of these might benefit from such an allocation scheme and how many would be impaired by it? Maybe its an insignificant issue. >> + /* XXX: Maybe to loop rather than recurse here? */ > > At -O2, the GCC optimizers should convert tail recursion into looping. > Great, no worries there then. >> + if (type_dependent_expression_p (expr)) >> +/* TODO: Should defer this until instantiation rather than using >> + decltype. */ >> +return_type = type_decays_to (non_reference (finish_decltype_type >> + (expr, /*id_expression_or_member_access_p=*/false))); > > Definitely need to defer it; type_decays_to and non_reference don't work > on DECLTYPE_TYPE. > I thought as much -- I assume it's just trying to strip non-existent qualifiers from `decltype(expr)' which amounts to a no-op. Thanks again for the feedback. I'll try to get deferred return type deduction working when I get some time. Working through that will probably end up sorting some of the issues with dependent return type deduction inside templates. Cheers, Adam
Re: [lambda] Latest experimental polymorphic lambda patches
A few comments: /* XXX: Any way to get current location? */ input_location The following examples produce equivalent functions: 1. [] (auto x, auto& y, auto const& z) { return x + y + z; } 2. [] (X x, Y& y, Z const& z) { return x + y + z; } 3. [] (auto x, Y& y, auto const& z) { return x + y + z; } IMO #3 should not be equivalent to the others; the auto template parms should come after Y. And I believe that's currently the case with your patch. In fact it would be better + to keep building a tree list and only flatten into + a vector after parsing the parameter list. */ If you save up all the auto parms until the end and then assign indices and adjust the parm vector then, that will avoid reallocating the vector each time. But don't worry about tidying tree_node_counts; it just tracks how many of a particular tree code we create, not how many we currently have. Normal GC throws away lots of stuff without adjusting the counts. + /* XXX: Maybe to loop rather than recurse here? */ At -O2, the GCC optimizers should convert tail recursion into looping. + if (type_dependent_expression_p (expr)) +/* TODO: Should defer this until instantiation rather than using + decltype. */ +return_type = type_decays_to (non_reference (finish_decltype_type + (expr, /*id_expression_or_member_access_p=*/false))); Definitely need to defer it; type_decays_to and non_reference don't work on DECLTYPE_TYPE. Jason
[lambda] Latest experimental polymorphic lambda patches
Attached are my latest experimental polymorphic lambda patches against the latest lambda branch. Template parameters implied by auto in the lambda's call parameter list no longer lose qualifiers. The following examples produce equivalent functions: 1. [] (auto x, auto& y, auto const& z) { return x + y + z; } 2. [] (X x, Y& y, Z const& z) { return x + y + z; } 3. [] (auto x, Y& y, auto const& z) { return x + y + z; } Note that using an explicit template parameter is only really useful if you wish to either a) ensure consistency among a number of call parameters, b) use a non-type template parameter or c) specify a call parameter type constraint (or other complex parameter type). I have flattened the latest auto-template-inference changes with the previous one to remove complexity due to re-arrangement. In particular it no longer abuses decl.c -- those changes have currently moved into parser.c but it is pretty clear that they have more in common with pt.c owing to a need to pull in some local static functions from that file. I intend to split or move parts (or most) into pt.c on my next attempt (if I get time to make one!) There are currently many issues: - efficiency of template parameter list growing. - implicit return type deduction doesn't work from inside a template context if the lambda's return expression involves a dependent type. Specifying decltype explicitly in these contexts is a workaround. - dependent inferred return type needs to be deferred and decayed. This may go some way (all the way?) to solving the previous point. - location of implementation. - only a few use-cases have been considered. Adam Summary: Subject: [PATCH] First pass polymorphic lambda support. This commit adds experimental support for an optional template-parameter-list in angle-brackets at the start of a lambda-parameter-declaration. --- Subject: [PATCH] Restored decltype in lambda return type deduction for when expr is dependent. --- Subject: [PATCH] Second version of typename inference from auto parameters in lambda call operator. Still quite hacky -- though better than previous. No longer loses qualifiers on replaced auto parameters so is functionally closer to what's really needed. - This is just a behavioural proof to find out how things work. - Need to shuffle some stuff into pt.c and do away with code dup. - Not sure how to free tree_vec's and tidy up the counts and sizes (looks like they're only intended to grow.) - Added `type_decays_to (non_reference (finish_decltype_type' as suggested by Jason. Currently doesn't remove cv-quals from non-class types though. Need to treat implicit return type differently for dependent types -- should defer and mark that it needs to be computed later. --- 0001-First-pass-polymorphic-lambda-support.patch Description: Binary data 0002-Restored-decltype-in-lambda-return-type-deduction-fo.patch Description: Binary data 0003-Second-version-of-typename-inference-from-auto-param.patch Description: Binary data