Discussion:
[std-proposals] What do we want from named paramaters
Henry Miller
2018-08-16 17:44:58 UTC
Permalink
In the past couple months I've seen several proposals for names parameters. Each with a list of pros and cons, and because there are cons arguments against them. I think we need a discussion on what we want assuming some strawman acceptable syntax, and some thought of how many limitations in corner cases we are willing to accept.

I can think of 4 uses for names parameters. (If you don't understand these I have simple code examples)
1 . a function with more than one parameter of the same type is called with the parameters in the wrong order
* Some people want this to be a compilation error, some want the compiler to correct the problem and continue
2. a function wants to take the same type to mean different things in different contexts
3. it isn't obvious from the type alone what a parameter means
4. A function has a bunch of defaulted arguments and you want to change one of the latter ones without specifying all the others

First question: is this complete?
Second, which problems are worth solving?
Third, for problems worth solving, which is the better solution, and how strongly attached to it are you?

For the first the motivating code is something like:

class myMatrix {
T GetCell(int row, int column);
...
};

in code:
cell = matrix.GetCell(column, row);

This will compile just fine in C++17, but the code is undoubtedly wrong. In C++2n do you want this to be a compiler error, or correct code?


Second:
class point {
point(double x, double y);
point(double distance, double angle);
...
};

This code does not compile in C++17. Do we want to make this case work?


Third:
class myString {
int compare(myString, bool CaseSensitive);
...
};

in code
if(str.compare(otherString, false) == 0) ... // what does this mean, why would you call compare and not compare?

This code is legal C++17, but it is user hostile. False in the context of reading the function makes no intuitive sense. Qt has created an enum for this, but it can be argued that this is too heavy. (you may or may not agree with the argument)


Fourth:
// warning, marketing regularly changes the default value of this function
void foo(double a = 1234.5, int b = 6789);

foo(b:=1234);

This won't compile in C++17. However it seems like it would be useful to not clutter function calls with default parameters that you don't care about. In the case I gave it is a maintenance problem to update all uses of foo every time the defaults change, though I'm not sure if this is actually a common problem.
--
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/1534441498.3721109.1476442920.71D445BF%40webmail.messagingengine.com.
Nicol Bolas
2018-08-16 19:02:18 UTC
Permalink
Post by Henry Miller
In the past couple months I've seen several proposals for names
parameters. Each with a list of pros and cons, and because there are cons
arguments against them. I think we need a discussion on what we want
assuming some strawman acceptable syntax, and some thought of how many
limitations in corner cases we are willing to accept.
I can think of 4 uses for names parameters. (If you don't understand these
I have simple code examples)
1 . a function with more than one parameter of the same type is called
with the parameters in the wrong order
* Some people want this to be a compilation error, some want the
compiler to correct the problem and continue
2. a function wants to take the same type to mean different things in different contexts
3. it isn't obvious from the type alone what a parameter means
4. A function has a bunch of defaulted arguments and you want to change
one of the latter ones without specifying all the others
First question: is this complete?
Second, which problems are worth solving?
Third, for problems worth solving, which is the better solution, and how
strongly attached to it are you?
I think that there should be a discussion of existing solutions to all of
the problems of interest, so that we can enumerate why those solutions are
not good enough. It would also allow us to perhaps find a better way to
handle this than with named parameters. For example, if tagged dispatch
solves a lot of these problems, then perhaps we can incorporate tags into
the language in some more formal way rather than going to full named
parameters.
Post by Henry Miller
class myMatrix {
T GetCell(int row, int column);
...
};
cell = matrix.GetCell(column, row);
This will compile just fine in C++17, but the code is undoubtedly wrong.
In C++2n do you want this to be a compiler error, or correct code?
Note that making this "not correct code" would require that the mechanism
*require* that the user provide named arguments. That is, you cannot use
positional arguments at all.

Tagged dispatch can handle such cases.
Post by Henry Miller
class point {
point(double x, double y);
point(double distance, double angle);
...
};
This code does not compile in C++17. Do we want to make this case work?
Tagged dispatch can work here. So can a properly named struct:
`point(Polar(dist, angle))`. Plus, by giving the type a full name, we allow
`Polar` coordinates to be passed around and used for other purposes.
Post by Henry Miller
class myString {
int compare(myString, bool CaseSensitive);
...
};
in code
if(str.compare(otherString, false) == 0) ... // what does this mean,
why would you call compare and not compare?
This code is legal C++17, but it is user hostile. False in the context of
reading the function makes no intuitive sense. Qt has created an enum for
this, but it can be argued that this is too heavy. (you may or may not
agree with the argument)
The alternatives should be considered and discussed. Enumerators and tagged
dispatch both are good solutions.
Post by Henry Miller
// warning, marketing regularly changes the default value of this function
void foo(double a = 1234.5, int b = 6789);
foo(b:=1234);
This won't compile in C++17. However it seems like it would be useful to
not clutter function calls with default parameters that you don't care
about. In the case I gave it is a maintenance problem to update all uses of
foo every time the defaults change, though I'm not sure if this is actually
a common problem.
There are several alternative solutions. A named struct works well enough,
thanks to designated initializers. Plus, it puts the default values in a
more accessible location, rather than the signature of a function. It's not
like users can get changes to such default values without recompiling
anyway.

There is also the option of using `optional<double>`. So you'd call it with
`foo(nullopt, 1234)`, and allow the internal code to fill in the default.
This alternative also has the advantage that, if the default changes, you *don't
have to recompile* to get the changed value. Named parameters could take
advantage of that too by using `optional`.
--
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/12ca0430-f790-4dee-b491-266435bae170%40isocpp.org.
Henry Miller
2018-08-16 20:41:45 UTC
Permalink
On Thursday, August 16, 2018 at 1:45:01 PM UTC-4, Henry Miller wrote:>>
Post by Henry Miller
In the past couple months I've seen several proposals for names
parameters. Each with a list of pros and cons, and because there are
cons arguments against them. I think we need a discussion on what we
want assuming some strawman acceptable syntax, and some thought of
how many limitations in corner cases we are willing to accept.>>
I can think of 4 uses for names parameters. (If you don't understand
these I have simple code examples)>> 1 . a function with more than one parameter of the same type is
called with the parameters in the wrong order>> * Some people want this to be a compilation error, some want
the compiler to correct the problem and continue>> 2. a function wants to take the same type to mean different things in
different contexts>> 3. it isn't obvious from the type alone what a parameter means
4. A function has a bunch of defaulted arguments and you want to
change one of the latter ones without specifying all the others>>
First question: is this complete?
Second, which problems are worth solving?
Third, for problems worth solving, which is the better solution, and
how strongly attached to it are you?>
I think that there should be a discussion of existing solutions to all
of the problems of interest, so that we can enumerate why those
solutions are not good enough. It would also allow us to perhaps find
a better way to handle this than with named parameters. For example,
if tagged dispatch solves a lot of these problems, then perhaps we can
incorporate tags into the language in some more formal way rather than
going to full named parameters.
That comes next. First I want to brainstorm in a world where we are not
constrained by possible to say what we want.
After that we look at the other solutions, decide which are useful, and
if any are good enough. Note in particular P0707 - metaclasses has
using...as notation which make strong types easier to declare and might
give everyone what they wanted.
Post by Henry Miller
class myMatrix {
T GetCell(int row, int column);
...
};
cell = matrix.GetCell(column, row);
This will compile just fine in C++17, but the code is undoubtedly
wrong. In C++2n do you want this to be a compiler error, or
correct code?>
Note that making this "not correct code" would require that the
mechanism *require* that the user provide named arguments. That is,
you cannot use positional arguments at all.
Right, the question is WHAT mechanism? When I write that I thought of 4
different ways to change C++ to accomplish this, and as it happens
taging wasn't one. My 4 plus taging isn't a complete list either, it
isn't even close.
The point isn't to discuss how we want to do this, it is to discuss to
we want to do it at all, and if so is it a compiler error or does the
compiler just do what the user wanted.
Tagged dispatch can handle such cases.
Post by Henry Miller
class point {
point(double x, double y);
point(double distance, double angle);
...
};
This code does not compile in C++17. Do we want to make this
case work?>
`point(Polar(dist, angle))`. Plus, by giving the type a full name, we
allow `Polar` coordinates to be passed around and used for other
purposes.>
Post by Henry Miller
class myString {
int compare(myString, bool CaseSensitive);
...
};
in code
if(str.compare(otherString, false) == 0) ... // what does this
mean, why would you call compare and not compare?>>
This code is legal C++17, but it is user hostile. False in the
context of reading the function makes no intuitive sense. Qt has
created an enum for this, but it can be argued that this is too
heavy. (you may or may not agree with the argument)>
The alternatives should be considered and discussed. Enumerators and
tagged dispatch both are good solutions.
The argument against both is they are "ugly" This is of course
subjective, but sometimes that is compelling anyway.
Post by Henry Miller
// warning, marketing regularly changes the default value of this
function>> void foo(double a = 1234.5, int b = 6789);
foo(b:=1234);
This won't compile in C++17. However it seems like it would be useful
to not clutter function calls with default parameters that you don't
care about. In the case I gave it is a maintenance problem to update
all uses of foo every time the defaults change, though I'm not sure
if this is actually a common problem.>
There are several alternative solutions. A named struct works well
enough, thanks to designated initializers. Plus, it puts the default
values in a more accessible location, rather than the signature of a
function. It's not like users can get changes to such default values
without recompiling anyway.>
There is also the option of using `optional<double>`. So you'd call it
with `foo(nullopt, 1234)`, and allow the internal code to fill in the
default. This alternative also has the advantage that, if the default
changes, you *don't have to recompile* to get the changed value. Named
parameters could take advantage of that too by using `optional`.
Lots of options are possible. Do we like them?

I considered proposing a syntax llke 'foo(:=default, 1234)' for this.  I
decided it wasn't worth it yet, but if we are not happy with the options
adding something like this is possible.
--
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/1534452105.3767720.1476682240.226BF14C%40webmail.messagingengine.com.
Vicente J. Botet Escriba
2018-08-17 08:59:31 UTC
Permalink
Post by Henry Miller
Post by Henry Miller
In the past couple months I've seen several proposals for names
parameters.  Each with a list of pros and cons, and because there
are cons arguments against them.  I think we need a discussion on
what we want assuming some strawman acceptable syntax, and some
thought of how many limitations in corner cases we are willing to
accept.
I can think of 4 uses for names parameters. (If you don't
understand these I have simple code examples)
1 . a function with more than one parameter of the same type is
called with the parameters in the wrong order
      *  Some people want this to be a compilation error, some
want the compiler to correct the problem and continue
2. a function wants to take the same type to mean different
things in different contexts
3. it isn't obvious from the type alone what a parameter means
4. A function has a bunch of defaulted arguments and you want to
change one of the latter ones without specifying all the others
First question: is this complete?
Second, which problems are worth solving?
Third, for problems worth solving, which is the better solution,
and how strongly attached to it are you?
I think that there should be a discussion of existing solutions to
all of the problems of interest, so that we can enumerate why those
solutions are not good enough. It would also allow us to perhaps find
a better way to handle this than with named parameters. For example,
if tagged dispatch solves a lot of these problems, then perhaps we
can incorporate tags into the language in some more formal way rather
than going to full named parameters.
That comes next. First I want to brainstorm in a world where we are
not constrained by possible to say what we want.
I'm not against a possible named parameter feature, but we need a good
proposal as all of them have failed. Why the past proposals failed?

In addition, I believe that what Nicol means is that in order to compare
possible solutions to those problems we need to compare them as well to
the current solutions we have already using the current standard. The
current way is even more important  than the new way to check if it is
worth changing the language.

One important thing to consider is if we are able to change the existing
defining code, if we are able to change the signature (the function
type), ...
Post by Henry Miller
After that we look at the other solutions, decide which are useful,
and if any are good enough. Note in particular P0707 - metaclasses has
using...as notation which make strong types easier to declare and
might give everyone what they wanted.
Post by Henry Miller
class myMatrix {
     T GetCell(int row, int column);
     ...
};
   cell = matrix.GetCell(column, row);
This will compile just fine in C++17, but the code is undoubtedly
wrong.  In C++2n do you want this to be a compiler error, or
correct code?
Note that making this "not correct code" would require that the
mechanism /require/ that the user provide named arguments. That is,
you cannot use positional arguments at all.
Right, the question is WHAT mechanism?  When I write that I thought of
4 different ways to change C++ to accomplish this, and as it happens
taging wasn't one.  My 4 plus taging isn't a complete list either, it
isn't even close.
The point isn't to discuss how we want to do this, it is to discuss to
we want to do it at all, and if so is it a compiler error or does the
compiler just do what the user wanted.
Hum, how to know what the user wanted?
Having a name parameter could help also partially as you could always
use the bad int while associating the row and columns named arguments.
Post by Henry Miller
Post by Henry Miller
Tagged dispatch can handle such cases.
When considering tag dispatch, we change the function type, and some
times this is not possible.
If we can change the signature, this case can be solved partially using
different types for row and column. I say partially because at the end
you will need to initialize a row and a column, and you could choose the
wrong int for them (as with named parameters)
Post by Henry Miller
Post by Henry Miller
class point {
    point(double x, double y);
    point(double distance, double angle);
...
};
This code does not compile in C++17.  Do we want to make this
case work?
`point(Polar(dist, angle))`. Plus, by giving the type a full name, we
allow `Polar` coordinates to be passed around and used for other
purposes.
In this case I'm all for strong types and I believe we shouldn't take it
into consideration this example while discussing named parameters. Named
parameters (as I understand them) couldn't be used to solve this case.
Tag dispatch could be a solution as well.
Post by Henry Miller
Post by Henry Miller
class myString {
    int compare(myString, bool CaseSensitive);
...
};
in code
if(str.compare(otherString, false) == 0) ...   // what does this
mean, why would you call compare and not compare?
This code is legal C++17, but it is user hostile. False in the
context of reading the function makes no intuitive sense.  Qt has
created an enum for this, but it can be argued that this is too
heavy.  (you may or may not agree with the argument)
The alternatives should be considered and discussed. Enumerators and
tagged dispatch both are good solutions.
The argument against both is they are "ugly"  This is of course
subjective, but sometimes that is compelling anyway.
What is wrong with case_sensitive, non_case_sensitive?

I'm a fan of strong types and I would like to minimize the direct use of
non-strong types as much as possible. When I try to solve define a
strong flag I have the problem that those flags can not be short circuit
the overloaded boolean expressions. This means that those strong types
should be convertible to a bool.
Post by Henry Miller
Post by Henry Miller
// warning, marketing regularly changes the default value of this function
void foo(double a = 1234.5, int b = 6789);
foo(b:=1234);
This won't compile in C++17. However it seems like it would be
useful to not clutter function calls with default parameters that
you don't care about. In the case I gave it is a maintenance
problem to update all uses of foo every time the defaults change,
though I'm not sure if this is actually a common problem.
There are several alternative solutions. A named struct works well
enough, thanks to designated initializers. Plus, it puts the default
values in a more accessible location, rather than the signature of a
function. It's not like users can get changes to such default values
without recompiling anyway.
There is also the option of using `optional<double>`. So you'd call
it with `foo(nullopt, 1234)`, and allow the internal code to fill in
the default. This alternative also has the advantage that, if the
default changes, you /don't have to recompile/ to get the changed
value. Named parameters could take advantage of that too by using
`optional`.
Lots of options are possible.  Do we like them?
I want to promote interfaces like the previous one. Maybe knowing what
foo, a and b mean could help me. Could we please, use concrete examples.
When I have a lot of parameters, I believe I like the named struct
approach. It is easy to define the default values today, and the use of
named designators help to override them. The compiler shopuld make the
code as efficient as if we had several parameters and in some cases it
will even make the code more efficient.

And you, do you like them? If not, what you don't like and why?
Post by Henry Miller
I considered proposing a syntax llke 'foo(:=default, 1234)' for this. 
I decided it wasn't worth it yet, but if we are not happy with the
options adding something like this is possible.
I want to promote interfaces like the previous one. Maybe knowing what
foo, a and b mean could help me.

Note that you can already define to code what the comment says "warning,
marketing regularly changes the default value of this function".

    double foo_a_default = ...;
    void foo(double a = foo_a_default, int b = foo_b_default);

    foo(foo_a_default, 1234);

so the previous solution should be compared to something like this to
check if it is worth changing the language to cover this case.

Vicente
--
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/2fcb51b2-fefb-b190-aaa5-d884cf6a4ab8%40wanadoo.fr.
Justin Bassett
2018-08-17 04:23:28 UTC
Permalink
Post by Nicol Bolas
I think that there should be a discussion of existing solutions to all of
the problems of interest, so that we can enumerate why those solutions are
not good enough. It would also allow us to perhaps find a better way to
handle this than with named parameters. For example, if tagged dispatch
solves a lot of these problems, then perhaps we can incorporate tags into
the language in some more formal way rather than going to full named
parameters.
A short list of current solutions I know of:

- "Named Parameters Idiom"
- Strong types
- Tag dispatch
- Operator overloading (writing foo(parameter = value) by overloading
operator=, sometimes done with other operators instead); I believe Boost
Parameters does this
- Boost Graph's named parameters. The named parameters argument is
always the last and is specified by member functions. Similar to the named
parameters idiom, but more complex: boost::foo(positional, arguments,
boost::arg1(val).arg2(val2))
- Designated Initializers

The named parameters idiom and Boost Graph's named parameters both require
a lot of overhead on the library author's side. There's a lot of code that
needs to be maintained. If you want to prevent
parameters().foo(value).foo(someOtherValue), that's even more work.
Together with designated initializers, I've heard that this can also
produce worse codegen, since we are passing around a struct rather than
individual parameters.

Strong types and designated initializers fall short in parameter
reordering. Sure, you can provide all possible combinations with strong
types, but then it becomes unmaintainable. Strong types also require a type
for each name you wish to use (if you want different types, that works
within C++17's CTAD), which might run into problems if you end up with
collisions with names of actual types rather than psuedo-types made just
for named parameters. Also, it's annoying to use without using declarations
or directives.

Designated initializers fall short if you go more than one layer deep:
std::invoke(something_with_named_parameters,
{ .arg1 = value }). You have to specify the name of the struct, which is
jarring. It's also not nice to decompose elements of each struct to send
them into other named-parameters-designated-structs. I was convinced
designated initializers would be the solution to C++'s lack of named
parameters, but I ran into problems such as this when experimenting with
it. I had some more complex scenarios, but I have since forgotten them.

There is also the option of using `optional<double>`. So you'd call it with
Post by Nicol Bolas
`foo(nullopt, 1234)`, and allow the internal code to fill in the default.
This alternative also has the advantage that, if the default changes, you *don't
have to recompile* to get the changed value. Named parameters could take
advantage of that too by using `optional`.
This isn't named parameters. This is optional parameters. Once you get more
than a few optional parameters, it becomes unreadable fast: foo(123,
nullopt, nullopt, "string", nullopt)
--
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAPuuy5cHU7OHPAEFJL41gLnknwxS1JQJHGrOsX8bQR7mfkVdxw%40mail.gmail.com.
Justin Bassett
2018-08-17 04:29:50 UTC
Permalink
Clicked send a bit fast.

Strong types and named parameters are not replacements for one another.
They solve different classes of problems. Strong types don't handle the
case of providing a value for a parameter in the middle of a bunch of
defaulted parameters.

Operator overloading is not a good solution. You need to namespace qualify
everything (else using), and it abuses operators in a way that makes it
unclear what's going on, especially when using operator=.

Boost Graph's named parameters are the best calling-side API I've yet seen
for named parameters. It is not nice to maintain code that provides such
nice APIs, though, although one could make a library to make it more
reasonable.

Tag dispatch is orthogonal to named parameters IMO. Using tags such as
std::in_place is just a way of saying, "I know this is an overload set, but
I really need to call this particular overload." That's not naming
parameters, that's naming overloads. Tag dispatch would not work for Boost
Graph's use case, which is approximately option 4 that Henry Miller
mentioned.
Post by Justin Bassett
Post by Nicol Bolas
I think that there should be a discussion of existing solutions to all of
the problems of interest, so that we can enumerate why those solutions are
not good enough. It would also allow us to perhaps find a better way to
handle this than with named parameters. For example, if tagged dispatch
solves a lot of these problems, then perhaps we can incorporate tags into
the language in some more formal way rather than going to full named
parameters.
- "Named Parameters Idiom"
- Strong types
- Tag dispatch
- Operator overloading (writing foo(parameter = value) by overloading
operator=, sometimes done with other operators instead); I believe
Boost Parameters does this
- Boost Graph's named parameters. The named parameters argument is
always the last and is specified by member functions. Similar to the named
parameters idiom, but more complex: boost::foo(positional, arguments,
boost::arg1(val).arg2(val2))
- Designated Initializers
The named parameters idiom and Boost Graph's named parameters both require
a lot of overhead on the library author's side. There's a lot of code that
needs to be maintained. If you want to prevent
parameters().foo(value).foo(someOtherValue), that's even more work.
Together with designated initializers, I've heard that this can also
produce worse codegen, since we are passing around a struct rather than
individual parameters.
Strong types and designated initializers fall short in parameter
reordering. Sure, you can provide all possible combinations with strong
types, but then it becomes unmaintainable. Strong types also require a type
for each name you wish to use (if you want different types, that works
within C++17's CTAD), which might run into problems if you end up with
collisions with names of actual types rather than psuedo-types made just
for named parameters. Also, it's annoying to use without using declarations
or directives.
Designated initializers fall short if you go more than one layer deep: std::invoke(something_with_named_parameters,
{ .arg1 = value }). You have to specify the name of the struct, which is
jarring. It's also not nice to decompose elements of each struct to send
them into other named-parameters-designated-structs. I was convinced
designated initializers would be the solution to C++'s lack of named
parameters, but I ran into problems such as this when experimenting with
it. I had some more complex scenarios, but I have since forgotten them.
There is also the option of using `optional<double>`. So you'd call it
Post by Nicol Bolas
with `foo(nullopt, 1234)`, and allow the internal code to fill in the
default. This alternative also has the advantage that, if the default
changes, you *don't have to recompile* to get the changed value. Named
parameters could take advantage of that too by using `optional`.
This isn't named parameters. This is optional parameters. Once you get
more than a few optional parameters, it becomes unreadable fast: foo(123,
nullopt, nullopt, "string", nullopt)
--
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAPuuy5cV03gX4Th%2BLxPAAXjnBEyNatrdinrjVFRLsSiLavj%2BjA%40mail.gmail.com.
Vicente J. Botet Escriba
2018-08-17 09:22:40 UTC
Permalink
Post by Nicol Bolas
I think that there should be a discussion of existing solutions to
all of the problems of interest, so that we can enumerate why
those solutions are not good enough. It would also allow us to
perhaps find a better way to handle this than with named
parameters. For example, if tagged dispatch solves a lot of these
problems, then perhaps we can incorporate tags into the language
in some more formal way rather than going to full named parameters.
* "Named Parameters Idiom"
* Strong types
* Tag dispatch
* Operator overloading (writing foo(parameter = value) by
overloading operator=, sometimes done with other operators
instead); I believe Boost Parameters does this
* Boost Graph's named parameters. The named parameters argument is
always the last and is specified by member functions. Similar to
boost::foo(positional, arguments, boost::arg1(val).arg2(val2))
* Designated Initializers
The named parameters idiom and Boost Graph's named parameters both
require a lot of overhead on the library author's side. There's a lot
of code that needs to be maintained. If you want to prevent
parameters().foo(value).foo(someOtherValue), that's even more work.
I guess for you the named parameter idiom is what Boost.Parameter
provides, isn't it?
Post by Nicol Bolas
Together with designated initializers, I've heard that this can also
produce worse codegen, since we are passing around a struct rather
than individual parameters.
I heard the opposite about the performances of designated initializes
;-) I suspect that it will depend on the particular case. We need
concrete cases and measure.
Post by Nicol Bolas
Strong types and designated initializers fall short in parameter
reordering. Sure, you can provide all possible combinations with
strong types, but then it becomes unmaintainable. Strong types also
require a type for each name you wish to use (if you want different
types, that works within C++17's CTAD), which might run into problems
if you end up with collisions with names of actual types rather than
psuedo-types made just for named parameters. Also, it's annoying to
use without using declarations or directives.
I don't want to use strong types to solve the problems named parameter
is intended to solve as I don't want to use named parameter to solve the
problems strong type intend to solve.
Post by Nicol Bolas
std::invoke(something_with_named_parameters, { .arg1 = value }). You
have to specify the name of the struct, which is jarring. It's also
not nice to decompose elements of each struct to send them into other
named-parameters-designated-structs. I was convinced designated
initializers would be the solution to C++'s lack of named parameters,
but I ran into problems such as this when experimenting with it. I had
some more complex scenarios, but I have since forgotten them.
perfect forwarding will imply to have specific function types or to use
overload sets.
For me named parameters don't change the function type (let me know if
this is something you want). This implies that named parameters couldn't
be used to solve this perfect forwarding issue. You need tag dispatching
or something else.
There is a proposal (from Mihail), that associates some named parameters
to the function type. I believe that we need to name it differently. I
will consider the first named parameter as as syntactic sugar for tag
dispatching ,ad the other just named parameters. As the nature is
different I would like to have different syntax for the parameters that
change the signature and those that don't change it.
Post by Nicol Bolas
There is also the option of using `optional<double>`. So you'd
call it with `foo(nullopt, 1234)`, and allow the internal code to
fill in the default. This alternative also has the advantage that,
if the default changes, you /don't have to recompile/ to get the
changed value. Named parameters could take advantage of that too
by using `optional`.
This isn't named parameters. This is optional parameters. Once you get
foo(123, nullopt, nullopt, "string", nullopt)
I agree.

Vicente
--
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/81d3b2f3-398f-9ac2-1783-074ac2ad1ef5%40wanadoo.fr.
m***@gmail.com
2018-08-16 21:01:08 UTC
Permalink
I will answer where I need them.

First to freely use constructors with "many" arguments.
I tend to prefer constructors in place of getter/setter and late
initialization.
This way I have tight control over the state of the object and know -
public interface means someone *else* needs to access this, not "I need
this for construction".

Second, which is tied to the first, I need this for non-so-public
interfaces, where things are not so stable and/or not so pretty. You
mention Qt, but even Qt uses bool arg, in the non public interface!
Yea, I also "never" use a bool, yet I have few places for sure, none of
them public interface, but still.

These two define my PoV:
1. Mainly need weak arguments, but stronger then comments and/or just
warnings
2. No alternative will ever help me if it is *more* code and need *more*
maintenance.

But I want to iterate on the second point.
Way, way to often there is the armchair argument "you should do this" or "you
should do that", in pace of named arguments, and these are mostly correct
(mostly),
*if we talk about public interface. *The requirement for private, and/or
semi stable, and/or work in progress code are different, and the code is
different.
With enough time, any interface can be pretty, even in C, but in practice,
day to day, we need quick and practical ways for more correct code.
(This all putting aside code that even pretty is vulnerable to confusion in
general, like math, physics some algorithms)
--
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/037bdc3e-6030-41d6-ae70-3849cca0585c%40isocpp.org.
Dejan Milosavljevic
2018-08-16 21:23:30 UTC
Permalink
Something complexly different approach.
Fro both items ignore syntax, ideas/problems are main focus.

1. Strong typedefs.
Currently there is strong demand for for it.
But no consensus so far.
Take a look at next code

strongdef polar = std::array<double,2>;
strongdef descartes = std::array<double,2>;
struct A{
void f( polar const& p );
void f( descartes const& p );
};

Clearly strong typedef will supersede this proposal.

2. Another nice proposal is call functions with named parameters:
Another very niece feature.

Example:
void f( int a, int b );
f( .b=1, .b=2 ); // Highly probable that is one of many proposed
syntax.
I see here another clash. Syntax must be clearly different. So more
complication.
Clash aslo will be in the head of programmer. Which one is call
functions with parameter naming and which one is from this proposal.

Combining two of them( strongdef and function call ) is very easy.
No interference to from each other.

Based on previous two item it is not enough to solve current problem.

It is must to see what is effect on other proposal.
Post by m***@gmail.com
I will answer where I need them.
First to freely use constructors with "many" arguments.
I tend to prefer constructors in place of getter/setter and late
initialization.
This way I have tight control over the state of the object and know -
public interface means someone *else* needs to access this, not "I need
this for construction".
Second, which is tied to the first, I need this for non-so-public
interfaces, where things are not so stable and/or not so pretty. You
mention Qt, but even Qt uses bool arg, in the non public interface!
Yea, I also "never" use a bool, yet I have few places for sure, none of
them public interface, but still.
1. Mainly need weak arguments, but stronger then comments and/or just
warnings
2. No alternative will ever help me if it is *more* code and need *more*
maintenance.
But I want to iterate on the second point.
Way, way to often there is the armchair argument "you should do this" or "you
should do that", in pace of named arguments, and these are mostly correct
(mostly),
*if we talk about public interface. *The requirement for private, and/or
semi stable, and/or work in progress code are different, and the code is
different.
With enough time, any interface can be pretty, even in C, but in practice,
day to day, we need quick and practical ways for more correct code.
(This all putting aside code that even pretty is vulnerable to confusion
in general, like math, physics some algorithms)
--
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
To view this discussion on the web visit https://groups.google.com/a/
isocpp.org/d/msgid/std-proposals/037bdc3e-6030-41d6-
ae70-3849cca0585c%40isocpp.org
<https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/037bdc3e-6030-41d6-ae70-3849cca0585c%40isocpp.org?utm_medium=email&utm_source=footer>
.
--
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAEfefmwPGsm3uuGCJKDBgd9d0e3mPONAKkHf0Pdfwbad4Y%3D6Dw%40mail.gmail.com.
Jake Arkinstall
2018-08-16 22:19:56 UTC
Permalink
Post by Dejan Milosavljevic
Something complexly different approach.
Fro both items ignore syntax, ideas/problems are main focus.
1. Strong typedefs.
Currently there is strong demand for for it.
But no consensus so far.
Take a look at next code
strongdef polar = std::array<double,2>;
strongdef descartes = std::array<double,2>;
struct A{
void f( polar const& p );
void f( descartes const& p );
};
Clearly strong typedef will supersede this proposal.
This aligns with my viewpoint on this - though it is commonly argued that
we might just end up cluttering up code with artificial types. My take on
it is that it's always worth doing so in order to define strict conversion
rules, but it isn't everyone's cup of tea.
Post by Dejan Milosavljevic
Another very niece feature.
void f( int a, int b );
f( .b=1, .b=2 ); // Highly probable that is one of many proposed
syntax.
I find that syntax ugly, but its something I would get used to after some
time. I'd prefer :name, $name, @name, something with a bit more prominence
than a dot. But that's just me.

I see here another clash. Syntax must be clearly different. So more
Post by Dejan Milosavljevic
complication.
Clash aslo will be in the head of programmer. Which one is call
functions with parameter naming and which one is from this proposal.
Combining two of them( strongdef and function call ) is very easy.
No interference to from each other.
Based on previous two item it is not enough to solve current problem.
It is must to see what is effect on other proposal.
I guess mixing the two approaches would make a lot of sense, and it
certainly goes some way to answer the "what if the signature for two
functions are the same" problem. Forbid it and make the types stronger if
and when you need to. The last thing I want to have is *forced* named
parameters because of a confusing API. It's an immediate way of making your
headers incompatible with older C++ versions, and I see no justification of
such a major language overhall for a feature that won't see any widespread
adoption for a decade.

On the other hand, it's easy enough for a library to provide structs for
strong types for older standard versions, wrapped in preprocessor
conditionals.
--
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCNmazfF1R35rWui0D73g258Y0X9RT7XPMa638DMmGf%2BEA%40mail.gmail.com.
Matthew Woehlke
2018-08-24 20:25:20 UTC
Permalink
Post by Dejan Milosavljevic
1. Strong typedefs.
Currently there is strong demand for for it.
But no consensus so far.
Take a look at next code
strongdef polar = std::array<double,2>;
strongdef descartes = std::array<double,2>;
struct A{
void f( polar const& p );
void f( descartes const& p );
};
Clearly strong typedef will supersede this proposal.
Hardly. That *might* solve the desire for name-based overloads, but it
doesn't solve the 'many defaulted parameters' problem. (Not, at least,
without way, way too many overloads.)
--
Matthew
--
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/c35ef267-f885-32d2-421e-8449f87621b5%40gmail.com.
Justin Bassett
2018-08-17 04:39:06 UTC
Permalink
Post by Henry Miller
In the past couple months I've seen several proposals for names
parameters. Each with a list of pros and cons, and because there are cons
arguments against them. I think we need a discussion on what we want
assuming some strawman acceptable syntax, and some thought of how many
limitations in corner cases we are willing to accept.
I can think of 4 uses for names parameters. (If you don't understand these
I have simple code examples)
1 . a function with more than one parameter of the same type is called
with the parameters in the wrong order
* Some people want this to be a compilation error, some want the
compiler to correct the problem and continue
2. a function wants to take the same type to mean different things in different contexts
3. it isn't obvious from the type alone what a parameter means
4. A function has a bunch of defaulted arguments and you want to change
one of the latter ones without specifying all the others
First question: is this complete?
Second, which problems are worth solving?
Third, for problems worth solving, which is the better solution, and how
strongly attached to it are you?
Some other use cases:

5. In tandem with reflection, names could be used for their names. A
formatting library could use this in tandem with reflection:
fmt::format("{sign}
{value}", .sign = "$", .value = 1.34_usd); Language bindings to e.g. Python
could use it to specify names for parameters (e.g. this could expose the
parameter names to the language bindings: m.def([](int .a, int .b) { return
a + b; }) )
6. This is a variation on 4. There may not be a bunch of defaulted
arguments, but rather a few expert settings which you want the users to be
able to tweak on rare occasions.
7. bool arguments have meaning. It's pretty well known that something
like file.open("path/to/file.txt",
true) is bad, because the bool has no meaning. But
file.open("path/to/file.txt",
.append = true) isn't so bad because the meaning is apparent. Enums
currently fill this role.
--
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAPuuy5dz_N4nwnDrmds%3DROEpnUY2jQU4XGcLytxXscB%3DX36P1g%40mail.gmail.com.
Vicente J. Botet Escriba
2018-08-17 09:33:43 UTC
Permalink
Post by Henry Miller
In the past couple months I've seen several proposals for names
parameters.  Each with a list of pros and cons, and because there
are cons arguments against them.  I think we need a discussion on
what we want assuming some strawman acceptable syntax, and some
thought of how many limitations in corner cases we are willing to
accept.
I can think of 4 uses for names parameters. (If you don't
understand these I have simple code examples)
1 . a function with more than one parameter of the same type is
called with the parameters in the wrong order
      *  Some people want this to be a compilation error, some
want the compiler to correct the problem and continue
2. a function wants to take the same type to mean different things
in different contexts
3. it isn't obvious from the type alone what a parameter means
4. A function has a bunch of defaulted arguments and you want to
change one of the latter ones without specifying all the others
First question: is this complete?
Second, which problems are worth solving?
Third, for problems worth solving, which is the better solution,
and how strongly attached to it are you?
5. In tandem with reflection, names could be used for their names. A
fmt::format("{sign} {value}", .sign = "$", .value = 1.34_usd);
Language bindings to e.g. Python could use it to specify names for
parameters  (e.g. this could expose the parameter names to the
language bindings: m.def([](int .a, int .b) { return a + b; }) )
I don't think this is a named parameter use case, even if it look like.
Note that the name of the arguments is not given by the parameter name
of the function, as it -is a variadic function, but for the name inside
the formatting string. So even if I want this to be solved, I don't
think it belongs to this feature.
Post by Henry Miller
6. This is a variation on 4. There may not be a bunch of defaulted
arguments, but rather a few expert settings which you want the users
to be able to tweak on rare occasions.
Could you elaborate?
Post by Henry Miller
7. bool arguments have meaning. It's pretty well known that something
like file.open("path/to/file.txt", true) is bad, because the bool has
no meaning. But file.open("path/to/file.txt", .append = true) isn't so
bad because the meaning is apparent. Enums currently fill this role.
Well, not only bool arguments. int arguments have also meaning. I
believe this fall under case 3.

Vicente
--
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/698e2fea-a733-33b5-282b-b033fe8b9167%40wanadoo.fr.
David Brown
2018-08-17 15:09:30 UTC
Permalink
Post by Henry Miller
In the past couple months I've seen several proposals for names
parameters. Each with a list of pros and cons, and because there are
cons arguments against them. I think we need a discussion on what we
want assuming some strawman acceptable syntax, and some thought of
how many limitations in corner cases we are willing to accept.
I can think of 4 uses for names parameters. (If you don't understand
these I have simple code examples)
1 . a function with more than one parameter of the same type is
called with the parameters in the wrong order
* Some people want this to be a compilation error, some want the
compiler to correct the problem and continue
Ideally, I'd want the compiler to correct it (i.e., re-arrange the
parameter order). But I'd be okay with an error as a second-best
choice. An error is enough to ensure that the code is more readable and
mistakes in parameter order are caught. Re-arranging is about
convenience in writing the code, which is a lot less important.
Post by Henry Miller
2. a function wants to take the same type to mean different things in different contexts
You mean function overloads based on parameter names? They would
occasionally be useful, but not essential IMHO. I'd like them but I
would not want them to break other important points like compatibility
with existing code and tools (this feature should not cost anything if
it is not used).
Post by Henry Miller
3. it isn't obvious from the type alone what a parameter means
I have an alternative idea for your example below.
Post by Henry Miller
4. A function has a bunch of defaulted arguments and you want to
change one of the latter ones without specifying all the others
This would be convenient for some types of coding, but is not an
essential. It would rely on being able to re-order parameters using names.
Post by Henry Miller
First question: is this complete?
I think so, yes - those are the key uses. My prime motivation for
wanting named parameters is to be able to be sure the code I write is
clear and correct, rather than allowing new kinds of coding. #1 above
would be sufficient for that.

But there are a few other requirements I would add.

5. Using named parameters should be optional unless unavoidable (such as
for overloads). The solution should not affect existing code, it should
be possible to use named parameters with existing functions, it should
not involve any change to generated code, mangled names, ABIs, object
code formats, etc., unless unavoidable (again, we are talking about
overalods).

6. It should be suitable for use in C as well as C++ (excluding
overloads). I don't expect it to be part of the C standards until
perhaps C38 (when we have all retired early to avoid the year 2038
fallout) as they are very slow to adopt new features. But I would
expect big C/C++ compilers to support it as an extension in C once it is
part of C++.
Post by Henry Miller
Second, which problems are worth solving?
#1 is definitely worth solving. The others would be nice as long as
they don't delay a solution to #1.

Parameter name based overloading looks challenging and would involve a
good deal more changes to the language and the tools. It is worth
considering, but may not be worth solving. There could be alternative
ways to get this effect.
Post by Henry Miller
Third, for problems worth solving, which is the better solution, and
how strongly attached to it are you?
My proposal in the other thread is the best solution :-)
Post by Henry Miller
class myMatrix {
T GetCell(int row, int column);
...
};
in code: cell = matrix.GetCell(column, row);
This will compile just fine in C++17, but the code is undoubtedly
wrong. In C++2n do you want this to be a compiler error, or correct
code?
I don't think it is an appropriate example. If you have:

int column = 1;
int row = 2;
auto cell = matrix.GetCell(column, row);

then it should compile fine. It is not using named parameters, but is
existing code. (A smart compiler could warn about it.) But /this/
should either be an error, or be re-arranged automatically:

auto cell = matrix.GetCell(.column = column, .row = row);
Post by Henry Miller
class point {
point(double x, double y);
point(double distance, double angle);
...
};
This code does not compile in C++17. Do we want to make this case work?
I'd be okay with allowing it, but it would involve a lot more changes to
support. See the next case below.
Post by Henry Miller
class myString {
int compare(myString, bool CaseSensitive);
...
};
in code
if(str.compare(otherString, false) == 0) ...
// what does this mean, why would you call compare and not compare?
This code is legal C++17, but it is user hostile. False in the
context of reading the function makes no intuitive sense. Qt has
created an enum for this, but it can be argued that this is too
heavy. (you may or may not agree with the argument)
The ideal solution, IMHO, involves two parts. I would like to see
function parameter scope types, and perhaps be able to define them
within a function declaration. I want to see:

class myString {
int compare(
myString,
enum class CaseSensitivity { insensitive, sensitive }
sensitivity
);

Then you could write:

if (str.compare(otherString, insensitive) == 0) ...

The "insensitive" would automatically be looked up in the scope of types
declared within the scope of the function declaration.

If you need to refer to the enum constants outside of a function call,
you could use myString::compare::CaseSensitivity.

As a convenience, perhaps the name of the type could be omitted and you
could use the parameter name here, and "enum" could automatically be a
strong enumeration (so you can't use booleans or integers instead of
enumeration constants):

class myString {
int compare(
myString,
enum { insensitive, sensitive } sensitivity
);

Within the function definition, these local types would also be in scope
(possibly qualified as "sensitivity::insensitive" if that is preferred).

The same idea, with a similar convenience, could give you:

class point {
point(struct double x, struct double y);
point(struct double distance, struct double angle);
...
};

This would be a convenience syntax for:

class point {
struct point_x { double x };
struct point_y { double y };
struct point_distance { double distance };
struct point_angle { double angle };

point(point_x x, point_y y);
point(point_distance distance, point_angle angle);
...
};

auto p = point(.x = 1, .y = 2);

would be

auto p = point(point_x(1), point_y(2));


This would give you all you need for overloading based on named
parameters, within the existing type system - no changes are needed in
name mangling or anything else. It's just a little short-cut for using
strong types for parameter names.

(I'm sure the syntax and details, especially scoping, will need more
careful thought than I've given it here.)
Post by Henry Miller
Fourth: // warning, marketing regularly changes the default value of
this function void foo(double a = 1234.5, int b = 6789);
foo(b:=1234);
This won't compile in C++17. However it seems like it would be useful
to not clutter function calls with default parameters that you don't
care about. In the case I gave it is a maintenance problem to update
all uses of foo every time the defaults change, though I'm not sure
if this is actually a common problem.
--
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/pl6ob7%249k1%241%40blaine.gmane.org.
Nicol Bolas
2018-08-17 15:25:27 UTC
Permalink
Post by David Brown
Post by Henry Miller
class myString {
int compare(myString, bool CaseSensitive);
...
};
in code
if(str.compare(otherString, false) == 0) ...
// what does this mean, why would you call compare and not compare?
This code is legal C++17, but it is user hostile. False in the
context of reading the function makes no intuitive sense. Qt has
created an enum for this, but it can be argued that this is too
heavy. (you may or may not agree with the argument)
The ideal solution, IMHO, involves two parts. I would like to see
function parameter scope types, and perhaps be able to define them
class myString {
int compare(
myString,
enum class CaseSensitivity { insensitive, sensitive }
sensitivity
);
if (str.compare(otherString, insensitive) == 0) ...
The "insensitive" would automatically be looked up in the scope of types
declared within the scope of the function declaration.
That is an over-designed solution. The problem has nothing to do with where
the enumeration gets declared. Sticking the declaration in the function
signature doesn't really solve the problem.

What solves the problem is the fact that the identifier `insensitive` is
looked up within the domain of how it is used. It's being used as a
function parameter that takes an enumeration which has an enumerator called
`insensitive`; therefore, that enumerator must be what it names.

*That* is the feature we need: the ability to take an identifier and
generate its "path" information based on context at the site of use. This
ability would aid in this problem and many others (enum-classes in
`switch/case`, having to prefix tags in tag dispatching with
`my_namespace::`, etc).

There is no reason to wed context-specific "path" lookup to the location
where the particular thing is declared.
--
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/2d91b5c9-da43-478c-b100-eed305f3397c%40isocpp.org.
David Brown
2018-08-17 17:16:03 UTC
Permalink
Post by David Brown
Post by Henry Miller
class myString {
int compare(myString, bool CaseSensitive);
...
};
in code
if(str.compare(otherString, false) == 0) ...
// what does this mean, why would you call compare and not compare?
This code is legal C++17, but it is user hostile. False in the
context of reading the function makes no intuitive sense. Qt has
created an enum for this, but it can be argued that this is too
heavy. (you may or may not agree with the argument)
The ideal solution, IMHO, involves two parts. I would like to see
function parameter scope types, and perhaps be able to define them
class myString {
int compare(
myString,
enum class CaseSensitivity { insensitive, sensitive }
sensitivity
);
if (str.compare(otherString, insensitive) == 0) ...
The "insensitive" would automatically be looked up in the scope of types
declared within the scope of the function declaration.
That is an over-designed solution. The problem has nothing to do with
where the enumeration gets declared. Sticking the declaration in the
function signature doesn't really solve the problem.
What solves the problem is the fact that the identifier `insensitive` is
looked up within the domain of how it is used. It's being used as a
function parameter that takes an enumeration which has an enumerator
called `insensitive`; therefore, that enumerator must be what it names.
/That/ is the feature we need: the ability to take an identifier and
generate its "path" information based on context at the site of use.
This ability would aid in this problem and many others (enum-classes in
`switch/case`, having to prefix tags in tag dispatching with
`my_namespace::`, etc).
There is no reason to wed context-specific "path" lookup to the location
where the particular thing is declared.
Fair enough. It sounds like you are suggesting a more general solution
that could be used in other places too. I'm happy with that idea.
--
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/pl6vog%246qv%241%40blaine.gmane.org.
m***@gmail.com
2018-08-22 18:58:12 UTC
Permalink
Back to the topic.


Discussions like this one come and go every 2-3 years. And we make ZERO
progress. At least no written progress.

May be we should make poll, what the most wanted types of named parameters
are?
May be we should write a paper to see what direction the committee is
willing to pursue, *if any*? Because right now I am not sure if the
implementation is the problem or the concept.

But above all, we should start agreeing on *something*.

Otherwise, after the dust settles, we will have nothing. As always.


We should start agreeing we are split, lets say 50/50 to opponents and
proponents, and no need to "convince" the other side they are "wrong".

We should start agreeing, there are different "types" of named parameters,
needed for different people. There is not "best", solution if it does one
type only.

Hell, even if we agree on one of these points, it will be progress.
--
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/73b10960-8c70-419a-b317-2d78ec46a1d7%40isocpp.org.
Nicol Bolas
2018-08-22 21:04:56 UTC
Permalink
Post by m***@gmail.com
Back to the topic.
Discussions like this one come and go every 2-3 years. And we make ZERO
progress. At least no written progress.
May be we should make poll, what the most wanted types of named parameters
are?
May be we should write a paper to see what direction the committee is
willing to pursue, *if any*? Because right now I am not sure if the
implementation is the problem or the concept.
But above all, we should start agreeing on *something*.
Otherwise, after the dust settles, we will have nothing. As always.
That's what this thread was trying to accomplish. The reason all that
arguing happens is that everyone is focused on the *solutions*, rather than
the problems.

Consider your explanation of "weak named arguments" from the other thread.
Your definition allows "optional" names to determine which function in an
overload set gets called. And in so doing, actually allows users to
*require* that you use names to call the function with a certain default
parameters.

But if the problem you're trying to solve with the proposal is to make
meaning apparent at the call site in a way the compiler can verify, then
you don't *need* names to factor into overload resolution or default
arguments at all. That would therefore be an extraneous bit of
functionality that isn't helping the feature solve the actual problem being
solved.

The only way to move forward is to localize the problem space into a
specific set of problems to be solved. If you can get broad agreement on
what problems need to be solved, or at least some series of problems with
various ratings of how much of a problem they are compared to existing
solutions, *then* you can move towards a design.

Having a small, well-defined set of problems to be solved focuses
discussions of the eventual proposal. It keeps people from saying, "well,
it doesn't do this" because... it's not *supposed* to do that.

We should start agreeing we are split, lets say 50/50 to opponents and
Post by m***@gmail.com
proponents, and no need to "convince" the other side they are "wrong".
You're not factoring in one group (to which I am a member): the group of
people who have yet to be convinced that C++ needs named parameters *of any
form*. People have provided examples of where they might be useful, sure.
But compared to the wealth of other, more useful features that C++ lacks,
the existing solutions seem more-or-less "good enough".

These are the ones who need the most convincing. And they're more likely to
be convinced by good *problems* than how you go about solving them.

We should start agreeing, there are different "types" of named parameters,
Post by m***@gmail.com
needed for different people. There is not "best", solution if it does one
type only.
The problem there is, as I've mentioned before, you're working in the same
space. However much different people may need different kinds of named
parameters, C++ as a whole will be dis-served by having different syntax's
for what is essentially a minor variation of the same thing.

Again, I hate using principles as bludgeons, but Remember the Vasa! It's
important to look back on what you're proposing from a high level and see
if it actually leads to good, easily understood code. And if not, maybe we
don't need it so badly.

Hell, even if we agree on one of these points, it will be progress.
--
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/8e2b5a47-f22b-4cd6-ba68-9802bfff7bc1%40isocpp.org.
Dejan Milosavljevic
2018-08-24 12:20:31 UTC
Permalink
Lets start wit very small list.

1. Declaration
1.1 No changes. Remain as is.
1.X Add Your preferences here
1.Y and here ...

2. Call
2.1 Dot style
Declaration: void f( int a, int b );
Call: f( .a=1, .b=2 );
2.X Add Your preferences here
2.Y and here ...
My opinion is: 1.1 and 2.1.

Extend this list with one line examples.
Do not explain why is something wrong and another is right.
Post by Nicol Bolas
Post by m***@gmail.com
Back to the topic.
Discussions like this one come and go every 2-3 years. And we make ZERO
progress. At least no written progress.
May be we should make poll, what the most wanted types of named
parameters are?
May be we should write a paper to see what direction the committee is
willing to pursue, *if any*? Because right now I am not sure if the
implementation is the problem or the concept.
But above all, we should start agreeing on *something*.
Otherwise, after the dust settles, we will have nothing. As always.
That's what this thread was trying to accomplish. The reason all that
arguing happens is that everyone is focused on the *solutions*, rather
than the problems.
Consider your explanation of "weak named arguments" from the other thread.
Your definition allows "optional" names to determine which function in an
overload set gets called. And in so doing, actually allows users to
*require* that you use names to call the function with a certain default
parameters.
But if the problem you're trying to solve with the proposal is to make
meaning apparent at the call site in a way the compiler can verify, then
you don't *need* names to factor into overload resolution or default
arguments at all. That would therefore be an extraneous bit of
functionality that isn't helping the feature solve the actual problem being
solved.
The only way to move forward is to localize the problem space into a
specific set of problems to be solved. If you can get broad agreement on
what problems need to be solved, or at least some series of problems with
various ratings of how much of a problem they are compared to existing
solutions, *then* you can move towards a design.
Having a small, well-defined set of problems to be solved focuses
discussions of the eventual proposal. It keeps people from saying, "well,
it doesn't do this" because... it's not *supposed* to do that.
We should start agreeing we are split, lets say 50/50 to opponents and
Post by m***@gmail.com
proponents, and no need to "convince" the other side they are "wrong".
You're not factoring in one group (to which I am a member): the group of
people who have yet to be convinced that C++ needs named parameters *of
any form*. People have provided examples of where they might be useful,
sure. But compared to the wealth of other, more useful features that C++
lacks, the existing solutions seem more-or-less "good enough".
These are the ones who need the most convincing. And they're more likely
to be convinced by good *problems* than how you go about solving them.
We should start agreeing, there are different "types" of named parameters,
Post by m***@gmail.com
needed for different people. There is not "best", solution if it does one
type only.
The problem there is, as I've mentioned before, you're working in the same
space. However much different people may need different kinds of named
parameters, C++ as a whole will be dis-served by having different syntax's
for what is essentially a minor variation of the same thing.
Again, I hate using principles as bludgeons, but Remember the Vasa! It's
important to look back on what you're proposing from a high level and see
if it actually leads to good, easily understood code. And if not, maybe we
don't need it so badly.
Hell, even if we agree on one of these points, it will be progress.
--
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
To view this discussion on the web visit https://groups.google.com/a/
isocpp.org/d/msgid/std-proposals/8e2b5a47-f22b-4cd6-
ba68-9802bfff7bc1%40isocpp.org
<https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/8e2b5a47-f22b-4cd6-ba68-9802bfff7bc1%40isocpp.org?utm_medium=email&utm_source=footer>
.
--
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAEfefmyFhMGM2UbPmCmKd%2B%3D1LgimaZ0-QkJDhov3E_0oqhQzkg%40mail.gmail.com.
i***@gmail.com
2018-08-24 13:07:41 UTC
Permalink
Post by Dejan Milosavljevic
Lets start wit very small list.
1. Declaration
1.1 No changes. Remain as is.
1.X Add Your preferences here
1.Y and here ...
2. Call
2.1 Dot style
Declaration: void f( int a, int b );
Call: f( .a=1, .b=2 );
2.X Add Your preferences here
2.Y and here ...
My opinion is: 1.1 and 2.1.
Extend this list with one line examples.
Do not explain why is something wrong and another is right.
1. Declaration
1.1 No changes. Remain as is.
1.2 Struct: `struct f_P{ int a; int b; }; void f(f_P);` (no change to
language)

2. Call
2.1 `f( .a=1, .b=2 );`
2.2 `f({ .a = 1, .b = 2 });` (no change to language)

My preferred is 1.2 and 2.2
--
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/ba2da34e-98f3-4d42-9a2a-5b35cffe51d4%40isocpp.org.
David Brown
2018-08-24 13:55:12 UTC
Permalink
Post by Dejan Milosavljevic
Lets start wit very small list.
1. Declaration
1.1 No changes. Remain as is.
1.X Add Your preferences here
1.Y and here ...
2. Call
2.1 Dot style
Declaration: void f( int a, int b );
Call: f( .a=1, .b=2 );
2.X Add Your preferences here
2.Y and here ...
My opinion is: 1.1 and 2.1.
Extend this list with one line examples.
Do not explain why is something wrong and another is right.
1. Declaration
1.1 No changes. Remain as is.
1.2 Struct: `struct f_P{ int a; int b; }; void f(f_P);` (no change to
language)
2. Call
2.1 `f( .a=1, .b=2 );`
2.2 `f({ .a = 1, .b = 2 });` (no change to language)
My preferred is 1.2 and 2.2
(Extending the list means copying it, then adding more - don't remove
parts of it as it makes other changes more difficult.)

1. Declaration
1.1 No changes. Remain as is.
1.2 Struct: `struct f_P{ int a; int b; }; void f(f_P);` (no change to
language)

2. Call
2.1 Dot style
Declaration: void f( int a, int b );
Call: f( .a=1, .b=2 );
2.1b Mixed dot style
Call: f( 1, .b=2 ); (Positional arguments allowed before named
ones, but not after named arguments)
2.1c Dot style with re-arrangements
Call: f(.b = 2, .a = 1);
2.1d Dot style with override of default parameters
Declaration: void g(int a = 10, int b = 20, int c = 30)
Call: g(.b = 2); (Same as g(10, 2) would be today)

2.2 f({ .a = 1, .b = 2 }); (no change to language)


My preference is 1.1 and at least 2.1b but ideally 2.1c or 2.1d.
--
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/plp2jt%2491c%241%40blaine.gmane.org.
Hyman Rosen
2018-08-24 16:24:04 UTC
Permalink
Post by David Brown
(Extending the list means copying it, then adding more - don't remove
parts of it as it makes other changes more difficult.)
1. Declaration
1.1 No changes. Remain as is.
1.2 Struct: `struct f_P{ int a; int b; }; void f(f_P);` (no change to
language)
2. Call
2.1 Dot style
Declaration: void f( int a, int b );
Call: f( .a=1, .b=2 );
2.1b Mixed dot style
Call: f( 1, .b=2 ); (Positional arguments allowed before named
ones, but not after named arguments)
2.1c Dot style with re-arrangements
Call: f(.b = 2, .a = 1);
2.1d Dot style with override of default parameters
Post by David Brown
Declaration: void g(int a = 10, int b = 20, int c = 30)
Call: g(.b = 2); (Same as g(10, 2) would be today)
2.1e Mixed dot style with positional arguments and rearrangements after
postionals
f(1, .c = 2, .b = 3); (Same as f(1, 3, 2) would be today.)
Post by David Brown
2.2 f({ .a = 1, .b = 2 }); (no change to language)
My preference is 1.1 and all of 2.1, 2.1b, 2.1c, 2.1d, 2.1e.
--
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAHSYqdYubze5qVAhCd1dPRxvgGBnAqU%2BCLuAQwFpEMY4dWq2jA%40mail.gmail.com.
m***@gmail.com
2018-08-24 19:03:55 UTC
Permalink
Post by Dejan Milosavljevic
Lets start wit very small list.
1. Declaration
1.1 No changes. Remain as is.
1.X Add Your preferences here
1.Y and here ...
2. Call
2.1 Dot style
Declaration: void f( int a, int b );
Call: f( .a=1, .b=2 );
2.X Add Your preferences here
2.Y and here ...
My opinion is: 1.1 and 2.1.
Extend this list with one line examples.
Do not explain why is something wrong and another is right.
We should move away from "no changes to the declaration" if we are to make
any progress:

What I have established, having had discussions about named arguments
Post by Dejan Milosavljevic
on multiple occasions,
1) it needs to be an opt-in for the author of a library, so no
automagic naming. Some library
authors do not want users relying on names that the library author
didn't expect them to rely
on, in order to avoid breakage that wasn't considered beforehand.
That aside, it seems so far the weak names are the only ones desired.
--
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/b3fd1d1d-2637-4ce3-8ad2-01b81e17b189%40isocpp.org.
Matthew Woehlke
2018-08-24 19:22:09 UTC
Permalink
Post by m***@gmail.com
That aside, it seems so far the weak names are the only ones desired.
Really?

Granted, I'm not sure at this point what "weak names" means, but I'm not
sure I agree with that statement.
--
Matthew
--
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/d0a6e276-8bbe-e65c-1e9f-09cc9c28b7ef%40gmail.com.
m***@gmail.com
2018-08-24 20:22:15 UTC
Permalink
Post by Matthew Woehlke
Post by m***@gmail.com
That aside, it seems so far the weak names are the only ones desired.
Really?
Granted, I'm not sure at this point what "weak names" means, but I'm not
sure I agree with that statement.
As far as the votes so far are concerned. As you know, I believe we need
both.
Post by Matthew Woehlke
--
Matthew
--
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/e630d4f6-1156-4149-90be-d45733f7d0b5%40isocpp.org.
Hyman Rosen
2018-08-24 21:15:59 UTC
Permalink
Post by m***@gmail.com
Post by Matthew Woehlke
Post by m***@gmail.com
That aside, it seems so far the weak names are the only ones desired.
Really?
Granted, I'm not sure at this point what "weak names" means, but I'm not
sure I agree with that statement.
As far as the votes so far are concerned. As you know, I believe we need
both.
I don't see why leaving declarations alone affects using parameter names to
specify arguments.
--
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAHSYqdakfiBVYNKQdu4mzCQZuyVQdUHrxp6%3Dq2s3oG7UasyxQw%40mail.gmail.com.
m***@gmail.com
2018-08-24 22:00:37 UTC
Permalink
Post by Hyman Rosen
Post by m***@gmail.com
Post by Matthew Woehlke
Post by m***@gmail.com
That aside, it seems so far the weak names are the only ones desired.
Really?
Granted, I'm not sure at this point what "weak names" means, but I'm not
sure I agree with that statement.
As far as the votes so far are concerned. As you know, I believe we need
both.
I don't see why leaving declarations alone affects using parameter names
to specify arguments.
Because the user code starts depending on things, the library author might
not want it to depend on.
Much like "don't reopen std", "don't take the address of a std function",
library authors want the arguments to remain outside the interface to their
code.

From a practical standpoint, the author might want to introduce naming
partially either because the code is in flux,
or simply because he considers only few argument important and worthy of
standardizing - after all it is his interface, he should be able to design
it how he wants it.
Also, with a separate syntax the author *should* be able to use any word,
including keywords like for, if, default.
--
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/9b26b74c-41c6-46c1-974e-1cd39f036a96%40isocpp.org.
Hyman Rosen
2018-08-26 04:23:55 UTC
Permalink
Post by m***@gmail.com
Post by Hyman Rosen
Post by m***@gmail.com
Post by Matthew Woehlke
Post by m***@gmail.com
That aside, it seems so far the weak names are the only ones desired.
Really?
Granted, I'm not sure at this point what "weak names" means, but I'm not
sure I agree with that statement.
As far as the votes so far are concerned. As you know, I believe we need
both.
I don't see why leaving declarations alone affects using parameter names
to specify arguments.
Because the user code starts depending on things, the library author might
not want it to depend on.
Much like "don't reopen std", "don't take the address of a std function",
library authors want the arguments to remain outside the interface to their
code.
Too bad? If we have named parameters, parameters will have to have
meaningful names. That's a good thing anyway, because it helps document
what functions do.
Post by m***@gmail.com
From a practical standpoint, the author might want to introduce naming
partially either because the code is in flux,
or simply because he considers only few argument important and worthy of
standardizing - after all it is his interface, he should be able to design
it how he wants it.
No. It's much more important to have a consistent language. Letting
people decide that only certain parameters are named is silly.

Also, with a separate syntax the author *should* be able to use any word,
Post by m***@gmail.com
including keywords
This is ridiculously unnecessary.
--
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAHSYqdZhJMgVd155mRzgL3zgakPpV3UY%2BxGTAyMZKtVy0rcaLA%40mail.gmail.com.
m***@gmail.com
2018-08-26 09:48:34 UTC
Permalink
Post by Hyman Rosen
Post by m***@gmail.com
Post by Hyman Rosen
Post by m***@gmail.com
Post by m***@gmail.com
Post by m***@gmail.com
That aside, it seems so far the weak names are the only ones
desired.
Really?
Granted, I'm not sure at this point what "weak names" means, but I'm not
sure I agree with that statement.
As far as the votes so far are concerned. As you know, I believe we
need both.
I don't see why leaving declarations alone affects using parameter names
to specify arguments.
Because the user code starts depending on things, the library author
might not want it to depend on.
Much like "don't reopen std", "don't take the address of a std function",
library authors want the arguments to remain outside the interface to their
code.
Too bad? If we have named parameters, parameters will have to have
meaningful names. That's a good thing anyway, because it helps document
what functions do.
Sure, in principal, but in practice this is not always possible or even
desirable, especially considering the prize to pay is breaking someone's
build.

And it is not just "library authors" breaking "users" code.

Think about a class that has a public interface and private implementation,
be it private functions, functions in anonymous ns, pimpl etc.

Ok, one will be a good guy and be careful to pick correct names upfront for
the public interface, what about all *other* functions that a *coworker*
might use?
Dozens upon dozens helper and implementation functions across all sorts of
files with different state of stability!

Without an ability to *pin* a name as *stable* there is no guarantee ever
one is not breaking someone else's code, even his own.

What would be the solution to this? A convection? Documentation? How is
this better then expressing it all in the code itself!
Post by Hyman Rosen
Post by m***@gmail.com
From a practical standpoint, the author might want to introduce naming
partially either because the code is in flux,
or simply because he considers only few argument important and worthy of
standardizing - after all it is his interface, he should be able to design
it how he wants it.
No. It's much more important to have a consistent language. Letting
people decide that only certain parameters are named is silly.
It is not so silly, even if we take stability of the code away from the
picture (and we can't, but lets say we do) - often the name is redundant
and/or there is no good name.

How to name the argument of sqrt? Why is it named that way? Is it
self-explanatory? Do you know how it is called according to the standard
library right now? Which implementation of it?

This tiny example shows all the problems with reusing arguments for names -
arguments *might* or might *not* require design and expressiveness, names,
*always* *do*.

And it does not stop there. Do you really need the begin and end iterators
of every algorithm named? And how would you name them? begin and end,
possibly colliding with the functions?
first and last, like they are now *unofficially* called and documented in
cppreference? *But this is wrong, end is not last, but one past last! *

And so on, reusing arguments creates problems *bigger*, then the
"simplicity" it promises:

Every argument ever, on every function ever,* can break code*, AND every
argument is essentially *mandatory* to design, you can't even mark it as
"name can be skipped" like in swift sqrt(_ val: double)

There is a reason this idea did not get traction in 91, no need to go the
same path again. We should move forward.
Post by Hyman Rosen
Also, with a separate syntax the author *should* be able to use any word,
Post by m***@gmail.com
including keywords
This is ridiculously unnecessary.
--
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/5940029a-6a96-47d7-86cf-4ae915a1f86f%40isocpp.org.
Hyman Rosen
2018-08-27 15:01:15 UTC
Permalink
Post by Hyman Rosen
Too bad? If we have named parameters, parameters will have to have
Post by Hyman Rosen
meaningful names. That's a good thing anyway, because it helps document
what functions do.
Sure, in principal, but in practice this is not always possible or even
desirable, especially considering the prize to pay is breaking someone's
build.
The parameter names become part of the interface. If you change method
names, you can break a build. If you add overloads, you can break a
build. If you change parameter names, you can break a build.

So don't? Or notify the users first? Other languages with named
parameters seem to have coped.

Without an ability to *pin* a name as *stable* there is no guarantee ever
Post by Hyman Rosen
one is not breaking someone else's code, even his own.
What would be the solution to this? A convection? Documentation? How is
this better then expressing it all in the code itself!
The "explanation" is the name of the parameter in the declaration. Nothing
more is needed.

It is not so silly, even if we take stability of the code away from the
Post by Hyman Rosen
picture (and we can't, but lets say we do) - often the name is redundant
and/or there is no good name.
The parameter must have some name. That becomes the name used for named
parameter passing.

How to name the argument of sqrt? Why is it named that way? Is it
Post by Hyman Rosen
self-explanatory? Do you know how it is called according to the standard
library right now? Which implementation of it?
It's named 'x' because that's how the C standard refers to it. The
parameters of operator<= are named 'lhs' and 'rhs'.
Whatever. Some name gets picked, and that's the name.

This tiny example shows all the problems with reusing arguments for names -
Post by Hyman Rosen
arguments *might* or might *not* require design and expressiveness,
names, *always* *do*.
Parameters always require expressiveness, because the contract that defines
what the function does needs to refer to them in a way that makes sense.
(Which, by the way, can be the next fight - national language arguments
over named parameters.)

And it does not stop there. Do you really need the begin and end iterators
Post by Hyman Rosen
of every algorithm named? And how would you name them? begin and end,
possibly colliding with the functions?
first and last, like they are now *unofficially* called and documented in
cppreference? *But this is wrong, end is not last, but one past last! *
Yes, we need them named, because the contract that describes what the
function does has to refer to them by name.
If 'begin' and 'end' are the best names, then those are the names to use,
and the implementation just has to deal with it.

Every argument ever, on every function ever,* can break code*, AND every
Post by Hyman Rosen
argument is essentially *mandatory* to design, you can't even mark it as
"name can be skipped" like in swift sqrt(_ val: double)
Huh? Named parameters don't eliminate positional parameters. If you want
to call sqrt(7.3), that works fine. (I'm assuming the Ada version of named
parameters, which is a leading set of positional arguments followed by a
trailing set of named arguments in arbitrary order, with defaulted
parameters elidable.)
--
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAHSYqdaF-UCWCkR0CbgeCU_y6Bg51Hwjy8_ft2Lfxc91n7B-CA%40mail.gmail.com.
Matthew Woehlke
2018-08-27 15:22:25 UTC
Permalink
Post by Hyman Rosen
The parameter names become part of the interface. If you change method
names, you can break a build. If you add overloads, you can break a
build. If you change parameter names, you can break a build.
So don't? Or notify the users first? Other languages with named
parameters seem to have coped.
...but in other languages, argument names have *always* been part of the
API, yes?

If C++ had done that from day one, it would probably be okay. It's the
notion of *changing* this that makes people nervous.
Post by Hyman Rosen
Post by m***@gmail.com
How to name the argument of sqrt? Why is it named that way? Is it
self-explanatory? Do you know how it is called according to the standard
library right now? Which implementation of it?
It's named 'x' because that's how the C standard refers to it. The
parameters of operator<= are named 'lhs' and 'rhs'.
Whatever. Some name gets picked, and that's the name.
And just how do you expect all the existing standard library
implementations, which not only don't use standard names right now, but
*need to be robust against users #define'ing those names*, to get fixed?

Remember, right now this code is supposed to compile:

#define lhs if(0)
#include <algorithm>
// do stuff

(Are you proposing that these named arguments will be *absolutely
dependent* on modules?)
Post by Hyman Rosen
Parameters always require expressiveness, because the contract that defines
what the function does needs to refer to them in a way that makes sense.
By "contract", are you talking about Contracts, or just the textual
description? Because I'm not convinced that every function will use the
former, and the latter can certainly say things like "the first argument".
Post by Hyman Rosen
(Which, by the way, can be the next fight - national language arguments
over named parameters.)
No, we don't need to go there. The function names are en_US. Not using
the same for the parameter names also would be madness.
--
Matthew
--
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/2db8cc0a-5c6c-486c-f550-ec87e31e4f7d%40gmail.com.
Magnus Fromreide
2018-10-20 07:18:37 UTC
Permalink
Post by Hyman Rosen
Post by m***@gmail.com
Post by Hyman Rosen
Post by m***@gmail.com
Post by Matthew Woehlke
Post by m***@gmail.com
That aside, it seems so far the weak names are the only ones desired.
Really?
Granted, I'm not sure at this point what "weak names" means, but I'm not
sure I agree with that statement.
As far as the votes so far are concerned. As you know, I believe we need
both.
I don't see why leaving declarations alone affects using parameter names
to specify arguments.
Because the user code starts depending on things, the library author might
not want it to depend on.
Much like "don't reopen std", "don't take the address of a std function",
library authors want the arguments to remain outside the interface to their
code.
Too bad? If we have named parameters, parameters will have to have
meaningful names. That's a good thing anyway, because it helps document
what functions do.
They will? What is the name?

Consider

int foo(double, double);
int foo(double xpos, double ypos);
int foo(double len, double angle);

Today that is legal C++ and all declarations of foo refer to the same
function, I am assuming that we can't break that.

The first declaration would obviously not introduce any parameter names but
the latter two does.

I suppose a call to

foo(.xpos = 1, .angle = 2);

should be ill formed - the argument against that is if we want to introduce
alternative names for named arguments.

This by the way also rules out any kind of overloading on parameter names.

One thing it don't rule out is usage of parameter names as guides in deducing
the type of an argument so

struct angle { angle(double); };
int foo(double xpos, double ypos);
int foo(double len, angle angle);

foo(1, .angle = 1);

could be seen as not ambigous with the xpos variant.

/MF
Post by Hyman Rosen
Post by m***@gmail.com
From a practical standpoint, the author might want to introduce naming
partially either because the code is in flux,
or simply because he considers only few argument important and worthy of
standardizing - after all it is his interface, he should be able to design
it how he wants it.
No. It's much more important to have a consistent language. Letting
people decide that only certain parameters are named is silly.
Also, with a separate syntax the author *should* be able to use any word,
Post by m***@gmail.com
including keywords
This is ridiculously unnecessary.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAHSYqdZhJMgVd155mRzgL3zgakPpV3UY%2BxGTAyMZKtVy0rcaLA%40mail.gmail.com.
--
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/20181020071836.GA1476%40noemi.bahnhof.se.
Hyman Rosen
2018-10-20 23:30:57 UTC
Permalink
Post by Magnus Fromreide
int foo(double, double);
int foo(double xpos, double ypos);
int foo(double len, double angle);
Today that is legal C++ and all declarations of foo refer to the same
function, I am assuming that we can't break that.
Assume away. I would happily break that. In fact, we have a static
analysis tool at my company for which I personally have written the test
that detects and warns about inconsistent parameter names.

What with contracts and modules, the first declaration is assuming
increased signifigance anyway. But if you want maximum preservation of
silliness, it's easy enough - make it the rule that if a function is
declared with the same parameter given multiple names, that parameter
cannot be specified by a named argument association.
--
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-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAHSYqdaGiE9vFd3ugXuRCOnSxWitO1KKy76pXr04mmfAqrcJgQ%40mail.gmail.com.
Loading...