June 06, 2019
On Thursday, 6 June 2019 at 13:13:45 UTC, Exil wrote:
> On Wednesday, 5 June 2019 at 21:24:35 UTC, FeepingCreature wrote:
>> On Wednesday, 5 June 2019 at 15:25:52 UTC, Exil wrote:
>>> I also don't see anywhere that this wouldn't be allowed?
>>>
>>>    void fun( int a, int b );
>>>    fun( a: 0, 10 );
>>>
>>
>> Yes.
>>
> That wasn't a yes or no question...

Yes, this would be allowed in the spec as it stands.

> Wouldn't make sense if you couldn't access all members of a base class. A method is a member of a class. Also the spec is outdated and incorrect in a lot of aspects.

Since it's a virtual method, accessing it as a base class member shouldn't do anything, because it should result in the same vtable slot. You don't just access it as a base class member, you access it *as a static method reference*. This is nonsense.

> The DIP states that it doesn't prevent a future DIP from
> allowing reordering and default parameters. But if this DIP
> is implemented it will become extremely difficult to implement
> such a feature in the future. It needs to go into detail why
> this feature isn't being included. I feel like because this is
> "Lite" is not a sufficient answer. You only get one chance to
> implement a feature like this, once it is in, there is not going
> to be changing it. If something is going to be excluded it
> should have a valid reason behind why it is not included.

If you think this proposal would block later work on named arguments, this is probably a strong reason against it. My impression is that this is very much intended as a "foot in the door" for named arguments, to demonstrate that the sky will not fall if they are implemented. I agree that as a "named parameters for now and forevermore" it is disappointingly sparse. The lack of ability to skip default parameters seems particularly crippling. Personally, varying the order of parameters doesn't matter to me, so if that's the cost of getting named parameters I'd pay it happily. But I think the problem in general is that we have a variety of proposals, and people have argued for, or especially against, parts of those proposals almost independently. I don't think it's accurate to say that there's "camps" of proposals; rather, almost every part of named arguments seems to have people who strenuously disagree and think it'll make the language worse - but there's no obvious consensus or commonality.

This naturally makes it hard to craft a compromise. I believe that Named Arguments Lite is an attempt to guess which set of compromises will put off the least people while being acceptable to the most and delivering at least some value to everybody who wants at least some part of named arguments. For me, the lack of ability to skip default arguments is a dealbreaker, particularly if accepting this proposal would mean that it would be the face of named arguments in D forevermore, but if it was "this or literally nothing else ever" I'd be in favor. So I guess the question rests on whether if this is rejected, there'll be a "D Named Arguments Proper" after. And, uh, looking at "shared", that seems unlikely for at least several years. So to me the question is "this or nothing", and even though it doesn't solve the main usecase I'd want it for (verbose constructors, which *needs* the ability to skip default arguments), it is at least better than the alternative, which is nothing. Though of course any change that would leave the door open for skipping parameters would be welcome.
June 06, 2019
On Thursday, 6 June 2019 at 13:47:57 UTC, FeepingCreature wrote:
> On Thursday, 6 June 2019 at 13:13:45 UTC, Exil wrote:
>> On Wednesday, 5 June 2019 at 21:24:35 UTC, FeepingCreature wrote:
>>> On Wednesday, 5 June 2019 at 15:25:52 UTC, Exil wrote:
>>>> I also don't see anywhere that this wouldn't be allowed?
>>>>
>>>>    void fun( int a, int b );
>>>>    fun( a: 0, 10 );
>>>>
>>>
>>> Yes.
>>>
>> That wasn't a yes or no question...
>
> Yes, this would be allowed in the spec as it stands.

Bit of a nitpick here, I know other people that do the same thing.

If you do want to take it as a question, "This wouldn't be allowed?", answering "yes" means that the feature wouldn't be allowed in the spec. It is the inverse of the question "This would be allowed?", you answer "yes" to this question to have the meaning you intended. The question and it's inverse can't have the same meaning for the same answer.

>> Wouldn't make sense if you couldn't access all members of a base class. A method is a member of a class. Also the spec is outdated and incorrect in a lot of aspects.
>
> Since it's a virtual method, accessing it as a base class member shouldn't do anything, because it should result in the same vtable slot. You don't just access it as a base class member, you access it *as a static method reference*. This is nonsense.

It is not nonsense, if you have a chain of 3 class A -> B -> C and in C you need to call A's method over B's overriden. You do so using the same syntax. A.foo(). It would be worse if you have some code that you couldn't access and now you need some kind of a hack just to access it. Anyways this is getting off topic.

>> The DIP states that it doesn't prevent a future DIP from
>> allowing reordering and default parameters. But if this DIP
>> is implemented it will become extremely difficult to implement
>> such a feature in the future. It needs to go into detail why
>> this feature isn't being included. I feel like because this is
>> "Lite" is not a sufficient answer. You only get one chance to
>> implement a feature like this, once it is in, there is not going
>> to be changing it. If something is going to be excluded it
>> should have a valid reason behind why it is not included.
>
> If you think this proposal would block later work on named arguments, this is probably a strong reason against it. My impression is that this is very much intended as a "foot in the door" for named arguments, to demonstrate that the sky will not fall if they are implemented. I agree that as a "named parameters for now and forevermore" it is disappointingly sparse. The lack of ability to skip default parameters seems particularly crippling. Personally, varying the order of parameters doesn't matter to me, so if that's the cost of getting named parameters I'd pay it happily. But I think the problem in general is that we have a variety of proposals, and people have argued for, or especially against, parts of those proposals almost independently. I don't think it's accurate to say that there's "camps" of proposals; rather, almost every part of named arguments seems to have people who strenuously disagree and think it'll make the language worse - but there's no obvious consensus or commonality.
>
> This naturally makes it hard to craft a compromise. I believe that Named Arguments Lite is an attempt to guess which set of compromises will put off the least people while being acceptable to the most and delivering at least some value to everybody who wants at least some part of named arguments. For me, the lack of ability to skip default arguments is a dealbreaker, particularly if accepting this proposal would mean that it would be the face of named arguments in D forevermore, but if it was "this or literally nothing else ever" I'd be in favor. So I guess the question rests on whether if this is rejected, there'll be a "D Named Arguments Proper" after. And, uh, looking at "shared", that seems unlikely for at least several years. So to me the question is "this or nothing", and even though it doesn't solve the main usecase I'd want it for (verbose constructors, which *needs* the ability to skip default arguments), it is at least better than the alternative, which is nothing. Though of course any change that would leave the door open for skipping parameters would be welcome.

Was there even anyone arguing against allowing named parameters to be used with default parameters? I've only seen people asking for the feature, like yourself. The people arguing against the feature are those that simply don't want the feature at all because they don't want to have to worry about renaming function parameters. That's the only argument I've seen. I haven't heard one against allow default parameters to be used as they were intended, specifically.
June 06, 2019
On Thursday, 6 June 2019 at 14:18:14 UTC, Exil wrote:
> On Thursday, 6 June 2019 at 13:47:57 UTC, FeepingCreature wrote:
>> On Thursday, 6 June 2019 at 13:13:45 UTC, Exil wrote:
>>> On Wednesday, 5 June 2019 at 21:24:35 UTC, FeepingCreature wrote:
>>>> On Wednesday, 5 June 2019 at 15:25:52 UTC, Exil wrote:
>>>>> I also don't see anywhere that this wouldn't be allowed?
>>>>
>>>> Yes.
>>>>
>>> That wasn't a yes or no question...
>>
>> Yes, this would be allowed in the spec as it stands.
>
> Bit of a nitpick here, I know other people that do the same thing.
>
> If you do want to take it as a question, "This wouldn't be allowed?", answering "yes" means that the feature wouldn't be allowed in the spec. It is the inverse of the question "This would be allowed?", you answer "yes" to this question to have the meaning you intended. The question and it's inverse can't have the same meaning for the same answer.
>

Nitpicking right back: what you said was "I don't see anywhere that this wouldn't be allowed". So there's a double negation in play; my "yes" was affirming that you don't see it ... because it isn't there, because it would be allowed.

> It is not nonsense, if you have a chain of 3 class A -> B -> C
> and in C you need to call > A's method over B's overriden.

Right, the problem is that you can have class A -> B -> C, and then you have module D with a void foo(), and in void foo() you have a class of C and you want to call A's method. That currently works, but it shouldn't, because it overrides C's authority to redefine methods from the superclass and makes code very hard to follow, because you can't tell which method was called when foo() was invoked from looking at the type of the object, you have to look at the callsite too.

You can end up with code like

class A
{
  void foo() { bar(); }
  void bar() { }
}

class B : A
{
  void foo() { bar(); }
  void bar() { }
}

B b = new B;
b.A.foo();

So in B.bar(), you cannot assume you were even called from B.foo()! There's just no reason to permit shenanigans of this degree of inanity.

> Was there even anyone arguing against allowing named parameters to be used with default parameters?

Then I don't see any reason to include in this spec concessions to people who would disagree with the spec regardless. I don't think there's an argument on the merits to not permit skipping default parameters.

June 06, 2019
On Wednesday, 5 June 2019 at 13:03:26 UTC, Mike Parker wrote:
> This is the feedback thread for the second round of Community Review for DIP 1019, "Named Arguments Lite":
>
> https://github.com/dlang/DIPs/blob/9c9cc39246de4c449fe1e6cb6b27f7e426ff1eb9/DIPs/DIP1019.md
>
> All review-related feedback on and discussion of the DIP should occur in this thread. The review period will end at 11:59 PM ET on June 19, or when I make a post declaring it complete.
>
> At the end of Round 2, if further review is deemed necessary, the DIP will be scheduled for another round of Community Review. Otherwise, it will be queued for the Final Review and Formal Assessment.
>
> I have recently made minor revisions to the DIP process and implemented guidelines for reviewers. Anyone intending to post feedback in this thread is expected to be familiar with the reviewer guidelines:
>
> https://github.com/dlang/DIPs/blob/master/docs/guidelines-reviewers.md
>
> I also recommend that everyone read my recent blog post on the topic:
>
> https://dlang.org/blog/2019/06/04/revisions-to-the-dip-process/
>
> To be clear, I will be moving (copying, deleting, and pasting in a new thread) posts that do not adhere to the reviewer guidelines. Please direct any comments on the new documentation to a new thread or to personal email. Please, let's keep the review discussion on topic.
>
> Thanks in advance to all who participate.

There's a big issue with this DIP.  It immediately allows any function call to increase coupling with the corresponding function definition with no way to disable it.  I agree that named parameters can increase readability, however, in the majority of cases they actually just add extra noise, i.e.

add(int x, int y) // parameter names not helpful
square(float x)  // parameter names not helpful
write(string s) // parameter names not helpful
void opEquals(T)(ref T other) // parameter names not helpful

Of course there are many cases where named arguments are very helpful (the DIP provides some examples of this).

However, if you suddenly allow every caller to specify the argument names to any parameter on any function, you've added a whole new set of dependencies between every function and its callers.  A layer of protection/encapsulation has been completely removed.  It would be like if we suddenly disabled the "private" modifier and allowed everything to access private fields within structs and classes.

Languages like python that uses kwargs don't expose the names of all parameters.  They are able to pick and choose which parameters should be named.  This allows them to keep that layer of protection/encapsulation for the parameters where the name doesn't matter to the caller, just like when you have private fields where the name doesn't matter to an outside component.  D should follow this pattern as it has been successful in other languages and the alternative has too much disadvantage.  Allowing a parameter to be named at the call-site should be an "opt-in" feature done at the function definition, so as not to expose the names of all the other parameters that don't make sense to expose to the caller.

June 06, 2019
On Thursday, 6 June 2019 at 19:17:38 UTC, Jonathan Marler wrote:
> On Wednesday, 5 June 2019 at 13:03:26 UTC, Mike Parker wrote:
>> This is the feedback thread for the second round of Community Review for DIP 1019, "Named Arguments Lite":
>>
>> https://github.com/dlang/DIPs/blob/9c9cc39246de4c449fe1e6cb6b27f7e426ff1eb9/DIPs/DIP1019.md
>>
>> All review-related feedback on and discussion of the DIP should occur in this thread. The review period will end at 11:59 PM ET on June 19, or when I make a post declaring it complete.
>>
>> At the end of Round 2, if further review is deemed necessary, the DIP will be scheduled for another round of Community Review. Otherwise, it will be queued for the Final Review and Formal Assessment.
>>
>> I have recently made minor revisions to the DIP process and implemented guidelines for reviewers. Anyone intending to post feedback in this thread is expected to be familiar with the reviewer guidelines:
>>
>> https://github.com/dlang/DIPs/blob/master/docs/guidelines-reviewers.md
>>
>> I also recommend that everyone read my recent blog post on the topic:
>>
>> https://dlang.org/blog/2019/06/04/revisions-to-the-dip-process/
>>
>> To be clear, I will be moving (copying, deleting, and pasting in a new thread) posts that do not adhere to the reviewer guidelines. Please direct any comments on the new documentation to a new thread or to personal email. Please, let's keep the review discussion on topic.
>>
>> Thanks in advance to all who participate.
>
> There's a big issue with this DIP.  It immediately allows any function call to increase coupling with the corresponding function definition with no way to disable it.  I agree that named parameters can increase readability, however, in the majority of cases they actually just add extra noise, i.e.
>
> add(int x, int y) // parameter names not helpful
> square(float x)  // parameter names not helpful
> write(string s) // parameter names not helpful
> void opEquals(T)(ref T other) // parameter names not helpful
>
> Of course there are many cases where named arguments are very helpful (the DIP provides some examples of this).
>
> However, if you suddenly allow every caller to specify the argument names to any parameter on any function, you've added a whole new set of dependencies between every function and its callers.  A layer of protection/encapsulation has been completely removed.  It would be like if we suddenly disabled the "private" modifier and allowed everything to access private fields within structs and classes.
>
> Languages like python that uses kwargs don't expose the names of all parameters.  They are able to pick and choose which parameters should be named.  This allows them to keep that layer of protection/encapsulation for the parameters where the name doesn't matter to the caller, just like when you have private fields where the name doesn't matter to an outside component.  D should follow this pattern as it has been successful in other languages and the alternative has too much disadvantage.  Allowing a parameter to be named at the call-site should be an "opt-in" feature done at the function definition, so as not to expose the names of all the other parameters that don't make sense to expose to the caller.

By the way, I like what the DIP is trying to do, where it is trying to enable named parameters using the "least common denominator".   It attempts to do as little as possible to increase the likelihood of acceptance and leaves room for future improvements to address things like re-ordering/omission of default parameters, features which may or may not be justified but shouldn't keep us from having named parameters.

However, the way in which it was designed where it suddenly exposes the parameter names of all functions to all callers is not what we want.  I think the "least common denominator" is to provide some way for the function definition to distinguish between named and un-named parameters. Something like this:

void foo(int a, int b, int c, alias int d, int e, int f)
             ^                         ^
  unnamed parameters (left of alias)   named parameters (right of alias)

foo(1, 2, 3, d:4, e:5, f:6)

June 06, 2019
On Thursday, 6 June 2019 at 19:30:36 UTC, Jonathan Marler wrote:
> On Thursday, 6 June 2019 at 19:17:38 UTC, Jonathan Marler wrote:
>> [...]
>
> By the way, I like what the DIP is trying to do, where it is trying to enable named parameters using the "least common denominator".   It attempts to do as little as possible to increase the likelihood of acceptance and leaves room for future improvements to address things like re-ordering/omission of default parameters, features which may or may not be justified but shouldn't keep us from having named parameters.
>
> However, the way in which it was designed where it suddenly exposes the parameter names of all functions to all callers is not what we want.  I think the "least common denominator" is to provide some way for the function definition to distinguish between named and un-named parameters. Something like this:
>
> void foo(int a, int b, int c, alias int d, int e, int f)
>              ^                         ^
>   unnamed parameters (left of alias)   named parameters (right of alias)
>
> foo(1, 2, 3, d:4, e:5, f:6)

One more thought, probably should be `public` instead of `alias` to enabled named parameters:

void drawRect(public int x, int y, int width, int height);

drawRect(x: 0, y: 0, width: 1, height: 1);



void calculateProduct(int[] values, public int multipler, public bool goFast, Allocator* allocator);

calculateProduct(value, multiplier: 7, goFast: false, allocator: null);
June 06, 2019
On Thursday, 6 June 2019 at 19:17:38 UTC, Jonathan Marler wrote:
>
> There's a big issue with this DIP.  It immediately allows any function call to increase coupling with the corresponding function definition with no way to disable it.

I just want to explicitly note that increasing coupling between the call site and the function definition is the entire point of named parameters.

June 06, 2019
On Thursday, 6 June 2019 at 19:50:09 UTC, FeepingCreature wrote:
> On Thursday, 6 June 2019 at 19:17:38 UTC, Jonathan Marler wrote:
>>
>> There's a big issue with this DIP.  It immediately allows any function call to increase coupling with the corresponding function definition with no way to disable it.
>
> I just want to explicitly note that increasing coupling between the call site and the function definition is the entire point of named parameters.

Correct.  But you don't want to increase everywhere with no way to disable it.  Parameters names have been completely private from the caller for the life of D, and you suddenly expose ALL OF THEM.  What's worse is unnamed parameters are preferred in the majority of cases, so you're increasing coupling for EVERY case to help the rare cases where it you actually want it.

June 06, 2019
On Thursday, 6 June 2019 at 19:17:38 UTC, Jonathan Marler wrote:
> On Wednesday, 5 June 2019 at 13:03:26 UTC, Mike Parker wrote:
>> This is the feedback thread for the second round of Community Review for DIP 1019, "Named Arguments Lite":
>>
>> https://github.com/dlang/DIPs/blob/9c9cc39246de4c449fe1e6cb6b27f7e426ff1eb9/DIPs/DIP1019.md
>>
>> All review-related feedback on and discussion of the DIP should occur in this thread. The review period will end at 11:59 PM ET on June 19, or when I make a post declaring it complete.
>>
>> At the end of Round 2, if further review is deemed necessary, the DIP will be scheduled for another round of Community Review. Otherwise, it will be queued for the Final Review and Formal Assessment.
>>
>> I have recently made minor revisions to the DIP process and implemented guidelines for reviewers. Anyone intending to post feedback in this thread is expected to be familiar with the reviewer guidelines:
>>
>> https://github.com/dlang/DIPs/blob/master/docs/guidelines-reviewers.md
>>
>> I also recommend that everyone read my recent blog post on the topic:
>>
>> https://dlang.org/blog/2019/06/04/revisions-to-the-dip-process/
>>
>> To be clear, I will be moving (copying, deleting, and pasting in a new thread) posts that do not adhere to the reviewer guidelines. Please direct any comments on the new documentation to a new thread or to personal email. Please, let's keep the review discussion on topic.
>>
>> Thanks in advance to all who participate.
>
> There's a big issue with this DIP.  It immediately allows any function call to increase coupling with the corresponding function definition with no way to disable it.  I agree that named parameters can increase readability, however, in the majority of cases they actually just add extra noise, i.e.
>
> add(int x, int y) // parameter names not helpful
> square(float x)  // parameter names not helpful
> write(string s) // parameter names not helpful
> void opEquals(T)(ref T other) // parameter names not helpful
>
> Of course there are many cases where named arguments are very helpful (the DIP provides some examples of this).
>
> However, if you suddenly allow every caller to specify the argument names to any parameter on any function, you've added a whole new set of dependencies between every function and its callers.  A layer of protection/encapsulation has been completely removed.  It would be like if we suddenly disabled the "private" modifier and allowed everything to access private fields within structs and classes.
>
> Languages like python that uses kwargs don't expose the names of all parameters.  They are able to pick and choose which parameters should be named.  This allows them to keep that layer of protection/encapsulation for the parameters where the name doesn't matter to the caller, just like when you have private fields where the name doesn't matter to an outside component.  D should follow this pattern as it has been successful in other languages and the alternative has too much disadvantage.  Allowing a parameter to be named at the call-site should be an "opt-in" feature done at the function definition, so as not to expose the names of all the other parameters that don't make sense to expose to the caller.

This has been brought up in the discussion regarding named arguments for DIP1020 (more specifically the @named attribute) and so far I am not convinced that this is an issue that needs to be address, and found it be be overblown given that we have powerful rename tools at this day of age.

Having it "opt-in" have it own downsides as the users have to request library developers to add the capability to their libraries. Among many other issues that were brought up and discuss with "opt-in"ing DIP1020.

Alex
June 06, 2019
I'll reiterate what I wrote for DIP1020 https://digitalmars.com/d/archives/digitalmars/D/DIP_1020--Named_Parameters--Community_Review_Round_1_325299.html#N325627

---

Here's a much simpler proposal, based on the recognition that D already has
named parameters:

   https://dlang.org/spec/struct.html#static_struct_init

and related:

   https://dlang.org/spec/hash-map.html#static_initialization
   https://dlang.org/spec/arrays.html#static-init-static

The only additional syntax would be allowing the equivalent of
https://dlang.org/spec/hash-map.html#static_initialization in the argument
list.
Assignment of arguments to parameters would work the same way as assignments to
fields.

As for the semantics, given this constraint, nothing needs to be invented, just
discovered as necessary behavior. Consider:

    void snoopy(T t, int i, S s);     // A
    void snoopy(S s, int i = 0; T t); // B

and calling it:

    S s; T t; int i;
    snoopy(t, i, s); // A
    snoopy(s, i, t); // B
    snoopy(s, t); // error, neither A nor B match
    snoopy(t, s); // error, neither A nor B match
    snoopy(s:s, t:t, i:i); // error, ambiguous
    snoopy(s:s, t:t); // B
    snoopy(t:t, s:s); // B
    snoopy(t:t, i, s:s); // A
    snoopy(s:s, t:t, i); // A

I.e. function resolution is done by constructing an argument list separately
for
each function before testing it for matching. Of course, if the parameter
name(s) don't match, the function doesn't match. If a parameter has no
corresponding argument, and no default value, then the function doesn't match.

I don't see much point in requiring the names, preventing use of names, nor
aliasing them. This has never been an issue for struct initializers.

One nice thing about this is the { } struct initialization syntax can be
deprecated, as S(a:1, b:2) can replace it, and would be interchangeable with
constructor syntax, making for a nice unification. (Like was done for array
initialization.)

One issue would be order of evaluation: would the arguments be evaluated in the
lexical order of the arguments, or the lexical order of the parameters?

Rationale:

Although this supports reordering, the real reason for naming is so one can
have
a function with a longish list of parameters, each with a reasonable default,
and the user need only supply the arguments that matter for his use case. This
is much more flexible than the current method of putting all the defaults at
the
end of the parameter list, and defaulting one means all the rest get defaulted.

A secondary reason is (again) for a longish list of parameters, when the user
finds himself counting parameters to ensure they line up, then named parameters
can be most helpful.