DIP 1019--Named Arguments Lite--Community Review Round 1

aliak something at something.com
Fri Feb 15 17:03:40 UTC 2019


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




More information about the Digitalmars-d mailing list