January 23, 2016
On Saturday, 23 January 2016 at 14:19:03 UTC, Jacob Carlborg wrote:
> This is mostly to prevent ugly hacks like Flag [1].
>
> http://wiki.dlang.org/DIP88
>
> [1] https://dlang.org/phobos/std_typecons.html#.Flag

I already see confusing code like:
foo(10, 20, width: ((big) ? 600 : 200), height: ((big) ? 800 : 480));

I know many people, especially those who are coming from the Python world, want named parameters, but I am not entirely sure we want that in D.

I would rather use the Builder pattern instead, because that typically what people do with named parameters...

January 24, 2016
On Saturday, 23 January 2016 at 14:19:03 UTC, Jacob Carlborg wrote:
> This is mostly to prevent ugly hacks like Flag [1].
>
> http://wiki.dlang.org/DIP88
>
> [1] https://dlang.org/phobos/std_typecons.html#.Flag

To be pedantic, this would be adding named arguments, not named parameters. The parameters are already named, but mixing up arguments and parameters is a common mistake to make, and folks do frequently talk about named parameters with regards to this sort of feature.

Regardless, I for one, hope that we never have named arguments. It's just one more thing that's then part of the function's signature that you can't change without breaking code and will cause that much more bikeshedding. At least right now, parameter names don't matter much, whereas if they're part of the API, then they're open to all of the issues that function naming has.

And while I appreciate that this DIP does not make named arguments the default behavior for a function, making it up to the library writer whether they support named arguments or not is likely to create a lot of bikeshedding and debates over whether a particular function or library should support named arguments. Personally, I'd never use them under any circumstances.

However, I do appreciate that the DIP doesn't allow for reordering the arguments based on their names. It does make named arguments a bit less ugly.

- Jonathan M Davis
January 24, 2016
On Saturday, 23 January 2016 at 14:19:03 UTC, Jacob Carlborg wrote:
> This is mostly to prevent ugly hacks like Flag [1].
>
> http://wiki.dlang.org/DIP88
>
> [1] https://dlang.org/phobos/std_typecons.html#.Flag

Someone on another thread made a comment that it wasn't clear what : does in D. I suspect this won't help. I'm more used to equals from R than : in C# and Swift, though I'm not sure that really matters much.

There is a good discussion of named parameters here (particularly amon's answer):
http://programmers.stackexchange.com/questions/219593/why-do-many-languages-not-support-named-parameters
January 24, 2016
On Sunday, 24 January 2016 at 02:51:43 UTC, Jonathan M Davis wrote:
> On Saturday, 23 January 2016 at 14:19:03 UTC, Jacob Carlborg wrote:
>> This is mostly to prevent ugly hacks like Flag [1].
>>
>> http://wiki.dlang.org/DIP88
>>
>> [1] https://dlang.org/phobos/std_typecons.html#.Flag
>
> Regardless, I for one, hope that we never have named arguments. It's just one more thing that's then part of the function's signature that you can't change without breaking code and will cause that much more bikeshedding. At least right now, parameter names don't matter much, whereas if they're part of the API, then they're open to all of the issues that function naming has.
>
> And while I appreciate that this DIP does not make named arguments the default behavior for a function, making it up to the library writer whether they support named arguments or not is likely to create a lot of bikeshedding and debates over whether a particular function or library should support named arguments. Personally, I'd never use them under any circumstances.
>
> - Jonathan M Davis

So given this method:
void M(int a, int b = 1, int c = 2, int d = 3, int e = 4, int f = 5, int g = 6, int h = 7, int i = 8)
{
}

You prefer calling it this way:
M(5, 1, 2, 3, 4, 5, 6, 7, 23);
As opposed to:
M(5, i: 23);

Or am I misunderstanding you?
Also consider that the two aren't even the same, if the library author decides to change some default values you will likely want to update the former call, but the latter can stay the same. Less of a maintenance burden.

Coming from C# where it's a free-for-all-every-argument-can-be-named implementation, I never once even heard someone complain or experience breakage because some parameter name changed, which makes me think that the possibility of breakage, while of course real, seems to not be an issue in practice. Judging from my own coding habits in C#, I rarely change parameter names anyways (about as rarely as I change method names) and I rarely use named arguments anyways (most functions I dealt with neither had many optional parameters, nor had "blind" parameters where the documentation would've been sincerely helpful).

Also consider that using named arguments is a decision made by the caller ("I want to document these parameters..." or "Ugh I don't want to pass 10.000 arguments to this function, SKIP!"), not the callee ("Will the user want to document these parameters? Hmm... it's possible!" or "Will the user want to skip these default values? Hmm there's at most three here, not sure if it's worthwhile...").

As for this DIP I don't know - it seems to be well-thought-out, albeit with a focus on ease of implementation rather than usefulness for a language user, so I don't really have a conclusive opinion on that.
January 24, 2016
On Sunday, 24 January 2016 at 10:14:53 UTC, default0 wrote:
> On Sunday, 24 January 2016 at 02:51:43 UTC, Jonathan M Davis wrote:
>> On Saturday, 23 January 2016 at 14:19:03 UTC, Jacob Carlborg wrote:
>>> This is mostly to prevent ugly hacks like Flag [1].
>>>
>>> http://wiki.dlang.org/DIP88
>>>
>>> [1] https://dlang.org/phobos/std_typecons.html#.Flag
>>
>> Regardless, I for one, hope that we never have named arguments. It's just one more thing that's then part of the function's signature that you can't change without breaking code and will cause that much more bikeshedding. At least right now, parameter names don't matter much, whereas if they're part of the API, then they're open to all of the issues that function naming has.
>>
>> And while I appreciate that this DIP does not make named arguments the default behavior for a function, making it up to the library writer whether they support named arguments or not is likely to create a lot of bikeshedding and debates over whether a particular function or library should support named arguments. Personally, I'd never use them under any circumstances.
>>
>> - Jonathan M Davis
>
> So given this method:
> void M(int a, int b = 1, int c = 2, int d = 3, int e = 4, int f = 5, int g = 6, int h = 7, int i = 8)
> {
> }
>
> You prefer calling it this way:
> M(5, 1, 2, 3, 4, 5, 6, 7, 23);
> As opposed to:
> M(5, i: 23);

Anyone who wrote a function like that is just plain writing bad code. With that many parameters, they should be creating a struct to hold the values. Named arguments really only seem to help in cases where functions are badly designed. I don't want to use them in my code, and I don't want to have to deal with them in other people's code. And as a library writer, I don't want to have to argue with anyone about whether the names that I picked for my parameters were good or not. We already get way too much bikeshedding over function names as it is without adding parameter names into the mix.

I would strongly argue that anyone who feels the need for named parameters should rethink how they're designing their functions.

- Jonathan M Davis
January 24, 2016
On 1/24/16, Jonathan M Davis via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> I would strongly argue that anyone who feels the need for named parameters should rethink how they're designing their functions.

Another example where they become useful is with functions that take source and destination parameters. E.g.:

void copy ( Buffer src, Buffer tgt ) { }

vs

void copy ( Buffer tgt, Buffer src ) { }

With regard to param names being part of the API I think that:

- Parameter names very rarely change
- It's the responsibility of the client code authors to fix any code
breakage due to parameter renaming

I think the best thing we can do before completely dismissing this idea is to look into the experience of other programming communities (like Python) and try to weigh the pros vs the cons.
January 24, 2016
On Saturday, 23 January 2016 at 14:19:03 UTC, Jacob Carlborg wrote:
> This is mostly to prevent ugly hacks like Flag [1].
>
> http://wiki.dlang.org/DIP88

"A new syntax is added to be used when declaring a function that should be callable with named parameters:"

Please, no more new syntax!

This can be done using templates and Flag is not an ugly hack!
January 24, 2016
On Sunday, 24 January 2016 at 10:40:10 UTC, Jonathan M Davis wrote:
> On Sunday, 24 January 2016 at 10:14:53 UTC, default0 wrote:
>
> Anyone who wrote a function like that is just plain writing bad code. With that many parameters, they should be creating a struct to hold the values. Named arguments really only seem to help in cases where functions are badly designed. I don't want to use them in my code, and I don't want to have to deal with them in other people's code. And as a library writer, I don't want to have to argue with anyone about whether the names that I picked for my parameters were good or not. We already get way too much bikeshedding over function names as it is without adding parameter names into the mix.
>
> - Jonathan M Davis

I agree that functions like that are badly designed. However they exist and you can't always change them.
That said, if there'd be traits for parameter names you can probably automate the creation of a decent struct-wrapper, making this a non-issue for D (you could not do that in C#, so writing wrappers would be a huge pain there).
Regarding the bikeshedding: I honestly don't think this increases the amount of bikeshedding happening. There'll always be bikeshedding anyways, independent of if you give many opportunities for it or not.

Thinking further about this, though, and being the inexperienced D user I am, I assume you use struct wrappers sort of like this?
ArgStruct s;
s.param1 = 12;
M(s);

If yes, consider that a named argument alternative would be far less noisy:
M(param1: 12);

If my code above is far more verbose than what you'd usually do (ie comparable to the succinctness of the named argument), can you please give an example?
January 24, 2016
On Sunday, 24 January 2016 at 11:20:20 UTC, Gary Willoughby wrote:
> Please, no more new syntax!
>
> This can be done using templates and Flag is not an ugly hack!

Why no more new syntax? I agree that keeping the language simple is a good idea, but new syntax isn't usually hard to learn, especially if it hits the sweet spot between being different enough to easily tell that it means something special/new and being close enough to the rest of the syntax to not feel alien.

Also Flag seems like quite the waste of linespace. In addition to the name of the parameter I lose 7 characters (Flag!""). Named arguments would only use up 2 (: ) or 3 ( = ) characters.
Plus, being a library solution, at first it makes you wonder if there is something special going on with Flag (cuz you know, types usually have associated behaviour), instead of being purely for documentation purposes.
Totally qualifies as a hack to me.
January 24, 2016
On 2016-01-23 19:27, Chris Wright wrote:

> One huge usecase for this is methods with many optional parameters.
> You've missed that. For instance, I wrote a method with six optional
> parameters recently. It's unusable without named parameters. I switched
> to a parameter struct, but it's still not that great.

I did not miss that. I deliberately chose to not support changing the order of the arguments.

> I'd also add that this proposal doesn't affect UFCS.

How would it affect UFCS?

> What about overloading based on parameter names? The proposal doesn't
> even mention the idea, so there's no guessing whether you considered and
> rejected it or just didn't consider it.

The DIP mentions that no change is required for function overloading. But I added an explicitly rule about that.

> I'll note that parameter names are already part of documentation, and
> they're already the only parameter documentation you're guaranteed to
> have.

Currently it's possible to change a parameter name without the call site needing any change. Documentation has nothing to do with that.

> The Dart devs decided that named parameters must be explicitly set out as
> named, and they cited the same reason. The C# devs, on the other hand,
> made every parameter a named parameter. I haven't heard of any explosions
> in C# land, and it's been five years.
>
> Your proposal is closer to C#'s version than Dart's. In Dart, a named
> parameter cannot be called positionally:
>
>    foo({a, b}) {}
>    main() {
>      // This works:
>      foo(b: 1, a: 2);
>
>      // Error: 0 positional arguments expected, 2 found
>      foo(2, 1);
>    }
>
> In C#, a named parameter is only about the call site and has nothing to
> do with the function being called. A function you wrote for C# 1.1 and
> never modified can be called with named parameters in C# 4.0. You can
> still call these functions with positional-style parameters.
>
>> Changing the order when using the named parameter syntax is not legal:
>
> Why not?
>
> Let's look at languages with named parameters. Python: reorderable. C#:
> reorderable. Dart: reorderable. Scala: reorderable. Ada: reorderable.
>
> Given this trend, people will be confused if they can't reorder named
> parameters. The main benefit of not letting people reorder things is
> reducing the amount of work *you* need to do when creating this DIP (and
> the amount others need to do when implementing it).

No. The only reason why that is not allowed is to have a greater chance of the DIP being accepted. The language would be even more complicated if it was possible to reorder the arguments. It's a benefit for the users if the language is simpler.

> Document how it's supposed to handle optional parameters

It's already documented.

-- 
/Jacob Carlborg