www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - DIP 1019--Named Arguments Lite--Community Review Round 1

reply Mike Parker <aldacron gmail.com> writes:
This is the feedback thread for the first round of Community 
Review for DIP 1019, "Named Arguments Lite":

https://github.com/dlang/DIPs/blob/23ef47a94e0fdd5ddc4b2f6b2f4dcfd3c1f43aa6/DIPs/DIP1019.md

All review-related feedback on and discussion of the DIP should 
occur in this thread. The review period will end at 11:59 PM ET 
on March 1, or when I make a post declaring it complete.

At the end of Round 1, if further review is deemed necessary, the 
DIP will be scheduled for another round of Community Review. 
Otherwise, it will be queued for the Final Review and Formal 
Assessment by the language maintainers.

Please familiarize yourself with the documentation for the 
Community Review before participating.

https://github.com/dlang/DIPs/blob/master/PROCEDURE.md#community-review

Thanks in advance to all who participate.
Feb 15
next sibling parent reply Atila Neves <atila.neves gmail.com> writes:
On Friday, 15 February 2019 at 12:56:45 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1019, "Named Arguments Lite":

 [...]
I'd add my library too as a possible library solution: https://github.com/atilaneves/kwargs
Feb 15
parent reply Francesco Mecca <me francescomecca.eu> writes:
On Friday, 15 February 2019 at 13:49:04 UTC, Atila Neves wrote:
 On Friday, 15 February 2019 at 12:56:45 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1019, "Named Arguments Lite":

 [...]
I'd add my library too as a possible library solution: https://github.com/atilaneves/kwargs
I think that the solution proposed by Atila is better for the following reasons: 1. it is a library solution 2. allows both the user and the author of a library to specify functions with named parameters 3. it is very lightweight But it is not enough for the following reasons: 1. Works only on templates (I'd like someone to explain to me why) 2. Is opinionated about using ad-hoc types to represent data (the opposite of http://wiki.c2.com/?PrimitiveObsession) If there is a consensus against primitive obsessions I think it would be better to solve point 1 and leave the decision to library authors to implement named parameters function or users to make their wrappers. This opt-in behaviour is not different from what it is provided by the DIP
Feb 15
next sibling parent reply 12345swordy <alexanderheistermann gmail.com> writes:
On Friday, 15 February 2019 at 17:38:23 UTC, Francesco Mecca 
wrote:
 On Friday, 15 February 2019 at 13:49:04 UTC, Atila Neves wrote:
 [...]
I think that the solution proposed by Atila is better for the following reasons: 1. it is a library solution 2. allows both the user and the author of a library to specify functions with named parameters 3. it is very lightweight [...]
You miss the other reason on why it is not enough: Compile time and run-time performance penalty. -Alex
Feb 15
next sibling parent reply JN <666total wp.pl> writes:
On Friday, 15 February 2019 at 17:43:52 UTC, 12345swordy wrote:
 You miss the other reason on why it is not enough: Compile time 
 and run-time performance penalty.
 -Alex
Also, when doing a typo, rather than a nice error message "No named argument defined for function foo()", you'd probably get few screens of template vomit :)
Feb 15
parent Atila Neves <atila.neves gmail.com> writes:
On Friday, 15 February 2019 at 17:57:38 UTC, JN wrote:
 On Friday, 15 February 2019 at 17:43:52 UTC, 12345swordy wrote:
 You miss the other reason on why it is not enough: Compile 
 time and run-time performance penalty.
 -Alex
Also, when doing a typo, rather than a nice error message "No named argument defined for function foo()", you'd probably get few screens of template vomit :)
Have you tried it? I attempted to static assert on nonsense with proper error messages. If you did and got terrible error messages, please file a github issue.
Feb 18
prev sibling next sibling parent reply Francesco Mecca <me francescomecca.eu> writes:
On Friday, 15 February 2019 at 17:43:52 UTC, 12345swordy wrote:
 On Friday, 15 February 2019 at 17:38:23 UTC, Francesco Mecca 
 wrote:
 On Friday, 15 February 2019 at 13:49:04 UTC, Atila Neves wrote:
 [...]
I think that the solution proposed by Atila is better for the following reasons: 1. it is a library solution 2. allows both the user and the author of a library to specify functions with named parameters 3. it is very lightweight [...]
You miss the other reason on why it is not enough: Compile time and run-time performance penalty. -Alex
I have messed with kwargs and compile time doesn't seem to be an issue. At least it is not noticeable to me and I have a quite old dual core cpu. What kind of runtime penalty do you incur when using the library? To me it seems that the only penalty would be error messages. Also, kwargs allows unordered arguments and that is the path of lowest friction for people coming from languages with named parameters function (python on top of my mind). It makes sense if you want to improve readibility.
Feb 16
parent aliak <something something.com> writes:
On Saturday, 16 February 2019 at 10:02:02 UTC, Francesco Mecca 
wrote:
 On Friday, 15 February 2019 at 17:43:52 UTC, 12345swordy wrote:
 On Friday, 15 February 2019 at 17:38:23 UTC, Francesco Mecca 
 wrote:
 On Friday, 15 February 2019 at 13:49:04 UTC, Atila Neves 
 wrote:
 [...]
I think that the solution proposed by Atila is better for the following reasons: 1. it is a library solution 2. allows both the user and the author of a library to specify functions with named parameters 3. it is very lightweight [...]
You miss the other reason on why it is not enough: Compile time and run-time performance penalty. -Alex
I have messed with kwargs and compile time doesn't seem to be an issue. At least it is not noticeable to me and I have a quite old dual core cpu. What kind of runtime penalty do you incur when using the library? To me it seems that the only penalty would be error messages. Also, kwargs allows unordered arguments and that is the path of lowest friction for people coming from languages with named parameters function (python on top of my mind). It makes sense if you want to improve readibility.
kwargs is not scalable. You can't use the same types as parameters and you have to create a new type for each parameter. It's cumbersome and clunky and it relies on (unenforceable) convention to make the call site more readable. And it doesn't allow the API author to dictate how their function should be called. Named arguments is not a necessary feature of a language at all, it's only useful for maintenance and readability. There're no technical advantages to the api author, only psychological and aesthetic advantages to the api user, and the many code reviewers and maintainers who will follow them. Ok there is one technical advantage when it comes to overloads (See a post above). Maybe there're more ... 🤔🤷‍♂️ Cheers, - Ali
Feb 16
prev sibling parent reply Atila Neves <atila.neves gmail.com> writes:
On Friday, 15 February 2019 at 17:43:52 UTC, 12345swordy wrote:
 On Friday, 15 February 2019 at 17:38:23 UTC, Francesco Mecca 
 wrote:
 On Friday, 15 February 2019 at 13:49:04 UTC, Atila Neves wrote:
 [...]
I think that the solution proposed by Atila is better for the following reasons: 1. it is a library solution 2. allows both the user and the author of a library to specify functions with named parameters 3. it is very lightweight [...]
You miss the other reason on why it is not enough: Compile time and run-time performance penalty. -Alex
Run-time? I'd expect the call to inlined. It'll definitely take longer to compile though, but I'm at a loss why named parameters in the compiler are expected to be free.
Feb 18
parent reply Rubn <where is.this> writes:
On Monday, 18 February 2019 at 10:17:32 UTC, Atila Neves wrote:
 On Friday, 15 February 2019 at 17:43:52 UTC, 12345swordy wrote:
 On Friday, 15 February 2019 at 17:38:23 UTC, Francesco Mecca 
 wrote:
 On Friday, 15 February 2019 at 13:49:04 UTC, Atila Neves 
 wrote:
 [...]
I think that the solution proposed by Atila is better for the following reasons: 1. it is a library solution 2. allows both the user and the author of a library to specify functions with named parameters 3. it is very lightweight [...]
You miss the other reason on why it is not enough: Compile time and run-time performance penalty. -Alex
Run-time? I'd expect the call to inlined. It'll definitely take longer to compile though, but I'm at a loss why named parameters in the compiler are expected to be free.
The compiler isn't some magic device, your implementation is not easily optimized out to have no runtime cost. Even LDC has trouble optimizing it, and forget about DMD. struct Foo { int[1024] value; } void foo(ref Foo faa ) { import core.stdc.stdio : printf; foreach(int i, ref v; faa.value) { printf("%d", v); } } alias slowFoo = kwargify!foo; void func() { import std.stdio; Foo f; foreach(int i, ref v; f.value) { writeln("%d", v); } slowFoo( f ); foreach(int i, ref v; f.value) { writeln("%d", v); } } void example.func(): push rbp push r15 push r14 push rbx sub rsp, 8200 lea rdi, [rsp + 4104] xor ebx, ebx xor esi, esi mov edx, 4096 call memset PLT lea r15, [rsp + 8] lea r14, [rip + .L.str.1] .LBB1_1: mov ebp, dword ptr [rsp + 4*rbx + 4104] mov rdi, r15 call property trusted std.stdio.File std.stdio.trustedStdout() PLT mov esi, 10 mov ecx, 2 mov rdi, r15 mov edx, ebp mov r8, r14 call safe void std.stdio.File.write!(immutable(char)[], int, char).write(immutable(char)[], int, char) PLT mov rdi, r15 call safe void std.stdio.File.__dtor() PLT add rbx, 1 cmp rbx, 1024 jb .LBB1_1 lea rdi, [rsp + 8] lea rsi, [rsp + 4104] mov edx, 4096 call memcpy PLT <-------------------- lea rbx, [rip + .L.str.1] xor ebp, ebp .LBB1_4: mov esi, dword ptr [rsp + 4*rbp + 8] xor eax, eax mov rdi, rbx call printf PLT <------------------- add rbp, 1 cmp rbp, 1024 jne .LBB1_4 xor ebx, ebx lea r15, [rsp + 8] lea r14, [rip + .L.str.1] https://godbolt.org/z/6Tu8V7 As you can it is unable to optimize the extra copy that your implementation does by having to build a tuple before passing it to the function. No one is arguing that named parameters that are built in will be free. But it will be way faster as the compiler knows exactly what you are doing, not the hacky workaround you have that is severally limited (no templates, distinguished by types not "names" only allows you to reorder parameters all but useless for default types like int/float). Your implementation is extremely slow, both increasing compile times and decreasing runtime performance. All for the purpose of simply making code more readable. That's not a worthwhile trade off for the performance hit in both aspects.
Feb 18
parent Atila Neves <atila.neves gmail.com> writes:
On Monday, 18 February 2019 at 13:18:15 UTC, Rubn wrote:
 On Monday, 18 February 2019 at 10:17:32 UTC, Atila Neves wrote:
 On Friday, 15 February 2019 at 17:43:52 UTC, 12345swordy wrote:
 On Friday, 15 February 2019 at 17:38:23 UTC, Francesco Mecca 
 wrote:
 On Friday, 15 February 2019 at 13:49:04 UTC, Atila Neves 
 wrote:
 [...]
I think that the solution proposed by Atila is better for the following reasons: 1. it is a library solution 2. allows both the user and the author of a library to specify functions with named parameters 3. it is very lightweight [...]
You miss the other reason on why it is not enough: Compile time and run-time performance penalty. -Alex
Run-time? I'd expect the call to inlined. It'll definitely take longer to compile though, but I'm at a loss why named parameters in the compiler are expected to be free.
The compiler isn't some magic device, your implementation is not easily optimized out to have no runtime cost. Even LDC has trouble optimizing it, and forget about DMD. struct Foo { int[1024] value; }
<snip> Good shout, thanks for bringing that up. I fixed this in version 0.0.2 (just pushed), and now both `callSlowFoo` and `callFastFoo` below yield the exact same assembly with ldc, and the function calls were inlined: ---------------------------------------------- import kwargs; struct Foo { int[1024] value; } void fastFoo(ref Foo faa) { import core.stdc.stdio: printf; foreach(int i, ref v; faa.value) { printf("%d ", v); } printf("\n"); } alias slowFoo = kwargify!fastFoo; void callSlowFoo() { Foo foo; initFoo(foo); slowFoo(foo); } void callFastFoo() { Foo foo; initFoo(foo); fastFoo(foo); } void initFoo(ref Foo foo) { foreach(int i, ref v; foo.value) { v = i; } } void main() { callSlowFoo; // callFastFoo; // it's the same! } ----------------------------------------------
Feb 19
prev sibling parent Atila Neves <atila.neves gmail.com> writes:
On Friday, 15 February 2019 at 17:38:23 UTC, Francesco Mecca 
wrote:
 On Friday, 15 February 2019 at 13:49:04 UTC, Atila Neves wrote:
 On Friday, 15 February 2019 at 12:56:45 UTC, Mike Parker wrote:
 [...]
I'd add my library too as a possible library solution: https://github.com/atilaneves/kwargs
I think that the solution proposed by Atila is better for the following reasons: 1. it is a library solution 2. allows both the user and the author of a library to specify functions with named parameters 3. it is very lightweight But it is not enough for the following reasons: 1. Works only on templates (I'd like someone to explain to me why)
That's not true - it works fine with regular functions.
 2. Is opinionated about using ad-hoc types to represent data 
 (the opposite of http://wiki.c2.com/?PrimitiveObsession)
Yes. I consider this to be a good thing, but then again, I would.
Feb 18
prev sibling next sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Friday, 15 February 2019 at 12:56:45 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1019, "Named Arguments Lite":
The fact that named arguments, as proposed, require both the caller *and* the callee to opt-in seems like it would make them almost useless in practice. Even if someone's willing to put in the effort of going through all of Phobos to figure out which functions should be annotated with named, that still leaves all of the packages on code.dlang.org to deal with. Realistically, a lot of existing code will never be updated to work with this feature, even if it could benefit from it. It's also a pretty unsightly wart for newcomers to D to first learn that D supports named arguments (hooray!), and then find out that no, they can't use them with <insert package here> (boo!), because the author of that package hasn't "said the magic word" to enable them. I understand that the intent is to avoid unintentional breakage, but this feature is already opt-in from the caller's side. If someone wants to write code that's robust against parameter name changes, they can do it by not using named arguments in the first place. And, as noted in the DIP itself, there are still opportunities for accidental breakage even with named, when the caller fails to re-compile their code after a parameter name change. Parameter lock-in is definitely a legitimate concern, but IMHO adding a neutered version of named arguments like this one to the language would be worse than not having named arguments at all.
Feb 15
parent reply Yuxuan Shui <yshuiv7 gmail.com> writes:
On Friday, 15 February 2019 at 14:23:06 UTC, Paul Backus wrote:
 On Friday, 15 February 2019 at 12:56:45 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1019, "Named Arguments Lite":
[snip] I understand that the intent is to avoid unintentional breakage, but this feature is already opt-in from the caller's side. If someone wants to write code that's robust against parameter name changes, they can do it by not using named arguments in the first place.
Named parameters have to be opt-in at both sides. For the caller side, they can choose to not call the function with names so they can be robust against name changes (as you said). For the callee side, opt into named parameter create extra responsibility for them (e.g. they need to create new prototypes if they want to change parameter names). So if they don't want this responsibility, they can choose to not opt-in
 And, as noted in the DIP itself, there are still opportunities 
 for accidental breakage even with  named, when the caller fails 
 to re-compile their code after a parameter name change.
I am not quite sure what you mean by this. A name change either changes the semantic of the parameters, in which case the caller won't realize their is a breakage until they recompile. But this kind of breakage is always intentional from the callee side. A pure parameter name change won't break anything even if caller doesn't recompile.
 Parameter lock-in is definitely a legitimate concern, but IMHO 
 adding a neutered version of named arguments like this one to 
 the language would be worse than not having named arguments at 
 all.
If someone doesn't like this, they can come up with a DIP to deprecate the named attribute in the future.
Feb 16
next sibling parent reply 12345swordy <alexanderheistermann gmail.com> writes:
On Saturday, 16 February 2019 at 14:04:44 UTC, Yuxuan Shui wrote:

 If someone doesn't like this, they can come up with a DIP to 
 deprecate the  named attribute in the future.
If many people don't like this, then what? That should be sufficient grounds of rejection of the DIP itself. I *WILL* oppose this dip in it's entirely unless you remove the named attribute requirement from it. -Alex
Feb 16
parent reply Olivier FAURE <couteaubleu gmail.com> writes:
On Saturday, 16 February 2019 at 16:09:59 UTC, 12345swordy wrote:
 I *WILL* oppose this dip in it's entirely unless you remove the 
  named attribute requirement from it.
Please calm down. We're just discussing merits, there's no need for ultimatums.
Feb 16
next sibling parent 12345swordy <alexanderheistermann gmail.com> writes:
On Sunday, 17 February 2019 at 00:41:24 UTC, Olivier FAURE wrote:
 On Saturday, 16 February 2019 at 16:09:59 UTC, 12345swordy 
 wrote:
 I *WILL* oppose this dip in it's entirely unless you remove 
 the  named attribute requirement from it.
Please calm down. We're just discussing merits, there's no need for ultimatums.
I am calm down, as the other poster said, we shouldn't accept this dip on the assumption that someone somewhere will write a DIP that will deprecated named. If that were the case, then this dip is bad to begin with. Expressing my strong objections to this is no way me being not calm, and I would appreciated that you didn't misinterpret my post. -Alex
Feb 16
prev sibling parent Rubn <where is.this> writes:
On Sunday, 17 February 2019 at 00:41:24 UTC, Olivier FAURE wrote:
 On Saturday, 16 February 2019 at 16:09:59 UTC, 12345swordy 
 wrote:
 I *WILL* oppose this dip in it's entirely unless you remove 
 the  named attribute requirement from it.
Please calm down. We're just discussing merits, there's no need for ultimatums.
Telling someone that is angry or distressed to calm down is just about the worse thing you could say to them. Just saying, if were you were trying to calm someone down, you would have just been agitating them further.
Feb 17
prev sibling parent Paul Backus <snarwin gmail.com> writes:
On Saturday, 16 February 2019 at 14:04:44 UTC, Yuxuan Shui wrote:
 On Friday, 15 February 2019 at 14:23:06 UTC, Paul Backus wrote:
 Parameter lock-in is definitely a legitimate concern, but IMHO 
 adding a neutered version of named arguments like this one to 
 the language would be worse than not having named arguments at 
 all.
If someone doesn't like this, they can come up with a DIP to deprecate the named attribute in the future.
I don't think a DIP that makes the language worse should be accepted simply because someone, someday, may write a new DIP that makes it better again. And I would be very surprised if Walter and Andrei felt differently.
Feb 16
prev sibling next sibling parent 12345swordy <alexanderheistermann gmail.com> writes:
On Friday, 15 February 2019 at 12:56:45 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1019, "Named Arguments Lite":

 https://github.com/dlang/DIPs/blob/23ef47a94e0fdd5ddc4b2f6b2f4dcfd3c1f43aa6/DIPs/DIP1019.md

 All review-related feedback on and discussion of the DIP should 
 occur in this thread. The review period will end at 11:59 PM ET 
 on March 1, or when I make a post declaring it complete.

 At the end of Round 1, if further review is deemed necessary, 
 the DIP will be scheduled for another round of Community 
 Review. Otherwise, it will be queued for the Final Review and 
 Formal Assessment by the language maintainers.

 Please familiarize yourself with the documentation for the 
 Community Review before participating.

 https://github.com/dlang/DIPs/blob/master/PROCEDURE.md#community-review

 Thanks in advance to all who participate.
I think named parameters should be opt-out rather then opt-in. It seems like a hassle for the developer to update your functions to support named arguments if it were to be opt-in. Making it opt-in for avoiding any code deprecation is simply not worth it. The benefit of readability by the callee greatly outweighs the cost of the code deprecation. -Alex We have to take account of libraries that are rarely updated.
Feb 15
prev sibling next sibling parent reply Guillaume Piolat <contact spam.org> writes:
On Friday, 15 February 2019 at 12:56:45 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1019, "Named Arguments Lite":
- new function attribute is almost an automatic "no, thanks" from me - misordering arguments, I don't like it either
Feb 15
parent reply Ron Tarrant <rontarrant gmail.com> writes:
On Friday, 15 February 2019 at 15:10:28 UTC, Guillaume Piolat 
wrote:

 - misordering arguments, I don't like it either
Yeah, that bothers me, too. OP: And how would a feature like this work with variable-length argument lists? As for the whole named arguments thing, I like the concept, but I'm still mulling over whether I connect with it in practice.
Jun 07
parent Mike Parker <aldacron gmail.com> writes:
I'd just like to point out to everyone that this thread is for 
the first round of DIP 1019's community review. Andrei appears to 
have reviewed the correct version of the DIP, he simply misplaced 
his feedback. The second round is going on here:

https://forum.dlang.org/thread/sbkftyukevoydivapumm forum.dlang.org

Best if we keep all the discussion in one place.
Jun 07
prev sibling next sibling parent reply aliak <something something.com> writes:
On Friday, 15 February 2019 at 12:56:45 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1019, "Named Arguments Lite":
Wee! Named arguments :D There's also another solution that was brought up by Simen. Forum post: https://forum.dlang.org/post/ejnsqqebrjbwefjhagvg forum.dlang.org An implementation: https://github.com/aliak00/ddash/commit/911e3b580e7bbe06f43c258a2d1c78f97a9668c5#diff-6919882fdb1af168f0e5b90603414fae Basically we have the following decision dimensions when allowing named parameters in APIs Also I'm on the side of named parameters being the default and the API author deciding if their use is opt-out. But, that's a compile time breaking change to, basically, everything. So I guess that's out the window. So, there's probably a better chance with named parameters being opt-in. 1) I don't think it should be re-orderable because it allows callers to abuse APIs and not be used how the author (may have) intended: void call(int me, int maybe) {} call(maybe: 3, me: 2); call(me: 2, maybe: 3); Carly Ray would roll in her grave :p Also, who's calling who?!? Also, it makes named overload resolution impossible should the need arise: void call(int a, int b) {} void call(int b, int a) {} call(a: 3, b: 4); // ?? 2) Then there's the issue of external names and internal names, as an API designer, I want to be able to specify an external name but also have a different internal identifier move(T)(T from, T to); Requires the awkward use of variables from and to in the function body. It's not the end of the world of course, but allowing external and internal variable naming gives allows for the best user experience, and code readability from both caller and API author: move(T)(T from source, T to dest) { // implementation use source and dest } // caller uses from and to: move(from: x, to: y); 3) Disallowing named arguments. In my experience this is especially useful for the first argument to a function. move(x, to: y); How does a ":" sound as an addition to the parameter list to be able to achieve all of these? By default, everything stays the same, i.e. no named parameters. If you add a ":" to your parameter then it *must* be called via named arguments by the caller. And if you have a second identifier after your first, then that one becomes the internal identifier (this can also be a separate DIP maybe in the future as it's additional) move(T)(T :from, T :to); move(a, b); // error move(from: a, to: b); // ok move(T)(T from, T :to); move(a, b); // error move(from: a, to: b); // error move(a, to: b); // ok Then there's the issue of default arguments: * A default argument on an unnamed parameter can only come at the end. * A default argument on a named parameter can go anywhere void func(int a = 3, int :b) func(b: 7); // ok void func(int a = 3, int b); // error void func(int :a = 7, int b, int :c = 4); func(3); // ok void func(int :a = 7, int b, int :c); func(3, c: 8); I think parameter lock in is as valid as a concern as function name lock in. Also, I agree with everything Paul Backus has said in his response :) I'm just not so sure how feasible it'd be to allow an API author to force named arguments on their APIs and at the same time allow callers to use current libraries by using named arguments? I didn't think about it too much. But maybe they work together seamlessly? Cheers, - Ali
Feb 15
parent reply Yuxuan Shui <yshuiv7 gmail.com> writes:
On Friday, 15 February 2019 at 17:03:40 UTC, aliak wrote:
 On Friday, 15 February 2019 at 12:56:45 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1019, "Named Arguments Lite":
Wee! Named arguments :D There's also another solution that was brought up by Simen. Forum post: https://forum.dlang.org/post/ejnsqqebrjbwefjhagvg forum.dlang.org An implementation: https://github.com/aliak00/ddash/commit/911e3b580e7bbe06f43c258a2d1c78f97a9668c5#diff-6919882fdb1af168f0e5b90603414fae Basically we have the following decision dimensions when allowing named parameters in APIs Also I'm on the side of named parameters being the default and the API author deciding if their use is opt-out. But, that's a compile time breaking change to, basically, everything. So I guess that's out the window. So, there's probably a better chance with named parameters being opt-in.
Yes, one of my "design goal" is to maximize my chance :)
 1) I don't think it should be re-orderable because it allows 
 callers to abuse APIs and not be used how the author (may have) 
 intended:

 void call(int me, int maybe) {}

 call(maybe: 3, me: 2);
 call(me: 2, maybe: 3);

 Carly Ray would roll in her grave :p Also, who's calling who?!?
I was reluctant about add reordering too. The first version of the proposal doesn't have reordering. But after some thought, I realized reordering cannot be add as an extension of this proposal without breakage. So in order to not rule reordering out, I have to include that in the proposal. But now I reconsider it again, it is probably not as bad as I thought. The future reordering proposal can probably *also* be opt-in behind a attribute. So I am not really decided at this moment.
 Also, it makes named overload resolution impossible should the 
 need arise:

 void call(int a, int b) {}
 void call(int b, int a) {}

 call(a: 3, b: 4); // ??
This is a compile time error since the call matches both functions.
 2) Then there's the issue of external names and internal names, 
 as an API designer, I want to be able to specify an external 
 name but also have a different internal identifier

 move(T)(T from, T to);

 Requires the awkward use of variables from and to in the 
 function body. It's not the end of the world of course, but 
 allowing external and internal variable naming gives allows for 
 the best user experience, and code readability from both caller 
 and API author:

 move(T)(T from source, T to dest) {
   // implementation use source and dest
 }

 // caller uses from and to:
 move(from: x, to: y);
This can be done with this proposal, you do move(T)(T source, T dest) { /* code */ } named move(T)(T from, T to);
 3) Disallowing named arguments. In my experience this is 
 especially useful for the first argument to a function.

 move(x, to: y);

 How does a ":" sound as an addition to the parameter list to be 
 able to achieve all of these? By default, everything stays the 
 same, i.e. no named parameters. If you add a ":" to your 
 parameter then it *must* be called via named arguments by the 
 caller. And if you have a second identifier after your first, 
 then that one becomes the internal identifier (this can also be 
 a separate DIP maybe in the future as it's additional)

 move(T)(T :from, T :to);
 move(a, b); // error
 move(from: a, to: b); // ok

 move(T)(T from, T :to);
 move(a, b); // error
 move(from: a, to: b); // error
 move(a, to: b); // ok

 Then there's the issue of default arguments:
 * A default argument on an unnamed parameter can only come at 
 the end.
 * A default argument on a named parameter can go anywhere

 void func(int a = 3, int :b)
 func(b: 7); // ok

 void func(int a = 3, int b); // error

 void func(int :a = 7, int b, int :c = 4);

 func(3); // ok

 void func(int :a = 7, int b, int :c);

 func(3, c: 8);

 I think parameter lock in is as valid as a concern as function 
 name lock in.
This proposal doesn't prevent your suggestion from being implemented in the future :)
 [snip]
Feb 15
next sibling parent reply 12345swordy <alexanderheistermann gmail.com> writes:
On Friday, 15 February 2019 at 18:26:34 UTC, Yuxuan Shui wrote:
 Yes, one of my "design goal" is to maximize my chance :)
Increasing the chance of this DIP being accepted by avoiding code deprecation shouldn't be any DIP design goal. We shouldn't reject good design just because it may break people code. That is THE ISSUE THAT I HAVE WITH THE C++ COMMITTEE! If I were so worried about breaking code when introducing new features I would use c++! Which guess what? The readability is horrible! So god awful! They are STILL stuck with using header files in spite of introducing modules! I can go on and on about this, but it be pointless, because they have such a religious devotion to backwards compatibility that I just gave up on them. D should not make the fatal mistake of "persevering backwards capability at all cost" scenario, that what c++ is for. Argue that the benefit of readability overweight the cost of breaking peoples code, which can be easily fix with the rename feature that comes with IDE and tools. Stand your ground. Please! I do not want to go around and beg package makers to label their functions named for readability sake! -Alex
Feb 15
next sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Friday, 15 February 2019 at 19:11:55 UTC, 12345swordy wrote:
 On Friday, 15 February 2019 at 18:26:34 UTC, Yuxuan Shui wrote:
 Yes, one of my "design goal" is to maximize my chance :)
Increasing the chance of this DIP being accepted by avoiding code deprecation shouldn't be any DIP design goal. We shouldn't reject good design just because it may break people code. [...] D should not make the fatal mistake of "persevering backwards capability at all cost" scenario, that what c++ is for.
It's actually worse than that--the purpose of named is not to avoid breaking *existing* code. Existing code that doesn't use named arguments will continue to work regardless. The purpose of named is to ensure that (a) changes to existing code which have yet to be made (b) do not break future code that has yet to be written.
Feb 15
parent 12345swordy <alexanderheistermann gmail.com> writes:
On Friday, 15 February 2019 at 20:11:47 UTC, Paul Backus wrote:
 On Friday, 15 February 2019 at 19:11:55 UTC, 12345swordy wrote:
 On Friday, 15 February 2019 at 18:26:34 UTC, Yuxuan Shui wrote:
 Yes, one of my "design goal" is to maximize my chance :)
Increasing the chance of this DIP being accepted by avoiding code deprecation shouldn't be any DIP design goal. We shouldn't reject good design just because it may break people code. [...] D should not make the fatal mistake of "persevering backwards capability at all cost" scenario, that what c++ is for.
It's actually worse than that--the purpose of named is not to avoid breaking *existing* code. Existing code that doesn't use named arguments will continue to work regardless. The purpose of named is to ensure that (a) changes to existing code which have yet to be made (b) do not break future code that has yet to be written.
Which it is a non-issue in other languages such as C# as the simple find and replace tool in your favorite editor can simply fix the code breakage due to parameter name change. This should really be opt-out rather then opt-in, as parameter name changes are rare and easy to fix. I don't think library authors should be nagged by user to put the named attribute to their functions just so they can use Named Arguments! If the calle is so worried about their code break, because of the name change of the parameter, then they shouldn't be using name arguments at all! I don't want Named Arguments to be dead on arrival, as your favorite library hasn't updated their functions to use the named arguments feature. -Alex
Feb 15
prev sibling next sibling parent reply Yuxuan Shui <yshuiv7 gmail.com> writes:
On Friday, 15 February 2019 at 19:11:55 UTC, 12345swordy wrote:
 On Friday, 15 February 2019 at 18:26:34 UTC, Yuxuan Shui wrote:
 Yes, one of my "design goal" is to maximize my chance :)
Increasing the chance of this DIP being accepted by avoiding code deprecation shouldn't be any DIP design goal. We shouldn't reject good design just because it may break people code. That is THE ISSUE THAT I HAVE WITH THE C++ COMMITTEE! If I were so worried about breaking code when introducing new features I would use c++! Which guess what? The readability is horrible! So god awful! They are STILL stuck with using header files in spite of introducing modules! I can go on and on about this, but it be pointless, because they have such a religious devotion to backwards compatibility that I just gave up on them. D should not make the fatal mistake of "persevering backwards capability at all cost" scenario, that what c++ is for. Argue that the benefit of readability overweight the cost of breaking peoples code, which can be easily fix with the rename feature that comes with IDE and tools. Stand your ground. Please! I do not want to go around and beg package makers to label their functions named for readability sake! -Alex
I am not saying "we should never break any code". I am deferring that decision to someone else. If someone want to make named parameters opt-out instead of opt-in, they can do so on top of this DIP. I am just not doing that in my proposal.
Feb 15
next sibling parent reply 12345swordy <alexanderheistermann gmail.com> writes:
On Friday, 15 February 2019 at 20:35:14 UTC, Yuxuan Shui wrote:
 On Friday, 15 February 2019 at 19:11:55 UTC, 12345swordy wrote:
 [...]
I am not saying "we should never break any code". I am deferring that decision to someone else. If someone want to make named parameters opt-out instead of opt-in, they can do so on top of this DIP. I am just not doing that in my proposal.
Why? We need to get it right the first time, as a.)This is a slow process b.)Would require another 180+ days if A&W reject this.
Feb 15
parent reply Yuxuan Shui <yshuiv7 gmail.com> writes:
On Friday, 15 February 2019 at 20:51:35 UTC, 12345swordy wrote:
 On Friday, 15 February 2019 at 20:35:14 UTC, Yuxuan Shui wrote:
 On Friday, 15 February 2019 at 19:11:55 UTC, 12345swordy wrote:
 [...]
I am not saying "we should never break any code". I am deferring that decision to someone else. If someone want to make named parameters opt-out instead of opt-in, they can do so on top of this DIP. I am just not doing that in my proposal.
Why?
You answered the why yourself:
 a.)This is a slow process
 b.)Would require another 180+ days if A&W reject this.
So I don't want this proposal to be rejected.
Feb 15
parent 12345swordy <alexanderheistermann gmail.com> writes:
On Friday, 15 February 2019 at 21:19:14 UTC, Yuxuan Shui wrote:
 On Friday, 15 February 2019 at 20:51:35 UTC, 12345swordy wrote:
 On Friday, 15 February 2019 at 20:35:14 UTC, Yuxuan Shui wrote:
 On Friday, 15 February 2019 at 19:11:55 UTC, 12345swordy 
 wrote:
 [...]
I am not saying "we should never break any code". I am deferring that decision to someone else. If someone want to make named parameters opt-out instead of opt-in, they can do so on top of this DIP. I am just not doing that in my proposal.
Why?
You answered the why yourself:
 a.)This is a slow process
 b.)Would require another 180+ days if A&W reject this.
So I don't want this proposal to be rejected.
There are severe usability disadvantages that outweigh readability advantages if this were to be opt-in. The decision to used named arguments should rest on the calle not the caller. When the calle used named arguments they are opt-in the risk of their code breakage in which forcing the caller to mark their function named does NOT solve this. Here is my statement: The caller is NOT AND SHOULD NOT BE responsible for code breakage when they renamed parameters as the Named Arguments are opt-in from the client side of the code. Forcing the Caller to be responsible for Named Arguments, is a HUGE usability disadvantage as it requires many existing libraries out there to mark their functions named if the client wants to use named arguments, when they have already have other attributes to worry about. It even worst for library creators to mark named in their modules EVERY SINGLE TIME if they to grant the client access to named arguments. Function not having Named Arguments support should be RARE NOT COMMON! This poor design should be the basis of this being rejected.
Feb 15
prev sibling parent reply Olivier FAURE <couteaubleu gmail.com> writes:
On Friday, 15 February 2019 at 20:35:14 UTC, Yuxuan Shui wrote:
 I am not saying "we should never break any code". I am 
 deferring that decision to someone else. If someone want to 
 make named parameters opt-out instead of opt-in, they can do so 
 on top of this DIP. I am just not doing that in my proposal.
I think that, at least, you should include more details in the DIP text about what kind of breakage the named attribute would prevent, how these breakages would otherwise occur, and what kind of situation would lead to them. I personally think breakages are unlikely: - The maintainer needs to export functions with argument names. - The user has to explicitly use DIP-1019 and use named arguments. - The maintainer has to change the argument names, without being aware of DIP-1019 and using your forward declaration workaround (and without being made aware of it by subsequent issues). - Then the user gets an easy-to-fix compile error when they update their library. In these cases, the user can always avoid using named arguments if there's a significant risk that named breakage occurs (eg if the library was written before DIP-1019). Keep in mind that library maintainers can always opt out of named arguments by exporting prototypes with anonymous arguments: int foobar(int, float, string); All-in-all, it's a trade-off with downsides either way, but I think being able to use named argument with any library made at any time far outweighs the breakage risks.
Feb 16
parent Olivier FAURE <couteaubleu gmail.com> writes:
On Sunday, 17 February 2019 at 00:38:33 UTC, Olivier FAURE wrote:
 On Friday, 15 February 2019 at 20:35:14 UTC, Yuxuan Shui wrote:
 I am not saying "we should never break any code". I am 
 deferring that decision to someone else. If someone want to 
 make named parameters opt-out instead of opt-in, they can do 
 so on top of this DIP. I am just not doing that in my proposal.
I forgot to say, thank you for your work on this DIP, and for your upbeat attitude in discussing possible improvements :)
Feb 16
prev sibling parent reply Ron J <ron gmail.com> writes:
On Friday, 15 February 2019 at 19:11:55 UTC, 12345swordy wrote:
 ...
 D should not make the fatal mistake of "persevering backwards 
 capability at all cost" scenario, that what c++ is for.
 ...
I agree with this and despite breaking code indeed sucks, for a language like D which has a very small user base, I think it should go for it instead of adding new properties for handling different cases and trying to be like C++. In fact look for example C++ 17 or 20 and you can clearly see that they are trying hard to force people over new features/ways of programming and hoping the old "habits" go way. Ron.
Feb 15
parent 12345swordy <alexanderheistermann gmail.com> writes:
On Friday, 15 February 2019 at 22:17:28 UTC, Ron J wrote:
 On Friday, 15 February 2019 at 19:11:55 UTC, 12345swordy wrote:
 ...
 D should not make the fatal mistake of "persevering backwards 
 capability at all cost" scenario, that what c++ is for.
 ...
I agree with this and despite breaking code indeed sucks, for a language like D which has a very small user base, I think it should go for it instead of adding new properties for handling different cases and trying to be like C++. In fact look for example C++ 17 or 20 and you can clearly see that they are trying hard to force people over new features/ways of programming and hoping the old "habits" go way. Ron.
The "Old Way" aka C++98 will still be used simply because they still support it. If they are serious about preventing people from coding the "Old Way" then they simply need to stop supporting the "Old Way". Until then the dinosaurs will still type C++98 code. -Alex
Feb 15
prev sibling parent aliak <something something.com> writes:
On Friday, 15 February 2019 at 18:26:34 UTC, Yuxuan Shui wrote:
 On Friday, 15 February 2019 at 17:03:40 UTC, aliak wrote:
 On Friday, 15 February 2019 at 12:56:45 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1019, "Named Arguments Lite":
Wee! Named arguments :D There's also another solution that was brought up by Simen. Forum post: https://forum.dlang.org/post/ejnsqqebrjbwefjhagvg forum.dlang.org An implementation: https://github.com/aliak00/ddash/commit/911e3b580e7bbe06f43c258a2d1c78f97a9668c5#diff-6919882fdb1af168f0e5b90603414fae Basically we have the following decision dimensions when allowing named parameters in APIs Also I'm on the side of named parameters being the default and the API author deciding if their use is opt-out. But, that's a compile time breaking change to, basically, everything. So I guess that's out the window. So, there's probably a better chance with named parameters being opt-in.
Yes, one of my "design goal" is to maximize my chance :)
Yeah, I understand that. Though, just for the record if it came down to a vote, I'd 100% vote for a deprecation path towards named-parameters-by-default.
 1) I don't think it should be re-orderable because it allows 
 callers to abuse APIs and not be used how the author (may 
 have) intended:

 void call(int me, int maybe) {}

 call(maybe: 3, me: 2);
 call(me: 2, maybe: 3);

 Carly Ray would roll in her grave :p Also, who's calling who?!?
I was reluctant about add reordering too. The first version of the proposal doesn't have reordering. But after some thought, I realized reordering cannot be add as an extension of this proposal without breakage. So in order to not rule reordering out, I have to include that in the proposal. But now I reconsider it again, it is probably not as bad as I thought. The future reordering proposal can probably *also* be opt-in behind a attribute. So I am not really decided at this moment.
Yeah, it may also make it simpler? As in, without reordering the resolution order of parameters don't have to be changed. But with, then you need to account for that too maybe. Also one more advantage, the call-site is consistent at every usage. Allowing reordering encourages sloppiness on the caller, with no particular (at least that I can see) benefit.
 Also, it makes named overload resolution impossible should the 
 need arise:

 void call(int a, int b) {}
 void call(int b, int a) {}

 call(a: 3, b: 4); // ??
This is a compile time error since the call matches both functions.
But this can be resolved if there was no reordering and "call" was a function that "required" named arguments. Or did I miss something?
 2) Then there's the issue of external names and internal 
 names, as an API designer, I want to be able to specify an 
 external name but also have a different internal identifier

 move(T)(T from, T to);

 Requires the awkward use of variables from and to in the 
 function body. It's not the end of the world of course, but 
 allowing external and internal variable naming gives allows 
 for the best user experience, and code readability from both 
 caller and API author:

 move(T)(T from source, T to dest) {
   // implementation use source and dest
 }

 // caller uses from and to:
 move(from: x, to: y);
This can be done with this proposal, you do move(T)(T source, T dest) { /* code */ } named move(T)(T from, T to);
Ah, ok, I did not catch that was possible. Cool, that could work as well. Requires more typing and maintenance of function signatures perhaps, which may be harder to deal with then just allowing that kind of functionality in one function signature.
 This proposal doesn't prevent your suggestion from being 
 implemented in the future :)
True, but if we force named parameters across the whole function now with something like named, then what will add a second way to have named parameters whereas it can potentially just be tackled in one go now. So maybe better to just allow that now? Also ":" is symmetrical with the way you call a named argument as well. Thought it would just be a bit nicer than taking up a new attribute, which is also quite generically "named".
 [snip]
One thing that could be mentioned in the DIP is the ability to allow for function overloads that were previously impossible: Consider: // Function to load a value from a program option auto createProgramOption(T)(string name, string envVar = null, T defaultValue = T.init); I want to force "name" but optionally have a defaultValue and an envVar. What happens if T is a string? How do you make the call-site nice? createProgramOption!int("port", "PORT", 8080); // ok createProgramOption!string("host", "HOST", "localhost"); // ok // Now I want to allow these two: createProgramOption!string("host","localhost"); // defaultValue version createProgramOption!string("host","HOST"); // envVar version What do I do? How do I achieve this without named arguments? With named arguments: auto createProgramOption(T)(string name, string envVar = null, T defaultValue = T.init); createProgramOption!string(name: "host", defaultValue: "localhost"); createProgramOption!string(name: "host", envVar: "HOST"); // Just works, intuitive, obvious, readable
Feb 16
prev sibling next sibling parent reply Jacob Shtokolov <jacob.100205 gmail.com> writes:
On Friday, 15 February 2019 at 12:56:45 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1019, "Named Arguments Lite":
I think the "Completeness" section contains some arguable points. The proposed solution doesn't take into account the cases where you need to partially skip default arguments. Say, we have a function: ```void drawCircle(int x, int y, int radius, Border border = Border.Solid, Bg bg = Bg.Transparent)``` Then we want to call this function with default parameters except the background (bg). The best way to do that would be: ```drawCircle(10, 10, 5, bg: Bg.Red);``` So you see that we omitted the "border" parameter. However, the proposed solution forces us to do that: ```drawCircle(x: 10, y: 10, radius: 5, bg: Bg.Red);``` A lot more unnecessary typing. Python, for example, allows us to mix both named and unnamed arguments, and thus effectively skip the default ones.
Feb 15
parent Yuxuan Shui <yshuiv7 gmail.com> writes:
On Friday, 15 February 2019 at 17:06:18 UTC, Jacob Shtokolov 
wrote:
 On Friday, 15 February 2019 at 12:56:45 UTC, Mike Parker wrote:
 [...]
I think the "Completeness" section contains some arguable points. The proposed solution doesn't take into account the cases where you need to partially skip default arguments. Say, we have a function: ```void drawCircle(int x, int y, int radius, Border border = Border.Solid, Bg bg = Bg.Transparent)``` Then we want to call this function with default parameters except the background (bg). The best way to do that would be: ```drawCircle(10, 10, 5, bg: Bg.Red);``` So you see that we omitted the "border" parameter. However, the proposed solution forces us to do that: ```drawCircle(x: 10, y: 10, radius: 5, bg: Bg.Red);``` A lot more unnecessary typing. Python, for example, allows us to mix both named and unnamed arguments, and thus effectively skip the default ones.
This proposal is written purposefully to minimized its scope. Yes, the current proposal doesn't address this use case, but it doesn't prevent future DIPs from doing so.
Feb 15
prev sibling next sibling parent reply Johannes Loher <johannesloher fg4f.de> writes:
Am 15.02.19 um 13:56 schrieb Mike Parker:
 [...]
All in all, DIP 1019 looks quite interesting and also primising to me. I do however see some issues with the DIP: 1. The rationale describes 2 problems that can arise when not having named arguments, but it does not describe how those problems could be prevented by using named arguments. 2. In the "Description" secion, the DIP says:
 When the label and the corresponding parameter name mismatch, the
compiler will generate an error of the following nature: "Named argument 'foo' does not match function parameter name 'bar'." I don't really understand how the compiler should generate this exact error message. How can the compiler know that the argument passed with name 'foo' is supposed to match the actual parameter 'bar'? I don't think this is possible if reordering of named arguments is allowed (as the DIP later suggests). To clearify this, the DIP should provide code examples where those mismatches occur and what errors are detected (or not bother with specifying what the exact error message is, but simply state that this is a compile error, but also provide examples). 3. In the completeness section, I would have liked an example to make this more easily understandable. 4. In the "Alternatives" section, the DIP says:
 For example, in one potential library-only solution, it is necessary
to call functions like so:
 args!(add, a=>1, b=>1);

 This has too much noise and, moreover, does not allow for the use of
Uniform Function Call Syntax (UFCS). This clearly suggests that named arguments as proposed by the DIP should work with UFCS. However, the DIP fails to explain how this should actually work. At the moment, UFCS works by lowering as described in the following example: ```d int add(int a, int b, int c) { /* ... */ } void main() { 1.add(2, 3); // lowered to add(1, 2, 3); } ``` It is totally unclear how this should work with named arguments. 5. Similarly, as already mentioned by somebody else, the DIP fails to explain interaction with function default arguments. 6. Another possible interaction the DIP does not mention at all is implicit istanciation of template functions. Without giving it too much tought, to me it looks like this should actually work. But the DIP does not consider this at all. It should at least describe whether those features are compatible or not, and provide examples if they are.
Feb 15
parent reply Yuxuan Shui <yshuiv7 gmail.com> writes:
On Friday, 15 February 2019 at 18:04:36 UTC, Johannes Loher wrote:
 Am 15.02.19 um 13:56 schrieb Mike Parker:
 [...]
All in all, DIP 1019 looks quite interesting and also primising to me. I do however see some issues with the DIP: 1. The rationale describes 2 problems that can arise when not having named arguments, but it does not describe how those problems could be prevented by using named arguments. 2. In the "Description" secion, the DIP says:
 When the label and the corresponding parameter name mismatch, 
 the
compiler will generate an error of the following nature: "Named argument 'foo' does not match function parameter name 'bar'." I don't really understand how the compiler should generate this exact error message. How can the compiler know that the argument passed with name 'foo' is supposed to match the actual parameter 'bar'? I don't think this is possible if reordering of named arguments is allowed (as the DIP later suggests). To clearify this, the DIP should provide code examples where those mismatches occur and what errors are detected (or not bother with specifying what the exact error message is, but simply state that this is a compile error, but also provide examples). 3. In the completeness section, I would have liked an example to make this more easily understandable. 4. In the "Alternatives" section, the DIP says:
 For example, in one potential library-only solution, it is 
 necessary
to call functions like so:
 args!(add, a=>1, b=>1);

 This has too much noise and, moreover, does not allow for the 
 use of
Uniform Function Call Syntax (UFCS). This clearly suggests that named arguments as proposed by the DIP should work with UFCS. However, the DIP fails to explain how this should actually work. At the moment, UFCS works by lowering as described in the following example: ```d int add(int a, int b, int c) { /* ... */ } void main() { 1.add(2, 3); // lowered to add(1, 2, 3); } ``` It is totally unclear how this should work with named arguments.
Thanks for pointing these out, they will be fixed in the next revision.
 5. Similarly, as already mentioned by somebody else, the DIP 
 fails to explain interaction with function default arguments.
I think it is reasonable to require a prefix of the parameters are specified. e.g. int fun(int a, int b = 1, int c = 2, int d = 3); The user can specify (a), (a, b), (a, b, c) or all of the parameters, and the arguments can be in any order.
 6. Another possible interaction the DIP does not mention at all 
 is implicit instantiation of template functions. Without giving 
 it too much thought, to me it looks like this should actually 
 work. But the DIP does not consider this at all. It should at 
 least describe whether those features are compatible or not, 
 and provide examples if they are.
I think it should just work. But I would give it some thought and include that in the next revision. Thanks!
Feb 15
parent reply Paul Backus <snarwin gmail.com> writes:
On Friday, 15 February 2019 at 18:32:52 UTC, Yuxuan Shui wrote:
 5. Similarly, as already mentioned by somebody else, the DIP 
 fails to explain interaction with function default arguments.
I think it is reasonable to require a prefix of the parameters are specified. e.g. int fun(int a, int b = 1, int c = 2, int d = 3); The user can specify (a), (a, b), (a, b, c) or all of the parameters, and the arguments can be in any order.
In my experience, one of the greatest benefits of argument re-ordering is that it lets you leave out optional arguments at the call site. For example, in Python, if you wanted to use the default value for every argument except `d`, you could write this: fun(a=123, d=456) ...whereas with this proposal, you'd be required to needlessly repeat the default values for `a` and `b`: fun(a: 123, d: 456, b: 1, c: 2); If this DIP isn't going to allow leaving out optional arguments in all cases, it might be better to simply forbid argument re-ordering entirely (or at least, to leave the issue for a future DIP).
Feb 15
parent aliak <something something.com> writes:
On Friday, 15 February 2019 at 20:28:02 UTC, Paul Backus wrote:
 On Friday, 15 February 2019 at 18:32:52 UTC, Yuxuan Shui wrote:
 5. Similarly, as already mentioned by somebody else, the DIP 
 fails to explain interaction with function default arguments.
I think it is reasonable to require a prefix of the parameters are specified. e.g. int fun(int a, int b = 1, int c = 2, int d = 3); The user can specify (a), (a, b), (a, b, c) or all of the parameters, and the arguments can be in any order.
In my experience, one of the greatest benefits of argument re-ordering is that it lets you leave out optional arguments at the call site. For example, in Python, if you wanted to use the default value for every argument except `d`, you could write this: fun(a=123, d=456) ...whereas with this proposal, you'd be required to needlessly repeat the default values for `a` and `b`: fun(a: 123, d: 456, b: 1, c: 2); If this DIP isn't going to allow leaving out optional arguments in all cases, it might be better to simply forbid argument re-ordering entirely (or at least, to leave the issue for a future DIP).
Being able to leave out arguments would be hugely beneficial to the caller. You don't need reordering to achieve that though, the arguments can still be specified in the correct order while the ones with default values are left out: https://swift.godbolt.org/z/Vhtouf
Feb 16
prev sibling next sibling parent reply Golden Rockefeller <golden.rockefeller protonmail.com> writes:
On Friday, 15 February 2019 at 12:56:45 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1019, "Named Arguments Lite":

 https://github.com/dlang/DIPs/blob/23ef47a94e0fdd5ddc4b2f6b2f4dcfd3c1f43aa6/DIPs/DIP1019.md

 All review-related feedback on and discussion of the DIP should 
 occur in this thread. The review period will end at 11:59 PM ET 
 on March 1, or when I make a post declaring it complete.

 At the end of Round 1, if further review is deemed necessary, 
 the DIP will be scheduled for another round of Community 
 Review. Otherwise, it will be queued for the Final Review and 
 Formal Assessment by the language maintainers.

 Please familiarize yourself with the documentation for the 
 Community Review before participating.

 https://github.com/dlang/DIPs/blob/master/PROCEDURE.md#community-review

 Thanks in advance to all who participate.
As another alternative, named parameters can be implemented using Tuple/tuple from the Phobos Library. This alternative solution will prevent silent breakage. The caller can not opt-out. This solution adds even more noise to function calls but typedef can reduce the noise. This solution does not address reordering but can be combined with other solutions that allow for reordering. Here is an example: import std.typecons; double get_area(Tuple!(double, "radius") t_radius) { double radius = t_radius.radius; return 3.14 * radius * radius; } double get_area(Tuple!(double, "diameter") t_diameter) { double radius = t_diameter.diameter / 2; return 3.14 * radius * radius; } void main() { import std.stdio; auto area = get_area(tuple!"radius"(4.)); writeln("Area with radius: ", area); area = get_area(tuple!"diameter"(8.)); writeln("Area with diameter: ", area); }
Feb 15
next sibling parent 12345swordy <alexanderheistermann gmail.com> writes:
On Friday, 15 February 2019 at 21:05:38 UTC, Golden Rockefeller 
wrote:
 On Friday, 15 February 2019 at 12:56:45 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1019, "Named Arguments Lite":

 https://github.com/dlang/DIPs/blob/23ef47a94e0fdd5ddc4b2f6b2f4dcfd3c1f43aa6/DIPs/DIP1019.md

 All review-related feedback on and discussion of the DIP 
 should occur in this thread. The review period will end at 
 11:59 PM ET on March 1, or when I make a post declaring it 
 complete.

 At the end of Round 1, if further review is deemed necessary, 
 the DIP will be scheduled for another round of Community 
 Review. Otherwise, it will be queued for the Final Review and 
 Formal Assessment by the language maintainers.

 Please familiarize yourself with the documentation for the 
 Community Review before participating.

 https://github.com/dlang/DIPs/blob/master/PROCEDURE.md#community-review

 Thanks in advance to all who participate.
As another alternative, named parameters can be implemented using Tuple/tuple from the Phobos Library. This alternative solution will prevent silent breakage. The caller can not opt-out. This solution adds even more noise to function calls but typedef can reduce the noise. This solution does not address reordering but can be combined with other solutions that allow for reordering. Here is an example: import std.typecons; double get_area(Tuple!(double, "radius") t_radius) { double radius = t_radius.radius; return 3.14 * radius * radius; } double get_area(Tuple!(double, "diameter") t_diameter) { double radius = t_diameter.diameter / 2; return 3.14 * radius * radius; } void main() { import std.stdio; auto area = get_area(tuple!"radius"(4.)); writeln("Area with radius: ", area); area = get_area(tuple!"diameter"(8.)); writeln("Area with diameter: ", area); }
The downside to your solution is an increases in memory.
Feb 15
prev sibling parent Basile B. <b2.temp gmx.com> writes:
On Friday, 15 February 2019 at 21:05:38 UTC, Golden Rockefeller 
wrote:
 As another alternative, named parameters can be implemented 
 using Tuple/tuple from the Phobos Library.
Tuples exist as an internal compiler type. The thing is just that there's no syntax for it. So what you think is a library thing is actually mostly compiler one. Maybe the tuple DIP should be handled before the named parameter one maybe ?
Feb 16
prev sibling next sibling parent reply Rubn <where is.this> writes:
On Friday, 15 February 2019 at 12:56:45 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1019, "Named Arguments Lite":

 https://github.com/dlang/DIPs/blob/23ef47a94e0fdd5ddc4b2f6b2f4dcfd3c1f43aa6/DIPs/DIP1019.md

 All review-related feedback on and discussion of the DIP should 
 occur in this thread. The review period will end at 11:59 PM ET 
 on March 1, or when I make a post declaring it complete.

 At the end of Round 1, if further review is deemed necessary, 
 the DIP will be scheduled for another round of Community 
 Review. Otherwise, it will be queued for the Final Review and 
 Formal Assessment by the language maintainers.

 Please familiarize yourself with the documentation for the 
 Community Review before participating.

 https://github.com/dlang/DIPs/blob/master/PROCEDURE.md#community-review

 Thanks in advance to all who participate.
drawRect(x: 0, y: 0, width: 1, height: 1); drawRect(width: 1, height: 1, x: 0, y: 0); The DIP doesn't state what order these are executed in. The spec states parameters are executed left to right. When you can rearrange the function arguments at the call site, is it going to call left to right as it is orangized at the call site, or left to right as according to as the function definition? I don't think we should require an attribute for this either. We already have enough we don't need one more. It means we can't use it for instances where you want to change a default value but keep other options at their default much like how C# implements it: void foo( int bar, int someDefault = 0, int someOtherDefault = 1 ); foo( 10, someOtherDefault: 2 );
Feb 15
parent Yuxuan Shui <yshuiv7 gmail.com> writes:
On Friday, 15 February 2019 at 22:48:52 UTC, Rubn wrote:
 On Friday, 15 February 2019 at 12:56:45 UTC, Mike Parker wrote:
 [...]
drawRect(x: 0, y: 0, width: 1, height: 1); drawRect(width: 1, height: 1, x: 0, y: 0); The DIP doesn't state what order these are executed in. The spec states parameters are executed left to right. When you can rearrange the function arguments at the call site, is it going to call left to right as it is orangized at the call site, or left to right as according to as the function definition?
Good point. I will fix this in next revision. Thanks.
Feb 16
prev sibling next sibling parent reply Andre Pany <andre s-e-a-p.de> writes:
On Friday, 15 February 2019 at 12:56:45 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1019, "Named Arguments Lite":

 https://github.com/dlang/DIPs/blob/23ef47a94e0fdd5ddc4b2f6b2f4dcfd3c1f43aa6/DIPs/DIP1019.md

 All review-related feedback on and discussion of the DIP should 
 occur in this thread. The review period will end at 11:59 PM ET 
 on March 1, or when I make a post declaring it complete.

 At the end of Round 1, if further review is deemed necessary, 
 the DIP will be scheduled for another round of Community 
 Review. Otherwise, it will be queued for the Final Review and 
 Formal Assessment by the language maintainers.

 Please familiarize yourself with the documentation for the 
 Community Review before participating.

 https://github.com/dlang/DIPs/blob/master/PROCEDURE.md#community-review

 Thanks in advance to all who participate.
With the struct initialization DIP there will come also named arguments complicity. https://github.com/wilzbach/DIPs/blob/b1283b455b635d7dcbc2c871d2aa47cc67190059/DIPs/DIP1xxx-sw.md Yes, the callee has to provide method/function overload with a structure containing all arguments. But in theory Phobos could provide a mixin/template to make this task a one liner. In my opinion this fits much nicer than introducing a new attribute. Kind regards Andre
Feb 16
parent reply Cym13 <cpicard openmailbox.org> writes:
On Saturday, 16 February 2019 at 12:41:01 UTC, Andre Pany wrote:
 With the struct initialization DIP there will come also named 
 arguments complicity.

 https://github.com/wilzbach/DIPs/blob/b1283b455b635d7dcbc2c871d2aa47cc67190059/DIPs/DIP1xxx-sw.md

 Yes, the callee has to provide method/function  overload with a 
 structure containing all arguments. But in theory Phobos could 
 provide a mixin/template to make this task a one liner.

 In my opinion this fits much nicer than introducing a new 
 attribute.

 Kind regards
 Andre
I 100% support that. Relying on struct initialization is both the easiest and safest way to go in my opinion: 0) as a reminder the idea is that today you can do that: struct S { int a, int b=42 } void f(S args); S args = { .b=43 }; // yeah, useful C legacy! f(args); but there's currently no way to directly initialize that struct in the f() call. 1) it's already there. All problems have already been solved, the code is there with reordering, default values, order of evaluation etc. Struct initialization already works, just not in-place. 2) it's as backward compatible as it can be: as long as the calle provides a function that takes a struct as argument it'll work. It'll work with C code, it'll work with C++ code, it'll work without named, it'll just work. It's just structs, cleverly used. 3) the only thing needed is to finally close that in-place struct initialization DIP. I'd much rather have that than introducing new attributes and duplicating code (since, as I said, such code is already existing for partial structs initialization).
Feb 17
next sibling parent Cym13 <cpicard openmailbox.org> writes:
On Sunday, 17 February 2019 at 13:44:09 UTC, Cym13 wrote:
     S args = { .b=43 };   // yeah, useful C legacy!
I obviously meant: S args = { b: 43 };
Feb 17
prev sibling parent reply Yuxuan Shui <yshuiv7 gmail.com> writes:
On Sunday, 17 February 2019 at 13:44:09 UTC, Cym13 wrote:
 On Saturday, 16 February 2019 at 12:41:01 UTC, Andre Pany wrote:
 [...]
I 100% support that. Relying on struct initialization is both the easiest and safest way to go in my opinion: 0) as a reminder the idea is that today you can do that: struct S { int a, int b=42 } void f(S args); S args = { .b=43 }; // yeah, useful C legacy! f(args); but there's currently no way to directly initialize that struct in the f() call. 1) it's already there. All problems have already been solved, the code is there with reordering, default values, order of evaluation etc. Struct initialization already works, just not in-place. 2) it's as backward compatible as it can be: as long as the calle provides a function that takes a struct as argument it'll work. It'll work with C code, it'll work with C++ code, it'll work without named, it'll just work. It's just structs, cleverly used.
Sure, but it has the exactly same property as named: it's opt-in. Yes, maybe you can do it with a one-liner (I don't know how. There doesn't seem to be a way to retrieve parameter names from a function), but that can't be easier than adding " named".
 3) the only thing needed is to finally close that in-place 
 struct initialization DIP.

 I'd much rather have that than introducing new attributes and 
 duplicating code (since, as I said, such code is already 
 existing for partial structs initialization).
So it probably could be reused?
Feb 17
parent Andre Pany <andre s-e-a-p.de> writes:
On Sunday, 17 February 2019 at 17:14:57 UTC, Yuxuan Shui wrote:
 On Sunday, 17 February 2019 at 13:44:09 UTC, Cym13 wrote:
 [...]
Sure, but it has the exactly same property as named: it's opt-in. Yes, maybe you can do it with a one-liner (I don't know how. There doesn't seem to be a way to retrieve parameter names from a function), but that can't be easier than adding " named".
 [...]
So it probably could be reused?
It already exists std.traits: ParameterIdentifierTuple Kind regards Andre
Feb 17
prev sibling next sibling parent reply Vladimir Panteleev <thecybershadow.lists gmail.com> writes:
On Friday, 15 February 2019 at 12:56:45 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1019, "Named Arguments Lite":

 https://github.com/dlang/DIPs/blob/23ef47a94e0fdd5ddc4b2f6b2f4dcfd3c1f43aa6/DIPs/DIP1019.md
Named arguments is the #1 missing language feature in my personal wish list. It allows drastically improving the readability of code in many situations. With it, we can also do away with the awful Flag!"enableSomething" enableSomething / Yes.enableSomething templates. So, thank you for working on this.
 For example, in one potential library-only solution, it is 
 necessary to call functions like so:
 args!(add, a=>1, b=>1);
There is another big problem with this approach: you cannot do a=>a, b=>b etc. The compiler will pick up the fake lambda parameter instead of the variable from the outer scope. This is a pain because you will very often see fun(foo=foo, bar=bar) in idiomatic Python code.
 Opt-in: Calling a function with named arguments is opt-in on 
 the callee side.
named is not the best idea. I don't want to have to check every time if the library author remembered to slap named on the function I want to use named arguments with. Making it opt-in will probably mean that there will be people who use it and those who don't, and libraries written by users who don't will just cause frustration by those who do; and, for people who do, they might as well just slap it on everything, further contributing to attribute bloat. Also, the decision to use named arguments depends as much on the function as on the call site (e.g. how important is code readability vs. terseness in that particular piece of code). I'd be just too tempted to patch the compiler to enable it for everything. Generally, I do not buy the lock-in arguments, now or 10 years ago when Don shut the idea down the first time. I think it is enough to give library authors a way to provide aliases to old parameter names, so they have freedom to rename the parameters without breaking code using named arguments. I'm not sure if forward arguments is the best approach for this, seems very brittle - you don't update all signatures correctly, and suddenly some users of your library get hit with linking errors. And, what about templated functions? I think allowing alias in parameter lists would be worthwhile, e.g.: void drawRect(int x, int y, int width, int height, alias w = width, alias h = height); Bonus if "deprecated alias" is allowed and works as expected. Sorry, I'm jumping late into the discussion, so the above might have been already discussed.
Feb 16
next sibling parent reply Yuxuan Shui <yshuiv7 gmail.com> writes:
On Saturday, 16 February 2019 at 23:56:45 UTC, Vladimir Panteleev 
wrote:
 On Friday, 15 February 2019 at 12:56:45 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1019, "Named Arguments Lite":

 https://github.com/dlang/DIPs/blob/23ef47a94e0fdd5ddc4b2f6b2f4dcfd3c1f43aa6/DIPs/DIP1019.md
Named arguments is the #1 missing language feature in my personal wish list. It allows drastically improving the readability of code in many situations. With it, we can also do away with the awful Flag!"enableSomething" enableSomething / Yes.enableSomething templates. So, thank you for working on this.
 For example, in one potential library-only solution, it is 
 necessary to call functions like so:
 args!(add, a=>1, b=>1);
There is another big problem with this approach: you cannot do a=>a, b=>b etc. The compiler will pick up the fake lambda parameter instead of the variable from the outer scope. This is a pain because you will very often see fun(foo=foo, bar=bar) in idiomatic Python code.
Good point.
 Opt-in: Calling a function with named arguments is opt-in on 
 the callee side.
named is not the best idea. I don't want to have to check every time if the library author remembered to slap named on the function I want to use named arguments with. Making it opt-in will probably mean that there will be people who use it and those who don't, and libraries written by users who don't will just cause frustration by those who do; and, for people who do, they might as well just slap it on everything, further contributing to attribute bloat. Also, the decision to use named arguments depends as much on the function as on the call site (e.g. how important is code readability vs. terseness in that particular piece of code). I'd be just too tempted to patch the compiler to enable it for everything.
It's not my favorite either. But I feel it is the best we can do at the moment.
 Generally, I do not buy the lock-in arguments, now or 10 years 
 ago when Don shut the idea down the first time. I think it is 
 enough to give library authors a way to provide aliases to old 
 parameter names, so they have freedom to rename the parameters 
 without breaking code using named arguments.

 I'm not sure if forward arguments is the best approach for 
 this, seems very brittle - you don't update all signatures 
 correctly, and suddenly some users of your library get hit with 
 linking errors. And, what about templated functions?
I don't see why forward declaration won't work for templated functions. And I don't quite understand why there might be linking problems. Can you give an example?
 I think allowing alias in parameter lists would be worthwhile, 
 e.g.:

 void drawRect(int x, int y, int width, int height, alias w = 
 width, alias h = height);
So, there are a couple (two) problems with this: 1. the parameter list might just get longer and longer, making the documentation verbose and hard to read. 2. The user can use any combinations of the aliases (e.g. (x, y, w, height), (x, y, width, h) are all valid), this is not necessarily helpful to readability.
 Bonus if "deprecated alias" is allowed and works as expected.
deprecated forward declaration could work. I will make that explicit in the next revision of this DIP.
 Sorry, I'm jumping late into the discussion, so the above might 
 have been already discussed.
You raised good points, thanks.
Feb 16
next sibling parent Vladimir Panteleev <thecybershadow.lists gmail.com> writes:
On Sunday, 17 February 2019 at 00:27:42 UTC, Yuxuan Shui wrote:
 It's not my favorite either. But I feel it is the best we can do
 at the moment.
Sorry, but I will vote against a DIP with named. With no guarantee that the opt-in will ever become opt-out or always available, the feature IMO will not carry its weight due to the problems I mentioned.
 I don't see why forward declaration won't work for templated 
 functions.
Will you need to expand the implicit template declaration (R fun(A)(A a){} => template fun(A) { R fun(A a) {} })? Or will the compiler need to detect that templates are part of the overload? I would suggest to consult with a DMD frontend expert to make sure the DIP is not overly difficult to implement.
 And I don't quite understand why there might be linking 
 problems. Can
 you give an example?
named: int add(int a, int b) { ... } int add(int c, int d); Let's say you want to add an optional argument to add. named: int add(int a, int b, int c = 0) { ... } but you forget to update the other forward declaration to match. You will not get a compiler error. You will not get a linking error if you never used the second declaration. But, a user using your library will now get a linking error if their code used the other declaration. I realized another problem after I sent my post: This approach is not usable for interface methods, and abstract methods (which may or may not have a body).
Feb 17
prev sibling parent reply Rubn <where is.this> writes:
On Sunday, 17 February 2019 at 00:27:42 UTC, Yuxuan Shui wrote:
 Opt-in: Calling a function with named arguments is opt-in on 
 the callee side.
named is not the best idea. I don't want to have to check every time if the library author remembered to slap named on the function I want to use named arguments with. Making it opt-in will probably mean that there will be people who use it and those who don't, and libraries written by users who don't will just cause frustration by those who do; and, for people who do, they might as well just slap it on everything, further contributing to attribute bloat. Also, the decision to use named arguments depends as much on the function as on the call site (e.g. how important is code readability vs. terseness in that particular piece of code). I'd be just too tempted to patch the compiler to enable it for everything.
It's not my favorite either. But I feel it is the best we can do at the moment.
I'd say enabling named parameters for everything would be better than any benefits you get with using an attribute. named void foo(int a, int b); named void foo(int c, int d); I don't find the above situation all that useful. There are multiple ways to deal with this. Using another type for the parameters: void foo( Size ab ); void foo( Point cd ); Or simply give the functions a different name to distinguish between them. Allowing two functions to exist with the same type signature just adds unnecessary complexity. Looking at a few languages that support named parameters they don't support this kind of named parameters. This includes C# and Python. def abc(a, b): print( "ab", a, b) def abc(c, d): print( "cd", c, d) abc(c=10, d=20) abc(a=12, b=23) # error the second def of abc() replaces the first If you want this functionality you are probably going to have to make a more concrete case for it than what is currently in the DIP. If there are any languages that implement it the way you want to implement it it would probably be a good idea to include them as examples.
Feb 17
parent reply Yuxuan Shui <yshuiv7 gmail.com> writes:
On Sunday, 17 February 2019 at 13:12:11 UTC, Rubn wrote:
 I'd say enabling named parameters for everything would be 
 better than any benefits you get with using an attribute.

      named void foo(int a, int b);
      named void foo(int c, int d);

 I don't find the above situation all that useful. There are 
 multiple ways to deal with this. Using another type for the 
 parameters:

     void foo( Size ab );
     void foo( Point cd );

 Or simply give the functions a different name to distinguish 
 between them.

 Allowing two functions to exist with the same type signature 
 just adds unnecessary complexity.
This is allowed, _right now_. This is not an addition made by this DIP. Example: https://d.godbolt.org/z/hbwsaU
 Looking at a few languages that support named parameters they 
 don't support this kind of named parameters. This includes C# 
 and Python.

     def abc(a, b):
         print( "ab", a, b)

     def abc(c, d):
         print( "cd", c, d)

     abc(c=10, d=20)
     abc(a=12, b=23) # error the second def of abc() replaces 
 the first
And they have the problem that the name of the parameter becomes part of the API. This is something this DIP tries to solve.
 If you want this functionality you are probably going to have 
 to make a more concrete case for it than what is currently in 
 the DIP. If there are any languages that implement it the way 
 you want to implement it it would probably be a good idea to 
 include them as examples.
I am pretty sure this DIP listed some major languages with this feature, and it also includes concrete examples.
Feb 17
next sibling parent reply 12345swordy <alexanderheistermann gmail.com> writes:
On Sunday, 17 February 2019 at 17:09:57 UTC, Yuxuan Shui wrote:
 And they have the problem that the name of the parameter 
 becomes part of the API. This is something this DIP tries to 
 solve.
A better solution would be allowing nameless parameters functions and refer the parameters by index. -Alex
Feb 17
next sibling parent Alex <sascha.orlov gmail.com> writes:
On Sunday, 17 February 2019 at 17:48:33 UTC, 12345swordy wrote:
 On Sunday, 17 February 2019 at 17:09:57 UTC, Yuxuan Shui wrote:
 And they have the problem that the name of the parameter 
 becomes part of the API. This is something this DIP tries to 
 solve.
A better solution would be allowing nameless parameters functions and refer the parameters by index. -Alex
This possibility exists already via variadic templates and via ´´´ void main() { fun(4, "kuku"); } void fun(int, string) { import std.stdio; writeln(_param_0); writeln(_param_1); } ´´´
Feb 17
prev sibling parent reply Rubn <where is.this> writes:
On Sunday, 17 February 2019 at 17:48:33 UTC, 12345swordy wrote:
 On Sunday, 17 February 2019 at 17:09:57 UTC, Yuxuan Shui wrote:
 And they have the problem that the name of the parameter 
 becomes part of the API. This is something this DIP tries to 
 solve.
A better solution would be allowing nameless parameters functions and refer the parameters by index. -Alex
That'd be worse, it'd make code less readable, the opposite of what named parameters are for.
Feb 17
parent reply 12345swordy <alexanderheistermann gmail.com> writes:
On Sunday, 17 February 2019 at 18:00:46 UTC, Rubn wrote:
 On Sunday, 17 February 2019 at 17:48:33 UTC, 12345swordy wrote:
 On Sunday, 17 February 2019 at 17:09:57 UTC, Yuxuan Shui wrote:
 And they have the problem that the name of the parameter 
 becomes part of the API. This is something this DIP tries to 
 solve.
A better solution would be allowing nameless parameters functions and refer the parameters by index. -Alex
That'd be worse, it'd make code less readable, the opposite of what named parameters are for.
That is only if you are so worried about "parameter name becomes part of the API", which such concerns should be the exception, not the norm. I have never ever encounter anyone in the c# community that worry about named parameter becomes part of the API, when named parameters are introduced. Client can simply use find and replace if the library they using change their parameter name. It is not a deal breaker as the DIP making out to be. Regardless, my objections still stand regarding named attribute and I can not tell other people with a straight face that in order to use named parameters they have to use named attribute without expecting them to look at me like "Are you insane?" I do not want D design to be worst, because of the "avoiding breaking code at all cost" mentality. That is what C++ is for.
Feb 17
parent reply JN <666total wp.pl> writes:
On Sunday, 17 February 2019 at 18:57:26 UTC, 12345swordy wrote:
 Regardless, my objections still stand regarding  named 
 attribute and I can not tell other people with a straight face 
 that in order to use named parameters they have to use  named 
 attribute without expecting them to look at me like "Are you 
 insane?"

 I do not want D design to be worst, because of the "avoiding 
 breaking code at all cost" mentality. That is what C++ is for.
While I still think named attribute feels weird, I know at least one language that requires opt-in for named arguments: Dart. An example is here: https://stackoverflow.com/a/13264231 . In Dart, you can mark arguments as named: getHttpUrl(String server, String path, {int port: 80}) and then call it: getHttpUrl('example.com', '/index.html', port: 8080); and you MUST use the name if it's a named argument. Also, mixing optional arguments and named arguments is just not allowed, so it solves the issue of how to deal with such ambiguous cases: thisFunctionWontWork(String foo, [String positonal], {String named})
Feb 17
parent 12345swordy <alexanderheistermann gmail.com> writes:
On Sunday, 17 February 2019 at 19:52:14 UTC, JN wrote:
 On Sunday, 17 February 2019 at 18:57:26 UTC, 12345swordy wrote:
 Regardless, my objections still stand regarding  named 
 attribute and I can not tell other people with a straight face 
 that in order to use named parameters they have to use  named 
 attribute without expecting them to look at me like "Are you 
 insane?"

 I do not want D design to be worst, because of the "avoiding 
 breaking code at all cost" mentality. That is what C++ is for.
While I still think named attribute feels weird, I know at least one language that requires opt-in for named arguments: Dart. An example is here: https://stackoverflow.com/a/13264231 . In Dart, you can mark arguments as named: getHttpUrl(String server, String path, {int port: 80}) and then call it: getHttpUrl('example.com', '/index.html', port: 8080); and you MUST use the name if it's a named argument. Also, mixing optional arguments and named arguments is just not allowed, so it solves the issue of how to deal with such ambiguous cases: thisFunctionWontWork(String foo, [String positonal], {String named})
Even though that is interesting, what is being currently presented is optional and not a requirement when the user call functions that are marked Named. That quite different from Dart. -Alex
Feb 17
prev sibling next sibling parent reply Rubn <where is.this> writes:
On Sunday, 17 February 2019 at 17:09:57 UTC, Yuxuan Shui wrote:
 On Sunday, 17 February 2019 at 13:12:11 UTC, Rubn wrote:
 I'd say enabling named parameters for everything would be 
 better than any benefits you get with using an attribute.

      named void foo(int a, int b);
      named void foo(int c, int d);

 I don't find the above situation all that useful. There are 
 multiple ways to deal with this. Using another type for the 
 parameters:

     void foo( Size ab );
     void foo( Point cd );

 Or simply give the functions a different name to distinguish 
 between them.

 Allowing two functions to exist with the same type signature 
 just adds unnecessary complexity.
This is allowed, _right now_. This is not an addition made by this DIP. Example: https://d.godbolt.org/z/hbwsaU
Yes that's very different from what you want to implement it. See below.
 Looking at a few languages that support named parameters they 
 don't support this kind of named parameters. This includes C# 
 and Python.

     def abc(a, b):
         print( "ab", a, b)

     def abc(c, d):
         print( "cd", c, d)

     abc(c=10, d=20)
     abc(a=12, b=23) # error the second def of abc() replaces 
 the first
And they have the problem that the name of the parameter becomes part of the API. This is something this DIP tries to solve.
 If you want this functionality you are probably going to have 
 to make a more concrete case for it than what is currently in 
 the DIP. If there are any languages that implement it the way 
 you want to implement it it would probably be a good idea to 
 include them as examples.
I am pretty sure this DIP listed some major languages with this feature, and it also includes concrete examples.
Yes and Python doesn't behave the way you are suggesting. Listing the languages that implement the feature but not how they implement it makes the argument weaker. You list Python but I would not say Python implements this feature the same way as you are suggesting it to be implemented. I'd use Python as an example against this DIP (as I have). Eg the DIP suggests this be valid code so long as it can be distinguished by at least one parameter. named: int add(int a, int b) { ... } int add(int c, int d) { ... } If you try and do the following currently: int add(int a, int b) { ... } int add(int c, int d) { ... } // error You get a compiler error. Defining two functions with the same type signatures shouldn't be possible, with or without named parameters. It just adds un-needed complexity.
Feb 17
parent reply Yuxuan Shui <yshuiv7 gmail.com> writes:
On Sunday, 17 February 2019 at 17:58:56 UTC, Rubn wrote:
 On Sunday, 17 February 2019 at 17:09:57 UTC, Yuxuan Shui wrote:
 On Sunday, 17 February 2019 at 13:12:11 UTC, Rubn wrote:
 [...]
This is allowed, _right now_. This is not an addition made by this DIP. Example: https://d.godbolt.org/z/hbwsaU
Yes that's very different from what you want to implement it. See below.
 [...]
And they have the problem that the name of the parameter becomes part of the API. This is something this DIP tries to solve.
 [...]
I am pretty sure this DIP listed some major languages with this feature, and it also includes concrete examples.
Yes and Python doesn't behave the way you are suggesting. Listing the languages that implement the feature but not how they implement it makes the argument weaker. You list Python but I would not say Python implements this feature the same way as you are suggesting it to be implemented. I'd use Python as an example against this DIP (as I have). Eg the DIP suggests this be valid code so long as it can be distinguished by at least one parameter. named: int add(int a, int b) { ... } int add(int c, int d) { ... }
This is not valid under this DIP. Actually, this is allowed under current D too, as long as you don't call "add". With my DIP, the behavior is the same, when you call add, you will get an error because your call matches both function. Parameter name is not part of overload resolution, this is explicitly stated in the DIP.
Feb 17
next sibling parent reply Yuxuan Shui <yshuiv7 gmail.com> writes:
After thinking about the feedback so far, I currently plan to 
make these changes to this DIP:

* For reordering: I want to step back from reordering. It was add 
as an after thought, and turns out to be way more involved than I 
expected, and it is really not part of my goal for this DIP.

* For  named: Since there exist templates like 
ParameterIdentiferTuple, it shouldn't be hard to write a template 
to automatically wrap non- named functions to make them  named. 
So this really is not a problem.

   If you are not satisfied with this solution (let me know), I 
have another proposal:  named will still be part of this DIP, but 
if a function is not annotated with  named, you can still call it 
with named parameters. If the names mismatch, you get a warning 
instead of an error. This way, API developers can clearly state 
their intentions with  named, and don't have to take 
responsibilities for API breakage caused by parameter rename; 
OTOH, API users can still call functions with named parameters.
Feb 17
next sibling parent 12345swordy <alexanderheistermann gmail.com> writes:
On Sunday, 17 February 2019 at 21:04:23 UTC, Yuxuan Shui wrote:
 After thinking about the feedback so far, I currently plan to 
 make these changes to this DIP:

 * For reordering: I want to step back from reordering. It was 
 add as an after thought, and turns out to be way more involved 
 than I expected, and it is really not part of my goal for this 
 DIP.

 * For  named: Since there exist templates like 
 ParameterIdentiferTuple, it shouldn't be hard to write a 
 template to automatically wrap non- named functions to make 
 them  named. So this really is not a problem.
It is an issue if you are concern about compile time cost and generating unwanted verbiage. Templates despite powerful have a cost associated with them. -Alex
Feb 17
prev sibling next sibling parent reply RazvanN <razvan.nitu1305 gmail.com> writes:
On Sunday, 17 February 2019 at 21:04:23 UTC, Yuxuan Shui wrote:
 After thinking about the feedback so far, I currently plan to 
 make these changes to this DIP:

 * For reordering: I want to step back from reordering. It was 
 add as an after thought, and turns out to be way more involved 
 than I expected, and it is really not part of my goal for this 
 DIP.

 * For  named: Since there exist templates like 
 ParameterIdentiferTuple, it shouldn't be hard to write a 
 template to automatically wrap non- named functions to make 
 them  named. So this really is not a problem.

   If you are not satisfied with this solution (let me know), I 
 have another proposal:  named will still be part of this DIP, 
 but if a function is not annotated with  named, you can still 
 call it with named parameters. If the names mismatch, you get a 
 warning instead of an error. This way, API developers can 
 clearly state their intentions with  named, and don't have to 
 take responsibilities for API breakage caused by parameter 
 rename; OTOH, API users can still call functions with named 
 parameters.
How about this: simply adding the ability to name the argument when calling a function? Example: void rectangle(int width, int height) {} void main() { rectangle(1, 2); rectangle(width: 1, height: 2); rectangle(height: 2, width: 1); rectangle(width: 1, 2); // error } All 3 function invocations lower to the same function call. Of course, naming should be either for all parameters or for none. This has the advantage that no code will be broken and naming will become optional. This way you have no mangling problems and you don't have to add any attributes. This solution is also easier to implement and easier to drop/enhance after we gather some information about where we need to go with this. Cheers RazvanN
Feb 18
next sibling parent RazvanN <razvan.nitu1305 gmail.com> writes:
On Monday, 18 February 2019 at 08:32:02 UTC, RazvanN wrote:
 On Sunday, 17 February 2019 at 21:04:23 UTC, Yuxuan Shui wrote:
 [...]
How about this: simply adding the ability to name the argument when calling a function? Example: void rectangle(int width, int height) {} void main() { rectangle(1, 2); rectangle(width: 1, height: 2); rectangle(height: 2, width: 1); rectangle(width: 1, 2); // error } All 3 function invocations lower to the same function call. Of course, naming should be either for all parameters or for none. This has the advantage that no code will be broken and naming will become optional. This way you have no mangling problems and you don't have to add any attributes. This solution is also easier to implement and easier to drop/enhance after we gather some information about where we need to go with this. Cheers RazvanN
I forgot to mention optional parameters; if there are any optional parameters and you are fine with the default value, you don't have to specify them.
Feb 18
prev sibling next sibling parent 12345swordy <alexanderheistermann gmail.com> writes:
On Monday, 18 February 2019 at 08:32:02 UTC, RazvanN wrote:
 On Sunday, 17 February 2019 at 21:04:23 UTC, Yuxuan Shui wrote:
 [...]
How about this: simply adding the ability to name the argument when calling a function? Example: [...]
Now this is a solution that I can get behind.
Feb 18
prev sibling parent reply Seb <seb wilzba.ch> writes:
On Monday, 18 February 2019 at 08:32:02 UTC, RazvanN wrote:
 On Sunday, 17 February 2019 at 21:04:23 UTC, Yuxuan Shui wrote:
 [...]
How about this: simply adding the ability to name the argument when calling a function? Example: void rectangle(int width, int height) {} void main() { rectangle(1, 2); rectangle(width: 1, height: 2); rectangle(height: 2, width: 1); rectangle(width: 1, 2); // error }
1) What about typos/wrong names? rectangle(width: 1, hight: 2) 2) How will this deal with parameter renames / deprecation? If (1) isn't checked, introducing this later would break a lot of code.
Feb 18
parent RazvanN <razvan.nitu1305 gmail.com> writes:
On Monday, 18 February 2019 at 19:27:15 UTC, Seb wrote:
 On Monday, 18 February 2019 at 08:32:02 UTC, RazvanN wrote:
 On Sunday, 17 February 2019 at 21:04:23 UTC, Yuxuan Shui wrote:
 [...]
How about this: simply adding the ability to name the argument when calling a function? Example: void rectangle(int width, int height) {} void main() { rectangle(1, 2); rectangle(width: 1, height: 2); rectangle(height: 2, width: 1); rectangle(width: 1, 2); // error }
1) What about typos/wrong names? rectangle(width: 1, hight: 2)
Easy: you print the parameters that do not match: "Unknown parameter name". If a parameter name is not in the list of parameters, you print it.
 2) How will this deal with parameter renames / deprecation?
The easiest solution would be to simply do nothing. Once a parameter name is changed, then it has to be updated on caller site. Later on we can add smarter stuff.
 If (1) isn't checked, introducing this later would break a lot 
 of code.
Indeed.
Feb 18
prev sibling parent reply David Bennett <davidbennett bravevision.com> writes:
On Sunday, 17 February 2019 at 21:04:23 UTC, Yuxuan Shui wrote:
 After thinking about the feedback so far, I currently plan to 
 make these changes to this DIP:

 ...
Would you also be able to confirm how this DIP handles default arguments and templates? I think the DIP could use an example showing this off. One of my almost dally 'is there no better way?' moments with D currently is default template arguments, for example to change throwErrors currently I need to do: --- T toString(T=string, bool SomeThing=true, bool throwErrors=true, S)(S value){return "";} auto foo = 123.toString!(string, true, false); --- Where as I think something like this would be better: --- auto foo = 123.toString!(throwErrors: false); ---
Mar 21
parent reply Yuxuan Shui <yshuiv7 gmail.com> writes:
On Thursday, 21 March 2019 at 20:31:57 UTC, David Bennett wrote:
 On Sunday, 17 February 2019 at 21:04:23 UTC, Yuxuan Shui wrote:
 After thinking about the feedback so far, I currently plan to 
 make these changes to this DIP:

 ...
Would you also be able to confirm how this DIP handles default arguments and templates? I think the DIP could use an example showing this off.
This DIP won't support template arguments. And with my current plan this DIP probably won't help default arguments either.
 One of my almost dally 'is there no better way?' moments with D 
 currently is default template arguments, for example to change 
 throwErrors currently I need to do:

 ---

 T toString(T=string, bool SomeThing=true, bool 
 throwErrors=true, S)(S value){return "";}

 auto foo = 123.toString!(string, true, false);

 ---

 Where as I think something like this would be better:

 ---

 auto foo = 123.toString!(throwErrors: false);

 ---
Yes, that would be better, but sadly that's out of the scope of this DIP.
Mar 22
parent David Bennett <davidbennett bravevision.com> writes:
On Friday, 22 March 2019 at 15:18:09 UTC, Yuxuan Shui wrote:
 On Thursday, 21 March 2019 at 20:31:57 UTC, David Bennett wrote:
 Would you also be able to confirm how this DIP handles default 
 arguments and templates?
 I think the DIP could use an example showing this off.
This DIP won't support template arguments. And with my current plan this DIP probably won't help default arguments either.
That is unfortunate as its the part that gives me the most pain currently. Almost so much as to make me feel like adding a 3rd named arguments DIP that only worked on default arguments.
Apr 01
prev sibling parent Rubn <where is.this> writes:
On Sunday, 17 February 2019 at 20:58:04 UTC, Yuxuan Shui wrote:
 On Sunday, 17 February 2019 at 17:58:56 UTC, Rubn wrote:
 On Sunday, 17 February 2019 at 17:09:57 UTC, Yuxuan Shui wrote:
 On Sunday, 17 February 2019 at 13:12:11 UTC, Rubn wrote:
 [...]
This is allowed, _right now_. This is not an addition made by this DIP. Example: https://d.godbolt.org/z/hbwsaU
Yes that's very different from what you want to implement it. See below.
 [...]
And they have the problem that the name of the parameter becomes part of the API. This is something this DIP tries to solve.
 [...]
I am pretty sure this DIP listed some major languages with this feature, and it also includes concrete examples.
Yes and Python doesn't behave the way you are suggesting. Listing the languages that implement the feature but not how they implement it makes the argument weaker. You list Python but I would not say Python implements this feature the same way as you are suggesting it to be implemented. I'd use Python as an example against this DIP (as I have). Eg the DIP suggests this be valid code so long as it can be distinguished by at least one parameter. named: int add(int a, int b) { ... } int add(int c, int d) { ... }
This is not valid under this DIP. Actually, this is allowed under current D too, as long as you don't call "add". With my DIP, the behavior is the same, when you call add, you will get an error because your call matches both function. Parameter name is not part of overload resolution, this is explicitly stated in the DIP.
How does it decide which function to call in this case, straight from the DIP, go through the entire process cause the DIP is rather ambiguous. Specifically if parameter names are not included in the mangled name of a function per the feature not being part of the scope of the DIP.
 int add(int a, int b) {...}
 int add(int c, int d) {...} // not in the overload set
 void main() {
     add(a: 1, b: 2);
 }

 It might be useful to have parameter names included in the 
 mangled name of a function so that changing the ordering of 
 parameters does not break existing binaries. Such is beyond the 
 scope of this DIP. A future DIP may address this issue.
Feb 17
prev sibling parent Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On Sunday, 17 February 2019 at 17:09:57 UTC, Yuxuan Shui wrote:
 On Sunday, 17 February 2019 at 13:12:11 UTC, Rubn wrote:
 Allowing two functions to exist with the same type signature 
 just adds unnecessary complexity.
This is allowed, _right now_. This is not an addition made by this DIP. Example: https://d.godbolt.org/z/hbwsaU
That seems to be a misunderstanding of what that example does. The first two declarations are just declaring that a function should exist with the signature `int fun(int, int)`. The third declaration actually implements that function. If OTOH you delete the implementation and use `dmd -c` to compile without linking, you'll get the expected overload-related error, whether or not you have the same or different parameter names, or no parameter names at all, in those first two declarations.
Feb 27
prev sibling parent SimonN <eiderdaus gmail.com> writes:
On Saturday, 16 February 2019 at 23:56:45 UTC, Vladimir Panteleev 
wrote:
  named is not the best idea.
I discourage named, too. The lesser evil is when implementors break call sites whenever implementors rename their arguments. It's rare that this happens purely for style. (If the renaming is caused by a semantic change in the function, then we want noisy breakage in the call sites anyway, with or without named.) Function designers are already annotating everything with property const safe pure nothrow nogc. Let's not bloat the definition even more with named. Besides named, I'm happy with the proposal. Expressiveness and automatic checks are good. -- Simon
Feb 18
prev sibling next sibling parent reply Elronnd <elronnd elronnd.net> writes:
I might be misunderstanding something, but with this code:

int add(int x, int y);
 named:
int add(int c, int d);

What happens if I do add(5, 6)?  Won't that be ambiguous?
Feb 17
parent Paul Backus <snarwin gmail.com> writes:
On Sunday, 17 February 2019 at 18:23:13 UTC, Elronnd wrote:
 I might be misunderstanding something, but with this code:

 int add(int x, int y);
  named:
 int add(int c, int d);

 What happens if I do add(5, 6)?  Won't that be ambiguous?
All declarations with the same signature must refer to the same function. Or, in other words, only one of them can have a function body, and that body will be used for all calls that match any of the equivalent declarations. Redundant declarations like this are actually already allowed in D; there just isn't any particular reason you'd want to use them. Example: https://run.dlang.io/is/MSmiF5
Feb 17
prev sibling next sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Friday, February 15, 2019 5:56:45 AM MST Mike Parker via Digitalmars-d 
wrote:
 This is the feedback thread for the first round of Community
 Review for DIP 1019, "Named Arguments Lite":

 https://github.com/dlang/DIPs/blob/23ef47a94e0fdd5ddc4b2f6b2f4dcfd3c1f43aa
 6/DIPs/DIP1019.md

 All review-related feedback on and discussion of the DIP should
 occur in this thread. The review period will end at 11:59 PM ET
 on March 1, or when I make a post declaring it complete.

 At the end of Round 1, if further review is deemed necessary, the
 DIP will be scheduled for another round of Community Review.
 Otherwise, it will be queued for the Final Review and Formal
 Assessment by the language maintainers.

 Please familiarize yourself with the documentation for the
 Community Review before participating.

 https://github.com/dlang/DIPs/blob/master/PROCEDURE.md#community-review

 Thanks in advance to all who participate.
I honestly don't understand the whole deal about discussing "repurposing" function parameters. If you refactor a function, it needs to continue to work with all existing calls to it, or it's going to break code. So, stuff like swapping x and y and the like make absolutely no sense. If you're going to screw up existing function calls by changing the function's signature, then you can't change the function's signature. So, I don't see any point in even worrying about function parameters being repurposed. Personally, I hope that we never have any form of named arguments in D (beyond whatever folks do with libraries, though I hope never have to deal with code that uses such libraries). But ultimately, that's going to be up to Walter and Andrei... I do approve of the fact that this DIP doesn't automatically enable named arguments everywhere, since I really, really, really don't want to have parameters be part of the API if I can possibly avoid it, and I would never use named anywhere if this DIP gets approved - though in all likelihood, that will result in arguments about whether folks should slap named on functions or not between folks who want named arguments and those who don't. So, approval of the DIP with such an attribute could become pretty divisive with regards to how folks write libraries. I'm not sure that you can punt the name mangling issue like the DIP currently does. It's currently legal to declare functions without even having parameter names (let alone requiring that the parameter names match) when you deal with stuff like .di files. It also affects what happens with functions that aren't extern(D). For instance, it's perfectly legal to put pure or nothrow on an extern(C) function declaration, and that affecs how the D code uses it, but it has no effect on the name mangling. If named arguments affect the name mangling, then they will only work with extern(D) functions, but if they don't, then you have issues when a function's declaration doesn't match its definition with regards to its parameters' names. - Jonathan M Davis
Feb 26
next sibling parent aliak <something something.com> writes:
On Wednesday, 27 February 2019 at 02:17:30 UTC, Jonathan M Davis 
wrote:

 Personally, I hope that we never have any form of named 
 arguments in D (beyond whatever folks do with libraries, though 
 I hope never have to deal with code that uses such libraries). 
 But ultimately, that's going to be up to Walter and Andrei...
Curious. How come? Would it not be nicer for contributors to know what "TexPos(1, 1)" (from your dxml library) does without having to lookup TextPos? I actually got it wrong from just reading the source. I thought it was pixel positions x, y. But nope. Another thing is that almost every time I see std.traits anywhere, I NEVER know which argument is what and always have to look it up. Multiply this by every programmer who has to code review, or maintain code and it's a lot of wasted time that's solved with proper use of named arguments. Some arguments I have heard about against named arguments though: 1) verbosity of call-site - solvable when named arguments are optional, should the API designer think so. It's the same as if an API designer decides to call a publicly accessible property "config" or "configuration". If there's a function that takes one argument, it makes little sense for an API writer to force it to be named. But as long as that choice is given, the purpose is to make the function as natural as possible. 2) Parameter lock in - don't see how that's different than function name lock in. Choose a name, use it. It goes through code reviews. If you change it, you bump a version number. I guess the number of places where the api can break increases though. But from a number of years of experience, I have not experienced this. Plus, I tend to find that API "superficially" used named arguments Example from std: topN(r, 3) topNCopy(r1, r2) topNIndex(r1, i1) These are the same function with different named arguments: topN(r, 3) topN(r, copy: r2) topN(r, index: r2) But since you don't have named arguments you put the name part of the arguments in the function name. 3) Needing to think about parameter names. You don't if they're optional. As the API designer. You need to think about the public interface of your function name anyway. And, if you're making public APIs, you're making docs (I hope). So you're already doing this. You would have to think if the API required named arguments or not though. 4) ?? Cheers, - Ali
Feb 27
prev sibling parent reply Rubn <where is.this> writes:
On Wednesday, 27 February 2019 at 02:17:30 UTC, Jonathan M Davis 
wrote:
 On Friday, February 15, 2019 5:56:45 AM MST Mike Parker via 
 Digitalmars-d wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1019, "Named Arguments Lite":

 https://github.com/dlang/DIPs/blob/23ef47a94e0fdd5ddc4b2f6b2f4dcfd3c1f43aa
6/DIPs/DIP1019.md

 All review-related feedback on and discussion of the DIP 
 should occur in this thread. The review period will end at 
 11:59 PM ET on March 1, or when I make a post declaring it 
 complete.

 At the end of Round 1, if further review is deemed necessary, 
 the DIP will be scheduled for another round of Community 
 Review. Otherwise, it will be queued for the Final Review and 
 Formal Assessment by the language maintainers.

 Please familiarize yourself with the documentation for the 
 Community Review before participating.

 https://github.com/dlang/DIPs/blob/master/PROCEDURE.md#community-review

 Thanks in advance to all who participate.
I do approve of the fact that this DIP doesn't automatically enable named arguments everywhere, since I really, really, really don't want to have parameters be part of the API if I can possibly avoid it, and I would never use named anywhere if this DIP gets approved - though in all likelihood, that will result in arguments about whether folks should slap named on functions or not between folks who want named arguments and those who don't. So, approval of the DIP with such an attribute could become pretty divisive with regards to how folks write libraries.
I don't agree with this at all. The feature becomes all but useless, it's either all in or just don't include it. So many things are already part of the API, and this will be an opt-in feature for the user (not the library developer). The user can choose to use the variable names if they want, knowing full well if the author pleases they can change it, but this will be no different than changing the variable name of struct.
Feb 28
parent reply Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On Friday, 1 March 2019 at 00:49:25 UTC, Rubn wrote:
 I don't agree with this at all. The feature becomes all but 
 useless, it's either all in or just don't include it. So many 
 things are already part of the API, and this will be an opt-in 
 feature for the user (not the library developer). The user can 
 choose to use the variable names if they want, knowing full 
 well if the author pleases they can change it, but this will be 
 no different than changing the variable name of struct.
It's not comparable to changing the variable name of a struct, because if that struct is a public data structure in a library, changing its field names is a breaking change. Downstream users should be able to rely on a library maintainer not doing that except in a major release (and even then, providing a clear heads-up and transition path; it might work in some cases to e.g. rename the struct field but add a `deprecated alias oldName = newName`, and then drop that alias only in the next major release). If the language design is changed so that downstream users _can_ use named arguments, then library maintainers have to assume that they _will_, and treat parameter names accordingly. It's no good just saying "I don't support this", because if you can't enforce such a constraint ahead of time, you are on a hiding to nothing. If API opt-in to named parameter support is not adequate, then it's better to drop the feature request entirely, because it is not reasonable to impose a big new responsibility like named arguments on maintainers of existing codebases.
Mar 03
next sibling parent reply Olivier FAURE <couteaubleu gmail.com> writes:
On Sunday, 3 March 2019 at 10:50:05 UTC, Joseph Rushton Wakeling 
wrote:
 If API opt-in to named parameter support is not adequate, then 
 it's better to drop the feature request entirely, because it is 
 not reasonable to impose a big new responsibility like named 
 arguments on maintainers of existing codebases.
I think you're overstating how big the responsibility is. Maintainers can still change argument names with the current DIP, they just need to keep exporting a prototype with the old names.
Mar 03
parent reply Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On Sunday, 3 March 2019 at 12:46:22 UTC, Olivier FAURE wrote:
 Maintainers can still change argument names with the current 
 DIP, they just need to keep exporting a prototype with the old 
 names.
Well, since the current DIP is entirely opt-in from the function author side anyway, it's a bit of a moot point. I was responding rather to someone who was arguing that it should _not_ be opt in for function authors.
Mar 03
parent reply Olivier FAURE <couteaubleu gmail.com> writes:
On Sunday, 3 March 2019 at 15:07:04 UTC, Joseph Rushton Wakeling 
wrote:
 Well, since the current DIP is entirely opt-in from the 
 function author side anyway, it's a bit of a moot point. I was 
 responding rather to someone who was arguing that it should 
 _not_ be opt in for function authors.
My point was, the DIP should be opt-out, because even then library maintainers can always change argument names if they want to, without breaking code. And even if code does break, it's an extremely easy fix (as in, "change a few names until it compiles", not "refactor everything"). Like, okay, I get that some people are opposed to the very idea of parameter names being important information to keep track of, but pragmatically, the costs of making named arguments the default are far outweighed by the benefits.
Mar 04
next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Mon, Mar 04, 2019 at 06:57:16PM +0000, Olivier FAURE via Digitalmars-d wrote:
 On Sunday, 3 March 2019 at 15:07:04 UTC, Joseph Rushton Wakeling wrote:
 Well, since the current DIP is entirely opt-in from the function
 author side anyway, it's a bit of a moot point. I was responding
 rather to someone who was arguing that it should _not_ be opt in for
 function authors.
My point was, the DIP should be opt-out, because even then library maintainers can always change argument names if they want to, without breaking code. And even if code does break, it's an extremely easy fix (as in, "change a few names until it compiles", not "refactor everything"). Like, okay, I get that some people are opposed to the very idea of parameter names being important information to keep track of, but pragmatically, the costs of making named arguments the default are far outweighed by the benefits.
IMNSHO, even if parameter names aren't important information to keep track of, being forced to accomodate renamings would motivate people to actually invent useful, self-explanatory parameter names rather than `func(int a, int b, int c)` or worse, `func(int, int, int)`, with no indication as to what the parameter is supposed to mean. T -- WINDOWS = Will Install Needless Data On Whole System -- CompuMan
Mar 04
prev sibling parent reply Yuxuan Shui <yshuiv7 gmail.com> writes:
On Monday, 4 March 2019 at 18:57:16 UTC, Olivier FAURE wrote:
 On Sunday, 3 March 2019 at 15:07:04 UTC, Joseph Rushton 
 Wakeling wrote:
 Well, since the current DIP is entirely opt-in from the 
 function author side anyway, it's a bit of a moot point. I was 
 responding rather to someone who was arguing that it should 
 _not_ be opt in for function authors.
My point was, the DIP should be opt-out, because even then library maintainers can always change argument names if they want to, without breaking code. And even if code does break, it's an extremely easy fix (as in, "change a few names until it compiles", not "refactor everything"). Like, okay, I get that some people are opposed to the very idea of parameter names being important information to keep track of, but pragmatically, the costs of making named arguments the default are far outweighed by the benefits.
I agree that, having named arguments as the default would be better, _if_ we are designing a new language from ground up. With D, even if we want to eventually make named arguments the default, it have to go through a deprecation path. IMHO, this is what a mature language should do.
Mar 22
parent Paul Backus <snarwin gmail.com> writes:
On Friday, 22 March 2019 at 15:23:54 UTC, Yuxuan Shui wrote:
 I agree that, having named arguments as the default would be 
 better, _if_ we are designing a new language from ground up.

 With D, even if we want to eventually make named arguments the 
 default, it have to go through a deprecation path. IMHO, this 
 is what a mature language should do.
Deprecation is typically used for changes to existing functionality that could break existing code. For example, the upcoming change to enable DIP 25 by default requires a deprecation process, because enabling DIP 25 will cause some code that currently works to fail to compile. Named arguments, however, are a purely additive change to the language. They will not break any existing D code, because all existing D code uses positional arguments, and positional arguments will continue to work the same way they always have. Why, then, is a deprecation process necessary?
Mar 22
prev sibling parent Yuxuan Shui <yshuiv7 gmail.com> writes:
On Sunday, 3 March 2019 at 10:50:05 UTC, Joseph Rushton Wakeling 
wrote:
 On Friday, 1 March 2019 at 00:49:25 UTC, Rubn wrote:
 I don't agree with this at all. The feature becomes all but 
 useless, it's either all in or just don't include it. So many 
 things are already part of the API, and this will be an opt-in 
 feature for the user (not the library developer). The user can 
 choose to use the variable names if they want, knowing full 
 well if the author pleases they can change it, but this will 
 be no different than changing the variable name of struct.
It's not comparable to changing the variable name of a struct, because if that struct is a public data structure in a library, changing its field names is a breaking change. Downstream users should be able to rely on a library maintainer not doing that except in a major release (and even then, providing a clear heads-up and transition path; it might work in some cases to e.g. rename the struct field but add a `deprecated alias oldName = newName`, and then drop that alias only in the next major release). If the language design is changed so that downstream users _can_ use named arguments, then library maintainers have to assume that they _will_, and treat parameter names accordingly. It's no good just saying "I don't support this", because if you can't enforce such a constraint ahead of time, you are on a hiding to nothing. If API opt-in to named parameter support is not adequate, then it's better to drop the feature request entirely, because it is not reasonable to impose a big new responsibility like named arguments on maintainers of existing codebases.
Agree completely. Finally someone arguing from this side :)
Mar 04
prev sibling next sibling parent reply Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
I would broadly second Jonathan's remarks above:
https://forum.dlang.org/post/mailman.7211.1551233866.29801.digitalmars-d puremagic.com

... but a few thoughts in my own words.

First, I think my core objection to this proposal is that 
ultimately, it's a cosmetic change to language syntax that does 
not make any meaningful improvement to the kinds of programs one 
can write, or to the compiler's ability to prove their safety and 
correctness -- even allowing that it's opt-in, implementing 
support is going to be finnicky and intrusive, and risks nasty 
impacts on stuff that affects _all_ programs (e.g. name mangling).

If we consider the languages where named arguments are a feature, 
virtually all of them are scripting (or scriptable) languages 
where it's common to use them via a REPL, and the use-case is for 
functions that have a lot of parameters, where in the typical 
use-case the caller only wants to specify the ones that are 
non-default.

In a scripting language, it's convenient to allow the user to 
just make the one function call.  But in a systems programming 
language it's both straightforward and arguably better 
self-documenting to do something like:

```
struct Config
{
     // default values for everything
     int alpha = 23;
     double beta = 0.25;
     int gamma = 6;
     double delta = 1.5;
     // ...
     int omega = 99;
}

double foo (Config config)
{
     with(config) {
         // implementation
     }
}
```

and then one can call with e.g.:

```
Config config = { beta: 6.5, omega: 101 };
auto result = foo(config);
```

As others have already pointed out, it needs only some small 
improvements to the struct declaration mechanisms to allow us to 
do something like:

```
foo({ beta: 6.5, omega: 101 });
```

... without even needing to declare a separate Config instance.  
This sort of approach will work naturally with UFCS:

```
double bar (int a, Config config) { ... }

x.bar({ delta: 9.125, gamma: 7});
```

... so one therefore has the effect of named parameters without 
any real change to the language syntax or behaviour.

On the question of "protecting against silent breakage in cases 
when a function's parameters are repurposed and renamed": this 
seems a very narrow protection compared to all the ways in which 
one can introduce breaking change into a function.  And by 
contrast it blocks something that can be very useful, which is 
renaming a function parameter to better illustrate its meaning, 
_without_ changing its purpose.

Specific feedback on a few points:

* `Completeness`: note that this approach of "all named or none" 
is
   in contrast with various languages' approach to named 
parameters,
   where it's common to have some initial obligatory parameters 
plus
   the option to set extra config variables.  Think Python, e.g. in
   this usage from the `pandas` data science library:

       dates = pd.date_range('20190227', periods=6)

   This should be noted as a contrast with what is being proposed
   in the current DIP.  (The struct-based approach outlined above
   may allow something closer to this, albeit imperfectly.)

* in the `Overloading and name mangling` section it would be good
   to have contrasting examples of what happens when parameter 
names
   are identical but types are different, e.g.:

       int add(int a, int b) {...}
       double add(double a, double b) {...}

   ... and a clear description of how template functions and 
methods
   will be impacted, e.g. `T add(T)(T a, T b)`.

* `Alternatives` should be updated to note the struct-based 
approach
   described above and by others, which does not need any specific
   support beyond perhaps improvements proposed in the DIP 
currently
   being drafted at
   
https://github.com/wilzbach/DIPs/blob/b1283b455b635d7dcbc2c871d2aa47cc67190059/DIPs/DIP1xxx-sw.md

In summary:

* despite being opt-in only, the proposal still seems an 
intrusive change
   for limited practical benefit

* suggestions by others that named parameters should be opt-out 
would make
   it even more intrusive, and impose a massive unasked-for 
maintenance
   burden on existing library maintainers

* some small improvements to struct initialization would make it 
possible
   to get a syntax and behaviour very close to that wanted, while 
keeping
   entirely within existing idiomatic language syntax and style

Hope that helps!
Feb 27
next sibling parent reply JN <666total wp.pl> writes:
On Wednesday, 27 February 2019 at 12:49:52 UTC, Joseph Rushton 
Wakeling wrote:
 If we consider the languages where named arguments are a 
 feature, virtually all of them are scripting (or scriptable) 
 languages where it's common to use them via a REPL, and the 
 use-case is for functions that have a lot of parameters, where 
 in the typical use-case the caller only wants to specify the 
 ones that are non-default.
Virtually all of them is a bit of a simplification. C#, Kotlin, Swift, Dart, Objective-C are definitely not scripting languages and they aren't primarily used through repr, and they all support named/keyword arguments in some form.
 As others have already pointed out, it needs only some small 
 improvements to the struct declaration mechanisms to allow us 
 to do something like:

 ```
 foo({ beta: 6.5, omega: 101 });
 ```
This would be great.
Feb 27
parent reply Daniel N <no public.email> writes:
On Wednesday, 27 February 2019 at 18:16:32 UTC, JN wrote:
 On Wednesday, 27 February 2019 at 12:49:52 UTC, Joseph Rushton 
 Wakeling wrote:
 ```
 foo({ beta: 6.5, omega: 101 });
 ```
This would be great.
It would be great indeed, but insufficient. At least I can't find a reasonble struct based solution which handle default arguments correctly. struct dim { uint w=5; uint h=5; } void foo(dim d={w:10, h:10}){} void bar(dim d={w:20, h:20}){} foo({w:50}); // h should default to 10 but it likely will be 5 bar({w:50}); // h should default to 20 but it likely will be 5
Feb 27
parent reply Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On Wednesday, 27 February 2019 at 18:51:40 UTC, Daniel N wrote:
 It would be great indeed, but insufficient.

 At least I can't find a reasonble struct based solution which 
 handle default arguments correctly.

 struct dim {
   uint w=5;
   uint h=5;
 }

 void foo(dim d={w:10, h:10}){}
 void bar(dim d={w:20, h:20}){}

 foo({w:50}); // h should default to 10 but it likely will be 5
 bar({w:50}); // h should default to 20 but it likely will be 5
I wonder if you have a real-world example of this requirement (same named parameters but different requirements for defaults)? I ask because it seems like the best way to address the concern is likely to be contingent on the particular use case. The example given considers the input as a type encoding the set of parameter names and types, with default values as something extraneous. It feels like that's the conceptual problem: the input type should encode parameter names, types, and defaults all together. In other words, `foo` and `bar` should have different struct types (with different default values to their fields) as input. Clunky and maybe a bit boilerplate-y? Yes, but much less intrusive than introducing a syntax change that has significant impact on the maintainability of much already existing code. Note that this would be simpler from a developer point of view if it was possible to declare "anonymous" structs in place in the function declarations, i.e.: int foo (struct { int w = 10; int h = 10; }); int bar (struct { int w = 20; int h = 20; }); ... which combined with the earlier suggestion would also be a fairly natural extension of existing struct syntax.
Mar 03
parent reply Yuxuan Shui <yshuiv7 gmail.com> writes:
On Sunday, 3 March 2019 at 09:36:32 UTC, Joseph Rushton Wakeling 
wrote:
 Note that this would be simpler from a developer point of view 
 if it was possible to declare "anonymous" structs in place in 
 the function declarations, i.e.:

     int foo (struct { int w = 10; int h = 10; });
     int bar (struct { int w = 20; int h = 20; });

 ... which combined with the earlier suggestion would also be a 
 fairly natural extension of existing struct syntax.
I think this approach gives every parameter a default value, and thus make them all optional. Which is not necessarily desirable.
Mar 04
parent Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On Monday, 4 March 2019 at 12:00:54 UTC, Yuxuan Shui wrote:
 I think this approach gives every parameter a default value, 
 and thus make them all optional. Which is not necessarily 
 desirable.
Agreed. It was an example of how to solve (essentially within current D idioms) a particular subset of the problems where named arguments are useful.
Mar 04
prev sibling parent reply FeepingCreature <feepingcreature gmail.com> writes:
On Wednesday, 27 February 2019 at 12:49:52 UTC, Joseph Rushton 
Wakeling wrote:
 ...
 First, I think my core objection to this proposal is that 
 ultimately, it's a cosmetic change to language syntax that does 
 not make any meaningful improvement to the kinds of programs 
 one can write, or to the compiler's ability to prove their 
 safety and correctness
Yes it does!! That is in fact the main argument for it! It allows the compiler to do a *much* better job at ensuring the correctness of programs, by attaching parameters to semantic labels instead of passing them by arbitrary positions and hoping that the type system will happen to catch errors.
 even allowing that it's opt-in, implementing support is going 
 to be finnicky and intrusive, and risks nasty impacts on stuff 
 that affects _all_ programs (e.g. name mangling).
Only if you do it in a weird way. There's no *necessary* reason for named parameters to affect mangling at all.
 If we consider the languages where named arguments are a 
 feature, virtually all of them are scripting (or scriptable) 
 languages where it's common to use them via a REPL, and the 
 use-case is for functions that have a lot of parameters, where 
 in the typical use-case the caller only wants to specify the 
 ones that are non-default.

 In a scripting language, it's convenient to allow the user to 
 just make the one function call.  But in a systems programming 
 language it's both straightforward and arguably better 
 self-documenting to do something like:

 ```
 struct Config
 {
     // default values for everything
     int alpha = 23;
     double beta = 0.25;
     int gamma = 6;
     double delta = 1.5;
     // ...
     int omega = 99;
 }

 double foo (Config config)
 {
     with(config) {
         // implementation
     }
 }
 ```

 and then one can call with e.g.:

 ```
 Config config = { beta: 6.5, omega: 101 };
 auto result = foo(config);
 ```
And even that is one case where named parameters represent a *huge* improvement! If a new parameter is added to Config, there is *absolutely* no way to require it to be passed. You have to use something like my own `boilerplate.Builder()`, and even that just gives you an exception at compiletime. struct Foo { int a; int b; mixin(GenerateThis); } with (Foo.Builder()) { a = 2; return value; // runtime error: necessary field b not assigned // but no compile error because :( :( :( } There is *no way* to statically enforce that a field was set in a struct. Parameters on the other hand do this effortlessly. I'd *love* to ditch Boilerplate's generated builders and replace them with named parameters. The lack of named parameters is why that hacky expensive feature even exists to begin with.
 As others have already pointed out, it needs only some small 
 improvements to the struct declaration mechanisms to allow us 
 to do something like:

 ```
 foo({ beta: 6.5, omega: 101 });
 ```

 ... without even needing to declare a separate Config instance.
  This sort of approach will work naturally with UFCS:

 ```
 double bar (int a, Config config) { ... }

 x.bar({ delta: 9.125, gamma: 7});
 ```

 ... so one therefore has the effect of named parameters without 
 any real change to the language syntax or behaviour.
Yeah at the cost of breaking struct behavior, or you still don't have any way to have necessary parameters.
 On the question of "protecting against silent breakage in cases 
 when a function's parameters are repurposed and renamed": this 
 seems a very narrow protection compared to all the ways in 
 which one can introduce breaking change into a function.  And 
 by contrast it blocks something that can be very useful, which 
 is renaming a function parameter to better illustrate its 
 meaning, _without_ changing its purpose.
I have literally never done that, whereas I reorder function parameters relatively often. Do you really rename function parameters more often than inserting a new required parameter in the middle?
Feb 28
next sibling parent reply Dominikus Dittes Scherkl <dominikus.scherkl continental-corporation.com> writes:
On Thursday, 28 February 2019 at 08:32:22 UTC, FeepingCreature 
wrote:
 I have literally never done that, whereas I reorder function 
 parameters relatively often. Do you really rename function 
 parameters more often than inserting a new required parameter 
 in the middle?
A function taking more than 2 parameters is a design flaw on its own, I think. Let alone adding new parameters _in_the_middle_ (shudder). You should almost always be better off taking a struct as parameter.
Feb 28
parent FeepingCreature <feepingcreature gmail.com> writes:
On Thursday, 28 February 2019 at 09:22:31 UTC, Dominikus Dittes 
Scherkl wrote:
 A function taking more than 2 parameters is a design flaw on 
 its own, I think. Let alone adding new parameters 
 _in_the_middle_ (shudder). You should almost always be better 
 off taking a struct as parameter.
Considering D is billed as a multiparadigm language, I'd be surprised to hear that the intended usecase does not include "functions with more than two parameters". This comment seems quite far from practiced reality. In any case, passing a struct is a horrible solution, because, again, there is no way for structs to even enforce that *all* fields were set, let alone some subset, short of spamming Nullable.
Feb 28
prev sibling parent Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On Thursday, 28 February 2019 at 08:32:22 UTC, FeepingCreature 
wrote:
 Yes it does!! That is in fact the main argument for it! It 
 allows the compiler to do a *much* better job at ensuring the 
 correctness of programs, by attaching parameters to semantic 
 labels instead of passing them by arbitrary positions and 
 hoping that the type system will happen to catch errors.
This could sometimes be nice, but the question is whether the extra benefits are worth it compared to the problems caused by imposing a major semantic change on the language.
 If a new parameter is added to Config, there is *absolutely* no 
 way to require it to be passed. You have to use something like 
 my own `boilerplate.Builder()`, and even that just gives you an 
 exception at compiletime.

 [... snip ...]

 There is *no way* to statically enforce that a field was set in 
 a struct.
That's certainly a reasonable objection. The question is not, does this cover _all_ use cases for named parameters, but does it cover some of the major ones that matter? (For example, the case of multiple different parameters where one only wants to set the ones that need to be non-default.)
 Parameters on the other hand do this effortlessly. I'd *love* 
 to ditch Boilerplate's generated builders and replace them with 
 named parameters. The lack of named parameters is why that 
 hacky expensive feature even exists to begin with.
I'm not familiar with your Boilerplate library, so difficult to comment -- are you saying here that the library's features could be implemented more straightforwardly (or with a nicer API for users) if named parameters were a thing? Or that features of the library would not need to exist in the first place? I ask because it's possible that the requirements here are arriving more out of preferences for how to write the downstream code, than about problems with writing idiomatically in D as it is right now.
 I have literally never done that, whereas I reorder function 
 parameters relatively often. Do you really rename function 
 parameters more often than inserting a new required parameter 
 in the middle?
In what context do you reorder or insert new function parameters often? In public functions or methods of a library? In internals private to a library or app? And what's the motivation for such re-ordering? I ask because I wonder if there aren't other entirely adequate methods for managing those transitions that don't rely on named parameters, and which are more idiomatic to D as it already exists. If you have concrete examples we could probably discuss those. I accept that named parameters might make some of these transitions easier, but that has to be weighed against the disruption of introducing that feature to a language where a large amount of code has already been written without that feature in mind.
Mar 03
prev sibling next sibling parent reply Dukc <ajieskola gmail.com> writes:
On Friday, 15 February 2019 at 12:56:45 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review for DIP 1019, "Named Arguments Lite":
The proposal mentioned that having two named functions with same names and parameter types but different parameter names is allowed. However, this does imply named functions have different mangling than a similar unnamed function. I think the DIP should mention whether this means that extern(!D) functions are forbidden altogether, or just don't consider parameter names in overload resolution. The above brings this proposal closer to what Rikki did propose. IMO this proposal has better syntax, but Rikki's proposal has the advantage that named parameters can be combined with unnamed parameters. In any case, I think they should go to formal assesment together. Either one will be a step forward.
Feb 27
parent reply Olivier FAURE <couteaubleu gmail.com> writes:
On Wednesday, 27 February 2019 at 17:46:24 UTC, Dukc wrote:
 The proposal mentioned that having two  named functions with 
 same names and parameter types but different parameter names is 
 allowed.
No, it mentions that having two named prototypes for the same functions with the same name and parameter types but different parameters is allowed. eg: This is forbidden: named: int foo(int x, int y) { return x + y; } int foo(int w, int z) { return w + z; } and this is allowed: named: int foo(int x, int y); int foo(int w, int z) { return y + z; } The next iteration should probably make that distinction clearer.
Feb 28
parent reply Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On Thursday, 28 February 2019 at 21:55:50 UTC, Olivier FAURE 
wrote:
 No, it mentions that having two  named prototypes for the same 
 functions with the same name and parameter types but different 
 parameters is allowed.

 eg: This is forbidden:

      named:
     int foo(int x, int y) { return x + y; }
     int foo(int w, int z) { return w + z; }

 and this is allowed:

      named:
     int foo(int x, int y);
     int foo(int w, int z) { return y + z; }

 The next iteration should probably make that distinction 
 clearer.
Is the idea here that you can effectively define "aliases" for the parameter names (e.g. to help transitions), but not have multiple function implementations with the same type signatures and different names? That presumably impacts back on the mangling question, and whether the parameter names need to be included in the function mangling ... ?
Mar 01
parent Yuxuan Shui <yshuiv7 gmail.com> writes:
On Friday, 1 March 2019 at 13:37:24 UTC, Joseph Rushton Wakeling 
wrote:
 On Thursday, 28 February 2019 at 21:55:50 UTC, Olivier FAURE 
 wrote:
 [...]
Is the idea here that you can effectively define "aliases" for the parameter names (e.g. to help transitions), but not have multiple function implementations with the same type signatures and different names? That presumably impacts back on the mangling question, and whether the parameter names need to be included in the function mangling ... ?
Function names won't be included in mangling. It is a bit complicated now since this version of this DIP includes reordering, but the next revision won't.
Mar 04
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.com> writes:
On 2/15/19 7:56 AM, Mike Parker wrote:
 This is the feedback thread for the first round of Community Review for 
 DIP 1019, "Named Arguments Lite":
 
 https://github.com/dlang/DIPs/blob/23ef47a94e0fdd5ddc4b2f6b2f4dcfd3c1f4
aa6/DIPs/DIP1019.md 
Things that I think would make this DIP stronger: * The presence of the feature in other programming languages belongs in "rationale" if also the rationale pertaining to those other languages is present. Otherwise it's argument by majority. Normally "rationale" would stand on its own (possibly using examples drawn/inspired from other languages) and mention of other languages would go in the "related work" section (which presently is missing). ( Michael we need to make "Related Work" a required section.) * The example with "CalculateProduct(values, 7, false, null);" in the rationale should be completed with the best-of-the-breed solution in the current D language, i.e. using Flag. Currently Flag is not being discussed at all and it should because it is a workaround to named parameters (however insufficient as the proposal might argue). * The argument with repurposing argument is weak because code that doesn't use named parameters would be broken anyway, which makes the idea of repurposing parameters bad to start with. I suggest it be dropped, or mentioned later as a perk of named parameters. * "The relevance of forward declarations will become clear later." -> "Section xyz clarifies the relevance of forward declarations." * "Named arguments proposed by this DIP have no effect on the ordering of arguments in function calls." Related work will in all likelihood reveal that reordering arguments in large argument lists is a key advantage of named arguments. Not availing ourselves of that advantage is a serious issue that weakens the proposal. It must explain why it is not possible to allow reordering of arguments (or better yet work out the mechanics to allow it). * "Named arguments proposed by this DIP do not allow default parameters to be skipped." Not sure what "skipped" means in context; I assume it means some defaulted arguments would be left unspecified and other following them would be specified with non-default values. My understanding is that this is another key advantage of named arguments in related work - typically complex functions with large argument lists like CreateWindow, CreateArchive etc. would have many arguments defaulted to reasonable values, which then the caller can pick and choose which to customize. I assume a large part of what makes Python APIs so friendly is this ability. The DIP should explain why this is not desirable or achievable for the D language (or again better yet make it just work). * "Variadic arguments can be labeled with the name of the variadic parameter and a subscript." seems to have little value if there's only one variadic per function and all indexes must be specified in order. The DIP should explain why this feature (the index can be any compile-time expression... right?) is useful. * "If a function is defined with some of its parameter names omitted, arguments to those parameters can labeled with an empty name." The utility of this should be explained. * "This seems to be the biggest concern among people who are against named arguments." This is vague and nonscientific and has no place in a DIP. Who are those (does it even matter), where are the relevant exchanges, how did the author arrive at the conclusion that this is the biggest concern. The concern should be discussed at face value and if appropriate rebutted soundly with an analysis of the tradeoff (I assume it's not "all bad" vs "all good" but more like pros and cons). * "Allow calling the same function with a different set of parameter names." The advantage of this seems to be backward compatibility, but it endorses a technique that is questionable in the first place. * "This DIP does not prohibit future proposals for adding parameter reordering, partially-specified parameter names with reordering, named template parameters, omission of default arguments by using named arguments, and other similar things." The problem here is that all of these (easily anticipated as desirable) weaken the DIP by their absence from it.
Jun 06
parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Thu, Jun 06, 2019 at 12:31:14PM -0400, Andrei Alexandrescu via Digitalmars-d
wrote:
 On 2/15/19 7:56 AM, Mike Parker wrote:
 This is the feedback thread for the first round of Community Review for
 DIP 1019, "Named Arguments Lite":
 
 https://github.com/dlang/DIPs/blob/23ef47a94e0fdd5ddc4b2f6b2f4dcfd3c1f43aa6/DIPs/DIP1019.md
[...]
 * "Named arguments proposed by this DIP have no effect on the ordering
 of arguments in function calls." Related work will in all likelihood
 reveal that reordering arguments in large argument lists is a key
 advantage of named arguments. Not availing ourselves of that advantage
 is a serious issue that weakens the proposal. It must explain why it
 is not possible to allow reordering of arguments (or better yet work
 out the mechanics to allow it).
 
 * "Named arguments proposed by this DIP do not allow default
 parameters to be skipped." Not sure what "skipped" means in context; I
 assume it means some defaulted arguments would be left unspecified and
 other following them would be specified with non-default values. My
 understanding is that this is another key advantage of named arguments
 in related work - typically complex functions with large argument
 lists like CreateWindow, CreateArchive etc.  would have many arguments
 defaulted to reasonable values, which then the caller can pick and
 choose which to customize. I assume a large part of what makes Python
 APIs so friendly is this ability. The DIP should explain why this is
 not desirable or achievable for the D language (or again better yet
 make it just work).
[...] Yeah, these 2 points are also what greatly weakens this DIP, IMO, because they could be construed to be the raison d'etre of named arguments in the first place. Not having them makes one wonder what's the point of this DIP in the first place. As Amaury said in his DConf lightning talk, we don't want 95% features (or in this case, more like 50% features -- halfway there but missing major benefits of having named arguments in the first place). We want 100% features that provide core benefits, without being crippled in some way that makes them useless in non-trivial cases. T -- People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird. -- D. Knuth
Jun 06