October 25, 2017
On Wednesday, 25 October 2017 at 07:46:49 UTC, Andrey wrote:
> good alternative, I already forgot about the power of structs after Java.

It would be a very good solution if we can init a struct using its named field. Something like:

struct S
{
  int a;
  int b;
  int c;
}

S test = { a:1, b:4; };

So:

void myFunc(S param);  =>   myFunc({a:1, b:3});

I know: you say that this has trouble with overloading:

void myFunc(S param);
void myFunc(T param);

But the same goes for this:
void f(float i) { writeln("float"); }
void f(double i) { writeln("double"); }
f(1);

And simply it won't compile. (for template arguments too)
You can solve this doing: f(1.0f); or f(1.0);

In the same way you can solve first problem calling:
myFunc({a:1, b:3}.to!S) or  myFunc(S{a:1, b:3}) or myFunc(cast(S){a:1, b:3}) or some other exotic syntax you want add to language, if needed (rarely, i guess).

And the same goes for:

auto blah = {a:1, b:2};

October 25, 2017
On Wednesday, 25 October 2017 at 08:09:52 UTC, Gary Willoughby wrote:
> On Tuesday, 24 October 2017 at 17:30:27 UTC, Andrey wrote:
>> Hello, why there are no named arguments for functions like, for example, in kotlin i.e.:
>>
>>> int sum(in int a, in int b) {
>>>     return a + b;
>>> }
>>>
>>> sum(a = 1, b = 2);
>
> This has been discussed to death:
>
> http://forum.dlang.org/post/n8024o$dlj$1@digitalmars.com
>
> and you can do it as a library so no need to go in the language:
>
> https://github.com/CyberShadow/ae/blob/master/utils/meta/args.d

Thanks for that link. Unaware of CyberShadow's work (which probably is of better quality) I just had a go:

```
void foo(int one, int two, double three, string four) {
    import std.stdio;
    writeln("one=", one, "; two=", two, "; three=", three, "; four=", four);
}

int first = 1;
void main()
{
    // Ordinary:
    foo(first, 2, 3.0, "4");    // Prints one=1; two=2; three=3; four=4
    // Named arguments:
    named!(foo, "four", "4",
                "two", 2,
                "one", first,
                "three", 3.0);  // idem
}

import std.traits;
auto named(alias F, args...)() if (isFunction!F) {
    import std.meta;

    alias names = Stride!(2, args[0..$]);
    alias values = Stride!(2, args[1..$]);

    bool cmp(alias valueA, alias valueB)() {
        import std.algorithm.searching;
        return countUntil([ParameterIdentifierTuple!F],
                          names[staticIndexOf!(valueA, values)]) <
               countUntil([ParameterIdentifierTuple!F],
                          names[staticIndexOf!(valueB, values)]);
    }

    return F(staticSort!(cmp, values));
}
```

Not battle tested, but it works here. There is a limitation that the variable "first" cannot be local, but people better at this stuff may be able to remove that.

Bastiaan.
October 25, 2017
On Wednesday, 25 October 2017 at 06:48:26 UTC, Jonathan M Davis wrote:
> On Wednesday, October 25, 2017 06:23:52 bauss via Digitalmars-d wrote:
>> [...]
>
> The issue I'm talking about is that if we had named arguments, and the names of the parameters in .di and .d files didn't match, and named arguments were used, then changing whether the .di file or .d file were used would break code. e.g.
>
> [...]

If you change function definitions you should provide fall-backs IMO and then deprecate the old function definition. Of course that's a world full of rainbows and unicorns, where people actually care about such things.
October 25, 2017
On Wednesday, October 25, 2017 13:56:51 bauss via Digitalmars-d wrote:
> On Wednesday, 25 October 2017 at 06:48:26 UTC, Jonathan M Davis
>
> wrote:
> > On Wednesday, October 25, 2017 06:23:52 bauss via Digitalmars-d
> >
> > wrote:
> >> [...]
> >
> > The issue I'm talking about is that if we had named arguments, and the names of the parameters in .di and .d files didn't match, and named arguments were used, then changing whether the .di file or .d file were used would break code. e.g.
> >
> > [...]
>
> If you change function definitions you should provide fall-backs IMO and then deprecate the old function definition. Of course that's a world full of rainbows and unicorns, where people actually care about such things.

Sure, but you don't have to provide fallbacks if you're just changing the implementation, and right now, the parameter names are part of the implementation, whereas with named arguments, they would be part of the API.

- Jonathan M Davis

October 25, 2017
On Wednesday, 25 October 2017 at 12:40:47 UTC, Bastiaan Veelo wrote:
> [snip]
>
> int first = 1;
> void main()
> {
>     // Ordinary:
>     foo(first, 2, 3.0, "4");    // Prints one=1; two=2; three=3; four=4
>     // Named arguments:
>     named!(foo, "four", "4",
>                 "two", 2,
>                 "one", first,
>                 "three", 3.0);  // idem
> }


You're passing the function arguments as template parameters. Usually you want them to be able to be passed at run-time.
October 25, 2017
On Wednesday, 25 October 2017 at 14:58:50 UTC, jmh530 wrote:
> On Wednesday, 25 October 2017 at 12:40:47 UTC, Bastiaan Veelo wrote:
>> [snip]
>>
>> int first = 1;
>> void main()
>> {
>>     // Ordinary:
>>     foo(first, 2, 3.0, "4");    // Prints one=1; two=2; three=3; four=4
>>     // Named arguments:
>>     named!(foo, "four", "4",
>>                 "two", 2,
>>                 "one", first,
>>                 "three", 3.0);  // idem
>> }
>
>
> You're passing the function arguments as template parameters. Usually you want them to be able to be passed at run-time.

That depends. It's a common pattern in D to pass them as template parameters, in fact most functionality in std.algorithm supports it.
October 25, 2017
On Wednesday, 25 October 2017 at 14:58:50 UTC, jmh530 wrote:
> On Wednesday, 25 October 2017 at 12:40:47 UTC, Bastiaan Veelo wrote:
>> [snip]
>>
>> int first = 1;
>> void main()
>> {
>>     // Ordinary:
>>     foo(first, 2, 3.0, "4");    // Prints one=1; two=2; three=3; four=4
>>     // Named arguments:
>>     named!(foo, "four", "4",
>>                 "two", 2,
>>                 "one", first,
>>                 "three", 3.0);  // idem
>> }
>
>
> You're passing the function arguments as template parameters. Usually you want them to be able to be passed at run-time.

Oops!
October 25, 2017
On Wednesday, 25 October 2017 at 10:32:19 UTC, Andrea Fontana wrote:
> On Wednesday, 25 October 2017 at 07:46:49 UTC, Andrey wrote:
>> [...]
>
> It would be a very good solution if we can init a struct using its named field. Something like:
>
> [...]

In case you're not already aware of it there's a DIPĀ in preparation just for that: https://github.com/dlang/DIPs/pull/71
October 25, 2017
On Wednesday, 25 October 2017 at 15:33:05 UTC, bauss wrote:
>
> That depends. It's a common pattern in D to pass them as template parameters, in fact most functionality in std.algorithm supports it.

std.algorithm has a lot of passing lambdas as template parameters, but not so much for parameters you would expect to be run-time parameters.

Consider count:
size_t count(alias pred = "a == b", Range, E)(Range haystack, E needle)
it's not
size_t count(alias pred = "a == b", Range haystack, E needle, Range, E)()
October 25, 2017
On Wednesday, 25 October 2017 at 16:40:52 UTC, jmh530 wrote:
> On Wednesday, 25 October 2017 at 15:33:05 UTC, bauss wrote:
>>
>> That depends. It's a common pattern in D to pass them as template parameters, in fact most functionality in std.algorithm supports it.
>
> std.algorithm has a lot of passing lambdas as template parameters, but not so much for parameters you would expect to be run-time parameters.
>
> Consider count:
> size_t count(alias pred = "a == b", Range, E)(Range haystack, E needle)
> it's not
> size_t count(alias pred = "a == b", Range haystack, E needle, Range, E)()

Oh yeah of course not like that