February 11, 2020
On Tuesday, 11 February 2020 at 09:27:52 UTC, Andrea Fontana wrote:
> On Tuesday, 11 February 2020 at 09:18:38 UTC, Paolo Invernizzi wrote:
>> On Monday, 10 February 2020 at 22:20:21 UTC, Adam D. Ruppe wrote:
>>
>>> In D, this is the most trivial type of breakage - the compiler tells you where the change is and can make a good guess as to what the fix is too and can suggest it.
>>>
>>
>>
>> That's true, but it's an hell when involving libraries: an external library author changes a parameter names, and break not only your codebase, that you can easily fix, but also other external libraries, and so on.
>>
>> It's a cascade process.
>
> If package dependencies are used correctly nothing is break :)
>
> Andrea

What I mean, is that multiple authors can be involved in the necessary fix: it's not a matter of find/replace on your own codebase.

Let's put It simple, and let's boil this down to essential: there's MORE probability of FUTURE breakage with named parameters, and that's a fact.



February 11, 2020
On Tuesday, 11 February 2020 at 09:29:22 UTC, Timon Gehr wrote:
> int troll(int ret){ return ret; }
>
> void main(){
>     wrapWithPrint!troll(2);
> }

lol, indeed. There can be downsides to inheriting random names :)
February 11, 2020
On Tuesday, 11 February 2020 at 09:46:35 UTC, Paolo Invernizzi wrote:
> Let's put It simple, and let's boil this down to essential: there's MORE probability of FUTURE breakage with named parameters, and that's a fact.

Only if you use the feature. That's part of the reason why I don't think you should be able to set a default of the middle argument. This just forces someone to use the feature if they want a default parameter. Neither C# nor Python allow you to set a default parameter in the middle without the rest that follow also having default values.

Other than that, if you don't want your code to break potentially from argument changes, then don't use named parameters.


February 11, 2020
On 2/10/20 2:38 PM, Manu wrote:
> I do an immense amount of generative meta; generate wrappers, shims,
> bindings etc, which wrap existing functions.
> When the parameter names become part of the API, it means any such
> meta must pay extra attention to properly mirror the parameter names,
> and it must also carefully mirror the default args from the function
> it's wrapping.
> While most of my code takes care to do this anyway, there are cases
> where it's unnecessary and inconvenient. Some tasks can be completed
> with a tool like:
> 
>    ReturnType!originalFunction wrapper(alias
> originalFunction)(Parameters!originalFunction args)
>    {
>      // special sauce...
>      return originalFunction(args);
>    }
> 
> It is possible to write many forms of glue this way. If we must mirror
> the argument names and default arguments, you must fall back into
> string mixin territory, and the code to emit the proper prototype is
> complex and intensive.
> In a named-arguments world, shim's like the one I showed above are no
> longer valid where calling code would use named arguments.

This has convinced me (along with reading the subsequent thread) that we shouldn't introduce named parameters until we can solve this problem.

Whether it be via Timon's suggestion of having template tuples capture named parameters or some other mechanism.

And the is(typeof(fn) P == __parameters) idea isn't the right approach either. It intercepts the parameter names based on what the *target* is, not on how it was *called*. Templates make decisions based on what they are given.

-Steve
February 11, 2020
On Tuesday, 11 February 2020 at 09:46:35 UTC, Paolo Invernizzi wrote:
> On Tuesday, 11 February 2020 at 09:27:52 UTC, Andrea Fontana wrote:
>> If package dependencies are used correctly nothing is break :)
>>
>> Andrea
>
> What I mean, is that multiple authors can be involved in the necessary fix: it's not a matter of find/replace on your own codebase.
>
> Let's put It simple, and let's boil this down to essential: there's MORE probability of FUTURE breakage with named parameters, and that's a fact.

Yes, precisely... I was a bit circumspect about named arguments (coming from the C world, I don't use them, and don't feel the need to), and I was agreeing with Jonathan point of view.

But I've changed my mind about it: I reckon naming things is quite important when writing a library. So that feature would make you think twice before naming a parameter, and care about how you name (and therefore design) things. So sure, it can break stuff, so that would probably be good if we could annotate parameter names with 'deprecated'.

And replacing the awkward 'Flag' template is a nice plus. Therefore I'm all for that DIP (and we can probably wait later for a design working with variadic arguments).
February 11, 2020
> On 2/10/2020 1:02 PM, Manu wrote:
>> Named arguments breaks this very important pattern:
> 
> Named arguments will not match to ... parameters, so it won't break existing code, it just won't compile if you write new code that tries that.

Just wanted to point out without muddying the feedback thread, that this response completely misses the point.

The point is to have a wrapper for origFun which behaves exactly as the original function, but does something special inside.

Saying you won't be able to call wrapper with named parameters is the actual point of the post. It would be good to have a response to the fact that it breaks the intention of perfect forwarding.

An example:

foo(a: 1, b:2);

Now I want to replace all calls to foo with a special wrapper that logs all calls.

alias foo = logCalls!(.foo);

foo(a: 1, b:2); // error, cannot use named parameters with tuples.

Is there a plan to mitigate this limitation?

-Steve
February 11, 2020
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.

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.)
February 11, 2020
On Tuesday, 11 February 2020 at 09:46:35 UTC, Paolo Invernizzi wrote:
> Let's put It simple, and let's boil this down to essential: there's MORE probability of FUTURE breakage with named parameters, and that's a fact.

That's true for every dip we approve, not only for named paramaters.

February 11, 2020
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! __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.

though wow id really like to have it work.
February 11, 2020
On Tuesday, 11 February 2020 at 14:05:08 UTC, Andrea Fontana wrote:
> On Tuesday, 11 February 2020 at 09:46:35 UTC, Paolo Invernizzi wrote:
>> Let's put It simple, and let's boil this down to essential: there's MORE probability of FUTURE breakage with named parameters, and that's a fact.
>
> That's true for every dip we approve, not only for named paramaters.

No, there could be language improvements introduced with breaking changes, like the final-by-default that I endlessly put on the table as an example, that turns D into a language that's more resilient to breaking changes, on the contrary of named parameters.