August 23, 2019
On Friday, 23 August 2019 at 16:19:51 UTC, Dennis wrote:
> You can't leave `fullScreenMonitor` to the default while passing `parentWindow` with this DIP, but writing out that argument doesn't seem like a big loss to me. And even if it is, limitations can easily be lifted without much friction. If it turns out that reordering causes problems down the line, deprecating them would be more of a hassle.

It is a loss. It's basically the same situation as the thing people were bringing up - named arguments allow you to detect a case when arguments get renamed and semantics change, rect(x, y, width, height) vs rect(x1, y1, x2, y2). But this is almost the same case, except you are binding yourself to the default value for fullScreenMonitor to null. You want to do the default here. What if the default gets changed and fullScreenMonitor is supposed to be fooMonitor instead? You can get silent breakages because you're overriding the default behavior now.

I like the idea of this DIP. I think skipping over default parameters should be a thing.
August 23, 2019
On Friday, 23 August 2019 at 16:47:14 UTC, H. S. Teoh wrote:
> But this DIP neither enables nor disables inordinately long parameter lists: the language already allows them!

It allows them, but it doesn't encourage them. Long parameter lists are currently rare in D as they should be.

> The only thing worse than an overly-long parameter list is one in which you cannot (easily) tell which argument corresponds with which parameter, and that's something this DIP would fix (by letting you name the arguments so that they are self-documenting).  So your argument doesn't really detract from this DIP.

If you look at some of the longest parameter lists on Dub:
https://github.com/jmh530/libnlopt/blob/06996b5c415cee2d2edd4efdeec078182fa24879/source/libnlopt/api.d#L300
https://github.com/d-widget-toolkit/dwt/blob/fa6b22597901a21fe51f91fb9628460fc71641fd/org.eclipse.swt.gtk.linux.x86/src/org/eclipse/swt/graphics/ImageData.d#L1794
https://github.com/Vild/xcb-d/blob/79e977943b187152924015bea090ee832ae92ef9/source/xcb/xkb.d#L5022
https://github.com/libmir/lapack/blob/1f00f70a15cdf10ba7564eff7e53dac3d070bd56/source/lapack/lapack.d#L651

My first observation is they are courtesy of other languages and not original D functions.
Secondly, I don't think "if only we could use named parameters with default values, then these functions would be great.".

August 23, 2019
On Friday, 23 August 2019 at 19:01:35 UTC, JN wrote:
> named arguments allow you to detect a case when arguments get renamed and semantics change, rect(x, y, width, height) vs rect(x1, y1, x2, y2).  (...)
> What if the default gets changed and fullScreenMonitor is supposed to be fooMonitor instead?

If they did something like that tens of thousands of C projects would break. For that reason they'd never simply overhaul function semantics while remaining the same function prototype.
It strikes me that people consider this an actual real-world scenario, but maybe I'm missing something. Did this ever happen to a library?


August 23, 2019
On Friday, 23 August 2019 at 17:59:38 UTC, Andrei Alexandrescu wrote:
> On 8/23/19 1:42 PM, H. S. Teoh wrote:
>> On Fri, Aug 23, 2019 at 05:16:16PM +0000, bachmeier via Digitalmars-d wrote:
>>> On Friday, 23 August 2019 at 16:47:14 UTC, H. S. Teoh wrote:
>> 
>> But this:
>> 
>> 	foo(x: 4, y: 8, z: 9,
>> 		screen: scr1, widget: wg2,
>> 		options: opts, menu: menu3);
>> 
>> is no worse than this:
>> 
>> 	FooParams params;
>> 	params.x = 4;
>> 	params.y = 8;
>> 	params.z = 9;
>> 	params.screen = scr1;
>> 	params.widget = wg2;
>> 	params.options = opts;
>> 	params.menu = menu3;
>> 	foo(params);
>
> Exactly. It seems that for short lists (2-3 arguments) naming would be a net negative (add notational overhead when there's little possibility of a confusion to start with). Then, when the list gets longer it actually makes matters _worse_ because it disallows skipping of defaulted arguments.
>
> This can't go.

C# version (C# online REPL https://repl.it/repls/KnowingDeliriousLifecycles)
==============================
using System;
class MainClass {
  static void fun( int arg1, string arg2, double arg3, string def1 ="one", int def2 = 2) {
    Console.WriteLine( $"fun( {arg1}, {arg2}, {arg3}, {def1}, {def2} )");
  }
  public static void Main (string[] args) {
    // ok
    fun( arg3:3.14, arg2:"world", arg1:789);

    // Named arguments must appear after the positional arguments
    //fun( 123, arg2:"world", 2.72, def1:"hello" );

    // ok now
    fun( 123, arg2:"hello", arg3:9.8, def2:-2);

    // defaulted args can be skipped in any order
    fun( 123, "hello", 6e23, def1:"world");
    fun( 123, "hello", def2:-2, arg3:3e8);

    //The best overloaded method match for `MainClass.fun(int, string, double, string, int)' has some invalid arguments
    // Argument `#2' cannot convert `int' expression to type `string'
    //fun( 123, 735, def2:-2, arg2:"wat?");
  }
}
==============================
fun( 789, world, one, 456 )
fun( 123, world, hello, 2 )
fun( 123, hello, one, 456 )
fun( 123, hello, world, 2 )

> defaulted args = args that have default value
totally:
- named args follows by unnamed args, not vice versa
- unnamed args correspond to order of args in func-DEF.
  any of unnamed arg can be non-defaulted or defaulted arg in func-DEF.
  (as now)
- named arg must not be specified again if its already set as unnamed.
- u cannot skip defaulted args in unnamed list (as now)
  [what is not prohibited is allowed]:
    any defaulted args can be skipped when named list has begun

August 23, 2019
On Friday, 23 August 2019 at 19:21:48 UTC, a11e99z wrote:
> On Friday, 23 August 2019 at 17:59:38 UTC, Andrei Alexandrescu wrote:
>> On 8/23/19 1:42 PM, H. S. Teoh wrote:
>>> On Fri, Aug 23, 2019 at 05:16:16PM +0000, bachmeier via Digitalmars-d wrote:
>>>> On Friday, 23 August 2019 at 16:47:14 UTC, H. S. Teoh wrote:
>>> 

> - named arg must not be specified again if its already set as unnamed.

CE error for this case is:
Named argument 'name' specified multiple times.
August 23, 2019
On Friday, 23 August 2019 at 19:25:17 UTC, a11e99z wrote:
> On Friday, 23 August 2019 at 19:21:48 UTC, a11e99z wrote:
>> On Friday, 23 August 2019 at 17:59:38 UTC, Andrei Alexandrescu wrote:
>>> On 8/23/19 1:42 PM, H. S. Teoh wrote:
>>>> On Fri, Aug 23, 2019 at 05:16:16PM +0000, bachmeier via Digitalmars-d wrote:
>>>>> On Friday, 23 August 2019 at 16:47:14 UTC, H. S. Teoh wrote:
>>>> 
>
>> - named arg must not be specified again if its already set as unnamed.
>
> CE error for this case is:
> Named argument 'name' specified multiple times.

*C#
and of course to:
> named arg must not be specified again if its already set as unnamed.
- named arg should be specified once only
August 23, 2019
On Friday, 23 August 2019 at 18:41:56 UTC, H. S. Teoh wrote:
> I just don't see the benefit of going through all the trouble of the DIP process and subsequent implementation work, only to end
> up with a half-hearted feature that doesn't even offer these
> two most desirable things of a named argument implementation.

The current DIP has less complexity. What if you go through all the trouble of implementing it only to find out some tricky edge cases you didn't think about? E.g. what does this code do:
```
import std.stdio;
void foo(int a, double b) {writeln("0");}
void foo(int b, int a) {writeln("1");}

void main()
{
    foo(b: 10, 0);
}
```

You might have an obvious intuition for this situation ("that should be an error!"), but maybe there are other ones.
August 23, 2019
On Friday, 23 August 2019 at 19:30:40 UTC, Dennis wrote:
> ```
> import std.stdio;
> void foo(int a, double b) {writeln("0");}
> void foo(int b, int a) {writeln("1");}
>
> void main()
> {
>     foo(b: 10, 0);
> }
> ```

Correction:
```
import std.stdio;
void foo(int a, int b) {writeln("0");}
void foo(int b, double a) {writeln("1");}
void main()
{
    foo(b: 10, 0);
}
```

The point is, is an exact type match more important than parameter order match?
August 23, 2019
On Friday, 23 August 2019 at 19:33:07 UTC, Dennis wrote:
> On Friday, 23 August 2019 at 19:30:40 UTC, Dennis wrote:
>> ```
>> import std.stdio;
>> void foo(int a, double b) {writeln("0");}
>> void foo(int b, int a) {writeln("1");}
>>
>> void main()
>> {
>>     foo(b: 10, 0);
>> }
>> ```
>
> Correction:
> ```
> import std.stdio;
> void foo(int a, int b) {writeln("0");}
> void foo(int b, double a) {writeln("1");}
> void main()
> {
>     foo(b: 10, 0);
> }
> ```
>
> The point is, is an exact type match more important than parameter order match?

as I said https://forum.dlang.org/post/wlcwgrfotdfpojbtktne@forum.dlang.org
- named args follows by unnamed args, not vice versa, no mixing
August 23, 2019
On Friday, 23 August 2019 at 19:33:07 UTC, Dennis wrote:
> Correction:
> ```
> import std.stdio;
> void foo(int a, int b) {writeln("0");}
> void foo(int b, double a) {writeln("1");}
> void main()
> {
>     foo(b: 10, 0);
> }
> ```
>
> The point is, is an exact type match more important than parameter order match?

Walter's proposal from the previous discussion was that named parameters should use the same rules for reordering as named struct initialization [1] (which in turn are the same rules used by designated initializers in C99 [2]). So in this case, the second overload would be called, because it's the only one with a parameter after `b`.

Even if these aren't your favorite rules, I think there's a lot to be said for consistency.

[1] https://dlang.org/spec/struct.html#static_struct_init
[2] http://port70.net/~nsz/c/c99/n1256.html#6.7.8p17