February 11, 2020
On 2/11/20 8:56 AM, Adam D. Ruppe wrote:
> On Tuesday, 11 February 2020 at 09:02:03 UTC, Timon Gehr wrote:
>> What if fn is a template?
> 
> Then, as I'm sure you already know, it won't work. It needs an instantiation to wrap in this style. Same with Manu's code though so we've lost nothing.

Manu's example doesn't work, but this would (and I use this all the time):

auto wrapper(alias originalFunction, T...)(T args) if (...) // makes sure we can call the function
{
    return originalFunction(args);
}

> Can be slightly annoying with stuff like `to!int`, you'd have to `wrap!(to!it)...`
> 
> A generic forwarder would be variadic and thus this DIP doesn't apply to it regardless. (Though, in a previous review on github for this I proposed a way to handle that - make a variadic template with named params form an anonymous struct that the receiving template can process. Similar to Python's kwargs I'm told. Got pushback and I decided to table it, even though it would provide a lot of cool flexibility so hoping we can come back to it later.)

What if fn has 10 different overloads? You have to provide all of them. Where as a template forwarder as above just works.

I think we need to solve this problem in a "just works" way before having named parameters.

-Steve
February 11, 2020
On Tuesday, 11 February 2020 at 09:15:05 UTC, Paolo Invernizzi wrote:
> On Monday, 10 February 2020 at 21:29:41 UTC, 12345swordy wrote:
>
>> Yes, I have encounter the "API breakage" counter argument in other threads already. Still not convinced that it is a big issue as they make it out to be.
>
> I don't know since when you are around in D-land, but I'm here since pre-1.0. Not ad hominem, but believe me, I think it's difficult to understand the immane efforts to convince the leadership that breakage for a solid reason is not an evil thing.
>
> The pendulum is waving between "breakage is not even taken in account" to "let's introduce more ways to have MORE breakage opportunity in the future".
>
> Maybe it's not a "bit issue" for someone, Walter included, but that's non sense, plain and simple.
>
> Until I will see a shift from 'virtual by default' to 'final by default' mentality, aka let's try to reduce FUTURE opportunity for breakage, I will push toward that direction.
>
> /P
Then use cpp if you hate future code breakage that much. The appeal of d to me is that it is not afraid to break code if it turns out to be a bad idea or that the improvements outweigh the breakage.

-Alex

February 11, 2020
On Tuesday, 11 February 2020 at 14:22:48 UTC, 12345swordy wrote:

> Then use cpp if you hate future code breakage that much.

I don't go down that rabbit hole ... I've seen it too many times here.

I think I've exposed my complains on named parameters enough, and I think in a clear manner, so I will stop arguing here. But, as usual, I'm listening to argumentation, as I try to discuss to understand better a topic


February 11, 2020
On 2/11/20 9:07 AM, Adam D. Ruppe wrote:
> On Tuesday, 11 February 2020 at 13:52:35 UTC, Steven Schveighoffer wrote:
>> Is there a plan to mitigate this limitation?
> 
> I wrote about this in github comments when the dip pr was first opened:
> 
> https://github.com/dlang/DIPs/pull/168#discussion_r324481363
> 
> lol actually you were the person to push back hardest! 

ha, I just pushed back on the idea of a custom struct coming in and the template having to deal with that in a special way ;)

But my thoughts have evolved on the importance of this. I think it makes the DIP not worth it if we can't capture those calls properly.

Note also: if the template parameters names are part of the tuple type, and therefore part of the template instantiation, we have an actual path to deprecations as well:

Date makeDate(int year, int month, int day) {...}

deprecated("Use better names please")
auto makeDate(T...)(T args) if (containsArgName!("a", T) || containsArgName!("b", T) || containsArgName!("c", T))
{
   auto makeDateImpl(int a, int b, int c)
   {
       // remove names
       return .makeDate(a, b, c);
   }
   return makeDateImpl(args);
}

> __traits(identifier) on the template param is a solid possibility, and the other push back is maybe making it opt-in... but with your __traits(identifier) add on.... no need for my weird struct thingy.
> 
> So basically the template variadic params would then work identically to the __parameters result we already have (probably including the slice technique lol). There's precedent!
> 
> That should absolutely work. And could be done right now to solve this in full - with the names being part of the variadic tuple it would forward to calls as well. I like it a lot.
> 
> But I still think this DIP as-is is an OK addition without it. We can always remove the T... limitation later as well.

I think while it doesn't break currently existing code, it breaks the *intention* of code. Something that intends to be a perfect forward of an API can no longer EVER claim that. Manu is right, a whole lot of code out there exists solely to massage APIs, adding one nuance here or there.

-Steve
February 11, 2020
On Tuesday, 11 February 2020 at 14:31:51 UTC, Paolo Invernizzi wrote:
> On Tuesday, 11 February 2020 at 14:22:48 UTC, 12345swordy wrote:
>
>> Then use cpp if you hate future code breakage that much.
>
> I don't go down that rabbit hole ... I've seen it too many times here.

What rabbit hole are you talking about here!? The cpp committee have religious like zeal when it comes to backwards compatibility. You want d to have that mentality as well?

-Alex
February 11, 2020
On Tuesday, 11 February 2020 at 14:22:30 UTC, Steven Schveighoffer wrote:
> Manu's example doesn't work, but this would (and I use this all the time):
>
> auto wrapper(alias originalFunction, T...)(T args) if (...) //

Yeah, I use that a lot too.

> What if fn has 10 different overloads?

static foreach(overload; __traits(getOverloads, item, fun))
static if(is(typeof(overload) Params == __parameters))
auto wrap(Params p) {
     return overload(p);
}


Which has advantages over the T... in terms of error messages and future reflection. Also works in interfaces and similar.

So I agree with you that the names in variadics would be super cool for lots of reasons. I'm meh on if it is *required* but I certainly do prefer it.

Just still knowing these techniques are useful anyway so I take any chance to educate :)
February 11, 2020
On Tuesday, 11 February 2020 at 14:45:30 UTC, 12345swordy wrote:
> On Tuesday, 11 February 2020 at 14:31:51 UTC, Paolo Invernizzi wrote:
>> On Tuesday, 11 February 2020 at 14:22:48 UTC, 12345swordy wrote:
>>
>>> Then use cpp if you hate future code breakage that much.
>>
>> I don't go down that rabbit hole ... I've seen it too many times here.
>
> What rabbit hole are you talking about here!? The cpp committee have religious like zeal when it comes to backwards compatibility. You want d to have that mentality as well?
>
> -Alex

Probably I'm not able to explain myself clearly, so my fault ... let's try in this way.

- I'm not against changing D language specifications or Phobos with breaking changes, on the contrary, I'm an historical baker of doing it also with _major_ breaking changes, in times where talking about "breaking customer code in ANY way" was an heresy :-P

- Stated that, and coming back to named arguments, I prefer a language that encourage writing code that's difficult to break: virtual-by-default, for example, is against that principle. You should "explicitly" mark the methods that are parts of the API with virtual, turning encapsulation the default, and not the way round.

- The fact that fields _names_ are already part of the API is _not_ an excuse to add more stuff like that, with named parameters. The "he is doing wrong, so I can do wrong as well" is not an argumentation (and add to that "I've never had complains on that in other languages")

My reasoning is that, since months ago:

a) breaking user codebase, in any way, was BAD
b) so, a language feature that try to minimise (a) is GOOD
c) but now, we want to improve the language, so we can _sometime_ go against rule (a)
...
why rule (b) is not longer valid today? what is the _strong_ reason for turning D in a language _less_ robust to code refactories, encouraging a small and encapsulated API?

please, be sure to reply only if the first part of the post is clear enough ... :-)



February 11, 2020
On Tuesday, 11 February 2020 at 15:05:48 UTC, Paolo Invernizzi wrote:
> On Tuesday, 11 February 2020 at 14:45:30 UTC, 12345swordy wrote:
>> [...]
>
> Probably I'm not able to explain myself clearly, so my fault ... let's try in this way.
>
> [...]

Then don't rename the arguments at all if you don't want to break userspace. Same principle goes to renaming functions.

-Alex
February 11, 2020
On Sunday, 9 February 2020 at 20:59:52 UTC, Walter Bright wrote:
> On 2/9/2020 11:51 AM, Arine wrote:
>> struct A {
>>     int foo;
>> }
>> 
>> struct A {
>>      int bar; // renamed from foo
>>      deprecated alias foo = bar;
>> };
>> 
>> 
>> False equivalency, you have many tools at your disposal to deal with this for structs.
>
>
> C has it, too. Never heard a single complaint about it, either.
>
> https://en.cppreference.com/w/c/language/struct_initialization

struct A {
    int foo;
};

struct A {
    union {
        int foo;
        int bar; // renamed to bar
    };
};


struct A a = { .foo = 10 };

False equivalency, you have some tools at your disposal to deal with this for structs in C.

February 11, 2020
On Tuesday, 11 February 2020 at 15:10:35 UTC, 12345swordy wrote:
> On Tuesday, 11 February 2020 at 15:05:48 UTC, Paolo Invernizzi wrote:
>> On Tuesday, 11 February 2020 at 14:45:30 UTC, 12345swordy wrote:
>>> [...]
>>
>> Probably I'm not able to explain myself clearly, so my fault ... let's try in this way.
>>
>> [...]
>
> Then don't rename the arguments at all if you don't want to break userspace. Same principle goes to renaming functions.
>
> -Alex

That's exactly the point.

If you don't change anything, you break anything.

The more you _can_ change _without_ breaking other code is proper encapsulation, and with this DIP the amount of things that you _can't_ change is just increasing. Named arguments _enlarge_ the amount of code that you are exposing and that you _can't_ change without breaking someone else code.