May 12, 2020
On Monday, 11 May 2020 at 11:37:07 UTC, Mike Parker wrote:
> [snip]

I think the arguments brought on in the previous review with respect to the API remain a concern. The feedback notes this issue, but in response the DIP author notes that if a parameter is not found then it is an error. Of course, this is the whole issue. Someone can change
void foo(int x, int y, int z) {}
to
void foo(int x, int a, int b) {}
and user code that relies on calling foo with keywords for y and z will break. I think this also connects with the feedback that the feature should be opt-in.

I think the comments in the prior discussion with respect to Python's positional-only and keyword-only arguments make sense (see [1] for the PEP on this). In particular, the only change I would make to this DIP would be to make it so that keyword arguments are opt-in, such asmaking the syntax something like
auto functionName(positional_only_parameters, /, positional_or_keyword_parameters) {}
While python requires "/" to force positional_only this is because "positional_or_keyword_parameters" is the default. Thus, I would recommend having / to force positional_or_keyword_parameters. So for instance, you could still have
void foo(int x, int a, int b) {}
and only have positional arguments and no breakage if names change, or you could potentially allow keyword arguments, as in
void foo(int x, /, int a, int b) {}
and call it like
foo(3, 2, 1);
foo(3, 2, b:1);
foo(3, a:2, b:1);
foo(3, b:1, a:2);



[1] https://www.python.org/dev/peps/pep-0570/

May 12, 2020
On Tuesday, 12 May 2020 at 18:57:25 UTC, jmh530 wrote:
> On Monday, 11 May 2020 at 11:37:07 UTC, Mike Parker wrote:
>> [...]
>
> I think the arguments brought on in the previous review with respect to the API remain a concern. The feedback notes this issue, but in response the DIP author notes that if a parameter is not found then it is an error. Of course, this is the whole issue. Someone can change
> void foo(int x, int y, int z) {}
> to
> void foo(int x, int a, int b) {}
> and user code that relies on calling foo with keywords for y and z will break. I think this also connects with the feedback that the feature should be opt-in.
>
> [...]

If the user uses named arguments then that is by definition opt-in. It makes no  sense for the developer to opt-in for named arguments as well.

I had already made my case regarding the "opt-in" part of the discussion, by pointing out that c# has named arguments by default and you can't opt out of it.

-Alex
May 12, 2020
On Tuesday, 12 May 2020 at 21:03:34 UTC, 12345swordy wrote:

> If the user uses named arguments then that is by definition opt-in. It makes no  sense for the developer to opt-in for named arguments as well.
>
> I had already made my case regarding the "opt-in" part of the discussion, by pointing out that c# has named arguments by default and you can't opt out of it.

I wasn't going to comment on this, but...yes, it makes perfect sense for the developer to opt in. Maybe you don't want someone calling arguments by name.

Making a change like this *and* forcing it on everyone is a change that belongs in D 3.0. "C# forces it on everyone" is not an argument.
May 13, 2020
On Tuesday, 12 May 2020 at 22:01:00 UTC, bachmeier wrote:


> I wasn't going to comment on this, but...yes, it makes perfect sense for the developer to opt in.

No, it does not make sense for the developer to opt in as the opt in process is done by the user here. You fear of code breakage due to name change still exist in this scenario, even if did make it opt in.

> Maybe you don't want someone calling arguments by name.

Which I found the reasons being brought forward by this weak at best, nonissue at worst. If you end up in a situation where you frequently chaining names of things, then you are doing something very wrong.

> Making a change like this *and* forcing it on everyone is a change that belongs in D 3.0.

Nonsense. The d language already does that already via a desperation process. The most recent change is the dip 25 start being forced on developers. This isn't c++ here. Making it opt-in will kill the adaptation of said feature, as many libraries have need to be modify and recompile which will require signficant amount of time here.

>"C# forces it on everyone" is not
> an argument.

No, the argument is there has been no apocalypse case scenario in the c# community which results from changing the name argument ever sense it was introduce in 4.0.

May 13, 2020
On Tuesday, 12 May 2020 at 21:03:34 UTC, 12345swordy wrote:
> [snip]
>
> If the user uses named arguments then that is by definition opt-in. It makes no  sense for the developer to opt-in for named arguments as well.
>
> I had already made my case regarding the "opt-in" part of the discussion, by pointing out that c# has named arguments by default and you can't opt out of it.
>
> -Alex

The underlying worry is that the developer changes the names of the parameters and user code that depends on the names not changing breaks. When I say opt-in, I mean that the developer opts-in to let the user be able to use them. In essence, they would be acknowledging that these parameters will not have their names changed without a clear path forward.

Not having programmed anything in C#, I wanted to double-check how C#'s named arguments work. Even after the change in 7.2 [1], C#'s named arguments are much more limited than what is in this DIP. The way C#'s work is that you can have all of them named, or you can put the named ones at the end or you keep the positional arguments in the right place. The proposal in the DIP is more flexible, as far as I can tell.

[1] https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-7.2/non-trailing-named-arguments
May 12, 2020
We already have named arguments in D since the very beginning - the struct initialization syntax.

Not a single person has complained about breakage when implementers changed the names of the struct fields.

This is similar to:

1. what happens if the implementer changes the types of the parameters?

2. what happens if the implementer changes the order of the parameters?

Then user code breaks.

If anything, this feature will motivate implementers to take some care to name the parameters appropriately.
May 13, 2020
On Wednesday, 13 May 2020 at 00:37:51 UTC, Walter Bright wrote:
> We already have named arguments in D since the very beginning - the struct initialization syntax.
>
> Not a single person has complained about breakage when implementers changed the names of the struct fields.
>
> This is similar to:
>
> 1. what happens if the implementer changes the types of the parameters?
>
> 2. what happens if the implementer changes the order of the parameters?
>
> Then user code breaks.
>
> If anything, this feature will motivate implementers to take some care to name the parameters appropriately.


How about providing a migration path by adding the ability to deprecate named arguments. In such way, libraries can warn users that a parameter is now deprecated either in favor of otherparameters or for future removal.

An alternative but similar approach would be to enable functions to introspect whether a named argument was called as named or not, in such way the user can provide more verbose deprecation messages without polluting function signature.

May 12, 2020
On 5/12/2020 10:42 AM, Paul Backus wrote:
> The logic behind this feature is that the rules it uses for re-ordering are the same ones already used for struct initializers [1], which are in turn based on the rules used for designated initializers in C99 [2].
> 
> These rules aren't perfect, but consistently using the same rules for everything is much better than having two separate sets of rules, and it's too late to go back and change the struct-initialization syntax now.
> 
> [1] https://dlang.org/spec/struct.html#static_struct_init
> [2] http://port70.net/~nsz/c/c99/n1256.html#6.7.8p17

Thank you for the clear explanation.

Consider the convention that turning a valve clockwise shuts it, and counterclockwise opens it. This matches the convention for tightening and loosening a bolt. It matches a meter where more is clockwise.

Except for the hot water faucet, which goes the other way. I always have to stop and think when I use the hot water faucet.

Consistency and predictability are huge advantages in user interfaces, and override small optimizations.
May 13, 2020
On Wednesday, 13 May 2020 at 00:37:51 UTC, Walter Bright wrote:
> We already have named arguments in D since the very beginning - the struct initialization syntax.
>
> Not a single person has complained about breakage when implementers changed the names of the struct fields.
>

I personally do not use this feature very much. I would expect named arguments for functions to be used significantly more.

> This is similar to:
>
> 1. what happens if the implementer changes the types of the parameters?
>
> 2. what happens if the implementer changes the order of the parameters?
>
> Then user code breaks.
>
> If anything, this feature will motivate implementers to take some care to name the parameters appropriately.

One reason why python supports positional-only arguments is interacting with C. Suppose there is a C library that you generate a wrapper for automatically. At some later point, the C library changes some names of parameters. If we generate a new wrapper for D, then any place where you called these functions with named parameters would break (I believe the alternative would be to remove the names from extern(C), but I believe there are reasons why people don't usually do this). This would have an impact on people who call C from D, but the C implementer would not change their behavior based on this DIP.

Alternately, suppose an implementer does want to change the name of some parameters, for whatever reason. The only thing I can think of is deprecating the old function, then eventually removing the old version and replacing it with a version with the parameter name changed. I don't see anything in the DIP that would suggest that both versions could be used at once. For instance, nothing in the DIP would suggest that the following would compile:

deprecated void foo(int x, int a) {}

void foo(int x, int b) {}

void main()
{
    foo(1, b:2);
}
May 13, 2020
On Wednesday, 13 May 2020 at 02:38:17 UTC, jmh530 wrote:
> [snip]
> I don't see anything in the DIP that would suggest that both versions could be used at once. For instance, nothing in the DIP would suggest that the following would compile:
>

Actually it may compile based on what it says about "function resolution is done by constructing an argument list separately for each function before testing it for matching".

I'm not 100% sure though.