Hi,The draft can be viewed at:http://jamboree.github.io/designator-draft.htmlThe prototype based on Clang can be found at:I'm not sure if it's proper to submit a new proposal before C++17 is settled, anyway, I'd like to make this work public now.
Thanks
obj.f(default, b)
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/e2d5660e-2cf7-4107-868d-7027bdce344f%40isocpp.org.
On 13 April 2016 at 22:31, Richard Smith <ric...@metafoo.co.uk> wrote:
> This looks more or less like how I'd always imagined designated initializers
> would work in C++. Thanks for writing this! One question, you say:
>
> "3.2.1.1 Function redeclaration
>
> If a function is declared with designatable parameters and/or default
> arguments, it cannot be redeclared with designatable parameters and/or
> default arguments, otherwise, the program is ill-formed."
>
> This seems very strange to me. I would expect that:
> a) every declaration of the same function must specify the same designatable
> parameters, with the same names, and
> b) perhaps overloading on designated parameter names should be permitted
>
> One example of why (b) would be useful:
>
> struct my_complex {
> my_complex(double .rho, double .theta);
> my_complex(double .real, double .imag);
> };
>
> Here, these constructors could *only* be called with designated parameter
> names, because any non-designated call would be ambiguous.
Just out of curiosity, how do you plan to mangle those names?
The
reason why I ask is that
sure, yeah, such overloading could be handy, but it also introduces
additional complexity
to deal with.
Hi,The draft can be viewed at:http://jamboree.github.io/designator-draft.htmlThe prototype based on Clang can be found at:
I'm not sure if it's proper to submit a new proposal before C++17 is settled, anyway, I'd like to make this work public now.Please let me know if anyone wants to be a champion if it's submitted.Thanks
--
2) a "works automatically" proposal comes in. The response is "well,
that doesn't work with the standard library,
and authors of other libraries don't want to have the introduced
requirement to provide stable names without their opt-in,
so <insert the work-arounds again>..."
On Wed, Apr 13, 2016 at 1:33 AM, TONGARI J <tong...@gmail.com> wrote:Hi,The draft can be viewed at:http://jamboree.github.io/designator-draft.htmlThe prototype based on Clang can be found at:Have you considered the interaction of this proposal with forwarding functions and with types like std::function? I would find it problematic if correct forwarding is not possible for functions with designated parameters. I think you will encounter resistance if something like this is not possible, and we have no known path forward to support it:void f(int .foo, int .bar);std::function<void(int .foo, int .bar)> fn = f;fn(.bar = 1, .foo = 2);One possible way to make this work could be:(a) designated parameter names to become part of a function type, and
(b) add a way to write a function template that accepts a pack of designated parameters, capturing both the names and the values, and allowing both to be used when forwarding
Am Mittwoch, 13. April 2016 22:58:45 UTC+2 schrieb Richard Smith:On Wed, Apr 13, 2016 at 1:33 AM, TONGARI J <tong...@gmail.com> wrote:Hi,The draft can be viewed at:http://jamboree.github.io/designator-draft.htmlThe prototype based on Clang can be found at:Have you considered the interaction of this proposal with forwarding functions and with types like std::function? I would find it problematic if correct forwarding is not possible for functions with designated parameters. I think you will encounter resistance if something like this is not possible, and we have no known path forward to support it:void f(int .foo, int .bar);std::function<void(int .foo, int .bar)> fn = f;fn(.bar = 1, .foo = 2);One possible way to make this work could be:(a) designated parameter names to become part of a function type, andWhat are the downsides of disignated parameters being part of a function type?
(b) add a way to write a function template that accepts a pack of designated parameters, capturing both the names and the values, and allowing both to be used when forwardingWouldn't this require some kind of reflection mechanism? (To save the names).
--But (b) in particular seems like it would add a lot of complexity. I hope there's a better alternative.--I'm not sure if it's proper to submit a new proposal before C++17 is settled, anyway, I'd like to make this work public now.Please let me know if anyone wants to be a champion if it's submitted.Thanks
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/e2d5660e-2cf7-4107-868d-7027bdce344f%40isocpp.org.
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/84335887-a9d3-4ef1-97eb-921220b1fb0e%40isocpp.org.
This looks more or less like how I'd always imagined designated initializers would work in C++. Thanks for writing this! One question, you say:"3.2.1.1 Function redeclarationIf a function is declared with designatable parameters and/or default arguments, it cannot be redeclared with designatable parameters and/or default arguments, otherwise, the program is ill-formed."This seems very strange to me. I would expect that:a) every declaration of the same function must specify the same designatable parameters, with the same names, andb) perhaps overloading on designated parameter names should be permittedOne example of why (b) would be useful:struct my_complex {my_complex(double .rho, double .theta);my_complex(double .real, double .imag);};Here, these constructors could *only* be called with designated parameter names, because any non-designated call would be ambiguous.
void f(int .a, int .b);
void f(int .x, int .y);
void f(int a = 1);
void f(int a = 1);
Have you considered the interaction of this proposal with forwarding functions and with types like std::function? I would find it problematic if correct forwarding is not possible for functions with designated parameters. I think you will encounter resistance if something like this is not possible, and we have no known path forward to support it:void f(int .foo, int .bar);std::function<void(int .foo, int .bar)> fn = f;fn(.bar = 1, .foo = 2);One possible way to make this work could be:(a) designated parameter names to become part of a function type, and
(b) add a way to write a function template that accepts a pack of designated parameters, capturing both the names and the values, and allowing both to be used when forwarding
But (b) in particular seems like it would add a lot of complexity. I hope there's a better alternative.
#if has_designatable_parameters
#define NAMED_PARAM(p) .p
#else
#define NAMED_PARAM(p) p
#endif
void f(int NAMED_PARAM(a)); // use it now
Not if we don't allow overloading on names?²
// header
int foo(int [[named("bar")]] maybe_bar);
// implementation
int foo(int not_bar) // note: API name not repeated
{ ... }
int foo(int .bar);
int foo(int not_bar);
int foo(int .bar);
int foo(int .not_bar);
Hi Richard,
On Thursday, April 14, 2016 at 3:31:20 AM UTC+8, Richard Smith wrote:This looks more or less like how I'd always imagined designated initializers would work in C++. Thanks for writing this! One question, you say:"3.2.1.1 Function redeclarationIf a function is declared with designatable parameters and/or default arguments, it cannot be redeclared with designatable parameters and/or default arguments, otherwise, the program is ill-formed."This seems very strange to me. I would expect that:a) every declaration of the same function must specify the same designatable parameters, with the same names, andb) perhaps overloading on designated parameter names should be permittedOne example of why (b) would be useful:struct my_complex {my_complex(double .rho, double .theta);my_complex(double .real, double .imag);};Here, these constructors could *only* be called with designated parameter names, because any non-designated call would be ambiguous.There are some principles I set when designing the feature:* Don't interfere with the type system
* Don't require ABI changes
* Don't complicate the function declarationI did consider allowing multiple function declarations with different designators in early stage, but the idea soon got dropped.The idea was different from what you would expect though:
void f(int .a, int .b);
void f(int .x, int .y);The 2 declarations will be the same function, not 2 overloads. This may be useful in some case but also confusing and may complicate the implementation so I dropped it.As for allowing multiple identical declarations, my argument against it is for consistency, consider default arguments:
void f(int a = 1);
void f(int a = 1);It's not allowed even though the 2 are lexically identical, and I think the same should apply to designatable parameters as well.What you suggested in the my_complex example is to make them overloads, which is a design decision I don't want to take in this proposal.Have you considered the interaction of this proposal with forwarding functions and with types like std::function? I would find it problematic if correct forwarding is not possible for functions with designated parameters. I think you will encounter resistance if something like this is not possible, and we have no known path forward to support it:void f(int .foo, int .bar);std::function<void(int .foo, int .bar)> fn = f;fn(.bar = 1, .foo = 2);One possible way to make this work could be:(a) designated parameter names to become part of a function type, and(b) add a way to write a function template that accepts a pack of designated parameters, capturing both the names and the values, and allowing both to be used when forwardingBut (b) in particular seems like it would add a lot of complexity. I hope there's a better alternative.Actually, forwarding function is explicitly listed in my non-goals, that's why I deliberately disable the indirect use in the end of section 3.2.3.
If I were going to support forwarding functions, that means I have to make designatable parameters part of the type as you suggested in (a), and that breaks my design principles.My choice for designated arguments is much like parameter pack, that is, don't make them first class objects.I should emphasize how reluctant I am in interfering with the type system - it's a no-go for me if adding designatable parameters to existing API would break the ABI.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/neop0a%24n8b%241%40ger.gmane.org.
Ville Voutilainen <ville.vo...@gmail.com>: Apr 14 12:55AM +0300
…I have indeed toyed with the idea of writing a rumination paper on why named arguments have failed, as far as I know and have observed it (which doesn’t cover all the old proposals), but perhaps I was kinda hoping I wouldn’t need to. :)
⋮
This looks like a very well written and presented proposal. I think it could be better evaluated though if there were more discussion about it in the context of existing API designs that have been created with languages that already have the features the proposed. In particular regarding named function parameters.
My own experience of using libraries with extensive numbers of parameters are the Microsoft COM object libraries that lay behind applications like Microsoft Word and Excel etc.
See here:
https://msdn.microsoft.com/en-us/library/kw65a0we.aspx
https://msdn.microsoft.com/en-us/library/office/ff194068.aspx
This proposal would seem to make using such libraries a lot easier?
As important to me though is whether people consider such API designs good? And do we want to encourage more of them by making them easier?
So to my mind we have to evaluate this proposal against real existing APIs while also determining if those real API's need to be as complex as they are so we. This should help us verify if this proposal helps with using such API's and reveal whether an alternative API design or language feature would be better to get the kinds of api's we do want.
I don't feel I can appreciate the value of this proposal without such discussion
If more recent API's could be discussed it might even more relevant. I am thinking some of the web driving api's (think setting html attributes from code etc). like those in the ASP.NET's MVC API, which are C# API's. Maybe that could be addressed? Perhaps a lot of lessons/encouragement could be learned from that?
So I think ultimately we have to compare this proposal against these types of API’s and evaluate the alternatives to appreciate this proposal, don't we?
Thanks for the proposal so far.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/3549854.PvpFWvaERv%40tjmaciei-mobl4.
Thiago, this is an evil (but welcome!) example.I read the proposal and I like it in general; in that area, it's among the good ones.
Contrary to some, I've been quite often in a situation where changing argument names in functions was important, and in situations where the documentary names in a .h/.hpp file were different from the names used in the function's implementation. I would be inclined to support a proposal that showed how named arguments fit in with this reality of software development.
On Wed, Apr 13, 2016 at 8:09 PM, TONGARI J <tong...@gmail.com> wrote:There are some principles I set when designing the feature:* Don't interfere with the type systemPlease allow me to suggest an alternative principle: integrate into the existing language.
Far too often, people proposing features make the mistake of making their feature be its own special island that has rules different from the rest of the language. This is a trap to be avoided. Language continuity is important: C++20 should look and feel like a development of C++17, in order to make it easier for programmers and programs to adapt, but we don't get there by minimizing the amount of change to the language or specification, we get there by making the changes complete so they feel like an extension of what came before.A feature that does not integrate into the type system, but whose design would naturally lead to type system changes, is flawed. In my opinion, you should first design the feature, and then analyze the type system implications, not the other way around. (And if that leads to no type system changes, that's fine, of course.)* Don't require ABI changesI think you should distinguish between "don't change the ABI of existing libraries" and "don't change the ABI when designated parameters are added to an interface". The first seems like an important principle. The second, less so -- as long as the library maintainer still gets to control their ABI as they see fit.
Actually, forwarding function is explicitly listed in my non-goals, that's why I deliberately disable the indirect use in the end of section 3.2.3.The fact that this is a non-goal is going to make your proposal very unappealing to some portion of the committee.If I were going to support forwarding functions, that means I have to make designatable parameters part of the type as you suggested in (a), and that breaks my design principles.My choice for designated arguments is much like parameter pack, that is, don't make them first class objects.I should emphasize how reluctant I am in interfering with the type system - it's a no-go for me if adding designatable parameters to existing API would break the ABI.Adding parameters with default arguments to existing API would break the ABI too
as would many other API changes. With a suitable overload resolution rule, I'd expect to be able to change an API that does this:struct A {void f(int a, int b);};... to do this:struct A {void f(int a, int b);void f(int .a, int .b) { f(a, b); }};... as a non-breaking change (except if someone is taking the address of the function), for people who need perfect ABI compatibility.
void f(int .a, int .b);
void f(int .b, int .a);
On Friday, April 15, 2016 at 1:57:27 AM UTC+8, Richard Smith wrote:On Wed, Apr 13, 2016 at 8:09 PM, TONGARI J <tong...@gmail.com> wrote:There are some principles I set when designing the feature:* Don't interfere with the type systemPlease allow me to suggest an alternative principle: integrate into the existing language.Well, it does integrate into the existing language.I know what I want for this feature, and smooth adoption w/o binary incompatibility is what I desire, hence the principle.Far too often, people proposing features make the mistake of making their feature be its own special island that has rules different from the rest of the language. This is a trap to be avoided. Language continuity is important: C++20 should look and feel like a development of C++17, in order to make it easier for programmers and programs to adapt, but we don't get there by minimizing the amount of change to the language or specification, we get there by making the changes complete so they feel like an extension of what came before.A feature that does not integrate into the type system, but whose design would naturally lead to type system changes, is flawed. In my opinion, you should first design the feature, and then analyze the type system implications, not the other way around. (And if that leads to no type system changes, that's fine, of course.)* Don't require ABI changesI think you should distinguish between "don't change the ABI of existing libraries" and "don't change the ABI when designated parameters are added to an interface". The first seems like an important principle. The second, less so -- as long as the library maintainer still gets to control their ABI as they see fit.I have a feeling that there would be a resistance to adopt designatable parameters because of ABI incompatibility.Actually, forwarding function is explicitly listed in my non-goals, that's why I deliberately disable the indirect use in the end of section 3.2.3.The fact that this is a non-goal is going to make your proposal very unappealing to some portion of the committee.If I were going to support forwarding functions, that means I have to make designatable parameters part of the type as you suggested in (a), and that breaks my design principles.My choice for designated arguments is much like parameter pack, that is, don't make them first class objects.I should emphasize how reluctant I am in interfering with the type system - it's a no-go for me if adding designatable parameters to existing API would break the ABI.Adding parameters with default arguments to existing API would break the ABI tooI don't see any difference in the generated LLVM IR with or without default arguments, any example how it affects the ABI?
as would many other API changes. With a suitable overload resolution rule, I'd expect to be able to change an API that does this:struct A {void f(int a, int b);};... to do this:struct A {void f(int a, int b);void f(int .a, int .b) { f(a, b); }};... as a non-breaking change (except if someone is taking the address of the function), for people who need perfect ABI compatibility.So call A{}.f(0, 1)is ruled by some conversion sequence?
What about:
void f(int .a, int .b);
void f(int .b, int .a);Is the overload valid? Is f(.a = 0, .b = 1) ambiguous?
And how would you forward the designators for, say, std::function?
Hi,The draft can be viewed at:http://jamboree.github.io/designator-draft.htmlThe prototype based on Clang can be found at:I'm not sure if it's proper to submit a new proposal before C++17 is settled, anyway, I'd like to make this work public now.Please let me know if anyone wants to be a champion if it's submitted.Thanks
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/e2d5660e-2cf7-4107-868d-7027bdce344f%40isocpp.org.
Hi Tongari,I've actually been working on a designated initialization proposal. My current thinking on the matter was to propose an uncontroversial first step of motivating and adopting in C++ a strict subset of the existing C feature (just the parts that clearly make sense for C++), and then showing how this fits into a large family of possible future roadmaps, such as the one you outline in your proposal.My reaction to reading your proposal is that you are being too ambitious. It would be multiple years of work to get standardized such a large feature of "uniform designators" across function calls, aggregate initialization and other types of initialization - and that is assuming consensus can be achieved at all, which given the history of named parameter proposals, is a long shot.
That's why I think breaking off and nailing down a smaller first step would be more practical. The C feature has extensive existing practice that can be appealed to, so I think a subset-only proposal has a much better chance of getting through. Once that gets in and is nailed down, a proposal to extend an existing feature will be much better received than trying to do everything at once.
Hi Andrew,
On Friday, April 15, 2016 at 11:36:59 AM UTC+8, Andrew Tomazos wrote:Hi Tongari,I've actually been working on a designated initialization proposal. My current thinking on the matter was to propose an uncontroversial first step of motivating and adopting in C++ a strict subset of the existing C feature (just the parts that clearly make sense for C++), and then showing how this fits into a large family of possible future roadmaps, such as the one you outline in your proposal.My reaction to reading your proposal is that you are being too ambitious. It would be multiple years of work to get standardized such a large feature of "uniform designators" across function calls, aggregate initialization and other types of initialization - and that is assuming consensus can be achieved at all, which given the history of named parameter proposals, is a long shot.Obviously, Richard is much more ambitious than me ;)What I proposed is really the minimal, simplest model in practice.That's why I think breaking off and nailing down a smaller first step would be more practical. The C feature has extensive existing practice that can be appealed to, so I think a subset-only proposal has a much better chance of getting through. Once that gets in and is nailed down, a proposal to extend an existing feature will be much better received than trying to do everything at once.I'm not sure if you're an advocator of the alternative described in section 5.7, which I already showed would be a dead end for C++, or you just want to cutoff the proposal to an even smaller subset.
Anyway, Richard seems to have the exact opposite opinion that we should give a more comprehensive proposal, quoting from his mail:we don't get there by minimizing the amount of change to the language or specification, we get there by making the changes complete so they feel like an extension of what came before.
We could imagine something like this:
template<typename F, designator ...D, typename ...T> decltype(auto) f(F f, T &&... .D) {
return f(0, .D = std::forward<T>(D) ...);
}
That is: a new kind of template parameter representing a designator, and designator names are looked up to see if they name such a parameter before assuming they're an opaque identifier. (Plus a notional "empty designator" that is deduced in cases where no designator is specified.) I don't think I like this approach, and as noted, I hope there's a better answer.
template<designator ...D, typename F, typename ...T> decltype(auto) call(F f, T && D ...t) { return f(0, D = std::forward<T>(t) ...);
}
call(f, .b = 1, .a = 2); // ok?
template<typename F, typename ...T> decltype(auto) call(F f, T && ...t) {
return f(0, std::forward<T>(t) ...);
}
call<.a, .b>(f, .b = 1, .a = 2);
On Fri, Apr 15, 2016 at 5:56 AM, TONGARI J <tong...@gmail.com> wrote:Hi Andrew,
On Friday, April 15, 2016 at 11:36:59 AM UTC+8, Andrew Tomazos wrote:Hi Tongari,I've actually been working on a designated initialization proposal. My current thinking on the matter was to propose an uncontroversial first step of motivating and adopting in C++ a strict subset of the existing C feature (just the parts that clearly make sense for C++), and then showing how this fits into a large family of possible future roadmaps, such as the one you outline in your proposal.My reaction to reading your proposal is that you are being too ambitious. It would be multiple years of work to get standardized such a large feature of "uniform designators" across function calls, aggregate initialization and other types of initialization - and that is assuming consensus can be achieved at all, which given the history of named parameter proposals, is a long shot.Obviously, Richard is much more ambitious than me ;)What I proposed is really the minimal, simplest model in practice.That's why I think breaking off and nailing down a smaller first step would be more practical. The C feature has extensive existing practice that can be appealed to, so I think a subset-only proposal has a much better chance of getting through. Once that gets in and is nailed down, a proposal to extend an existing feature will be much better received than trying to do everything at once.I'm not sure if you're an advocator of the alternative described in section 5.7, which I already showed would be a dead end for C++, or you just want to cutoff the proposal to an even smaller subset.An even smaller subset. Consider it as the intersection of your proposal and the existing C feature. This would necessarily be forward compatible with your proposal, as the intersection is a subset of your proposal. The people that support your proposal must also support such a step. Additionally, there may be people that don't support your proposal in entirety, but support such a step. Therefore that step has a better chance of achieving consensus than your proposal.
I think it's already too late to put new work into C++17.As proposals are approved they are applied to the working draft. Multiple proposals that build upon one another can be applied to the working draft between a single release cycle of the IS.Having said that, I think C++20 is too ambitious a target for your entire proposal. I consider it about twice as large as defaulted comparisons.Default comparisons were at the stage of your proposal in late 2013 by Oleg Smolsky (informal paper, prototype impl):and it's not clear yet whether they will just squeak into C++17.I don't think there is much risk of people getting a "syntax-sugar alternative" instead of a "formal approach". All alternative approaches will be discussed and considered ad nauseam for many years before selecting and standardizing one or none.As long as whatever the first step proposal is, is shown to be forward compatible with all the feasible approaches we might want to select later, I think it can achieve consensus, and C++20 is a realistic target.
On 2016-04-15 12:50, Thiago Macieira wrote:
> I recommend you stop talking about attributes, as this lowers the chance of
> the feature being accepted. Not only would the feature itself be fighting to
> prove its worth (it's been rejected more than once), using attributes means
> fighting against established rules over attributes.
>
> Remember that this feature is asking for differences in overload resolution
> and has consequences for the ABI. That's way outside what attributes are meant
> to do.
It *doesn't* have consequences for the ABI; Tongari has been rather
explicit on this point. I suspect it isn't "asking for differences in
overload resolution" either; not, at least, in the sense I suspect you
are thinking.