June 07, 2019
On Friday, 7 June 2019 at 09:23:42 UTC, Walter Bright wrote:
> On 6/7/2019 1:07 AM, aliak wrote:
>> What makes i unnamed and the others named?
>
>   snoopy(t:t, i, s:s);
>               ^ note this is not i:i

Ah! The way it's called of course. I'm so used to working with swift that i forget that it can *also* be controlled client side :)
June 07, 2019
On Thursday, 6 June 2019 at 13:47:57 UTC, FeepingCreature wrote:
>
> [snip]
>
> 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.

Thanks for put it so clearly.

> 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.

I think skipping default arguments will a really simple and straightforward DIP on top of this. Especially given the recent revision of the DIP process.

I don't see how lacking that feature could be a dealbreaker.
June 07, 2019
On Friday, 7 June 2019 at 05:37:25 UTC, Jonathan Marler wrote:
> I think there are pros and cons to exposing all parameters names to all callers.

We already have this though.

> If I want to keep my parameters names private so that I can change them without breaking compatibility, I have no way to do it.

Actually, you could use a .di file. The parameter names are not in the function mangle (and even if they were, it could be handled, like the extern(objective-c) @selector thing), so you can call it one thing in your code and something else in the distributed interface file.

You could also use public names on the outside and immediately alias them to something else inside a function.

It is just, again, we *already have* the names exposed (and already have ways to ignore them). So it isn't taking something previously totally hidden and opening it.
June 07, 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.

Where were you during the last community review? :)

Last time literally _everyone_ is arguing against named parameters being opt-in, and that's why I removed the opt-in-ness (the @named attribute) from the DIP.

> It would be like if we suddenly disabled the "private" modifier and allowed everything to access private fields within structs and classes.

I don't think this is a fair comparison.
June 07, 2019
On Thursday, 6 June 2019 at 20:04:15 UTC, Walter Bright wrote:
> 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.

I don't necessarily see any problems with this proposal. (Also, I think this is a superset of my DIP). But I don't think what you have written here covers all of the nitty-gritty that could arise if your proposal is implemented.

I don't have a really strong example off the top of head, but I have a couple of small things that need clarification:

1. (Clearly function overloading is affected, but) is name mangling also affected?
2. What about declarations in .di files?
3. What about function declarations with parameter names different from the definition?

> 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.

There is at least on difference here: structs can have private members.
June 07, 2019
On 07.06.19 05:10, Jonathan Marler wrote:
> On Friday, 7 June 2019 at 02:51:16 UTC, Timon Gehr wrote:
>> On 07.06.19 01:36, Jonathan Marler wrote:
>>> On Thursday, 6 June 2019 at 23:08:56 UTC, Exil wrote:
>>>> On Thursday, 6 June 2019 at 22:35:31 UTC, Jonathan Marler wrote:
>>>>> On Thursday, 6 June 2019 at 20:25:32 UTC, Exil wrote:
>>>>>> [...]
>>>>>
>>>>> Yes I am making the same argument as for structs/classes. Structs and classes can "opt-in" and "opt-out" to exposing their fields.  Saying that all function parameter names should be exposed and coupled to the caller is like saying we shouldn't have private fields in structs and classes.
>>>>
>>>> That doesn't make any sense. To make a function parameter "private" that would mean the user wouldn't be able to pass in a value to it.
>>>
>>> That's not the meaning I proposed.  I proposed that public exposes the "name" of the function parameter.  You're "straw manning" again,
>>
>> No, he's just not arguing against the aspect of your idea that you think he is. You are the one setting up the straw man.
>>
> 
> He said "To make a function parameter 'private' that would mean the user wouldn't be able to pass in a value to it".  My idea had nothing to do with preventing callers from passing values to arguments, hence why he is straw manning me.
> ...

Reductio ad absurdum is not per se a straw man fallacy, even if you disagree with/misunderstand the reasoning/definitions/values that lead to the ridiculous conclusion.

>>>> The only benefit you get from having names be optional is that library maintainers can screw over their user base if they want to use the feature or not.
>>>
>>> Again, the benefit is Encapsulation.
>>
>> Well, let's look at the facts:
>>
>> - Parameter names are already exposed, and changing parameter names can already break third-party code:
>> https://dlang.org/phobos/std_traits.html#ParameterIdentifierTuple
>>
>> No "encapsulation" for you. (Whatever that's supposed to mean.)
>>
>> - It is possible to not name parameters (an alternative way is to use *.di files):
>>
>> import std.traits;
>> int add(int, int){
>>     return _param_0+_param_1;
>> }
>> void main(){
>>     assert(add(1,2)==3);
>> }
>>
>> I guess that's what you would call "encapsulation".
>>
>> I.e., if you want to not expose any parameter names, you have the means to do so. Let's call those two ways to declare parameters public and private. What named arguments allow you to do is to actually refer to the public parameters by name.
>>
>> If we had structs with public and private fields, there was no field access (e.f) syntax and you could only access public fields by index, would you also argue that this is a good thing, even if there was already a __trait to get the index of a field from its name and vice-versa?
> 
> Hmmm that's a good point, I suppose they are already exposed to the caller.  However, I believe private fields in structs/classes have the same problem.  You can still access those fields with some fancy reflection, but I don't think that means we should get rid of private fields just because we can still access them through reflection.  Do you?
I don't particularly care, because there are other ways to restrict your public interface. Anyway, there are other pertinent points. As I said before, the analogy to _private_ fields actually does not have a lot of merit. You don't make your fields private just to be able to rename them, but to be able to completely reorganize your implementation, removing some private fields and adding other ones. A key reason why you don't want to have private members accessible is because you might break some internal invariant. With parameters, there is no such concern, because they need to be accessible by definition, they are part of the interface. Your subsystems _need_ to be coupled at interfaces, you just want the interfaces to be small. More automated checking for consistency at interfaces is actually good. Checking for consistency of parameter and argument names might occasionally break compilation of code in superficial ways that are easily dealt with by changing the characters in some identifier, but it does not actually lead to the disadvantages you get with a poorly encapsulated system.

Also consider that a library author can always note in the documentation that parameter names are not guaranteed to be stable, and that hence it is on the user of the library to trade off better type checking against fewer compilation errors when updating the library. Note that a compilation failure is actually the best kind of failure you can get when updating library versions.
June 07, 2019
On Wednesday, 5 June 2019 at 15:41:08 UTC, Kagamin wrote:
> Remove the variadic functions section. That's a tuple parameter, not variadic, and should use (future) tuple syntax.

Are you suggesting we will be forced to call

    void func(Args...)(int, Args);

Like this:

    func(1, (1,2,3));

In the future?


June 07, 2019
On Thursday, 6 June 2019 at 20:04:15 UTC, Walter Bright wrote:
> 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
>

And how do you deal with:

    void func(Args...)(Args args);

?

June 07, 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:
>> [...]
>
> 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.
>
> [...]

See also: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4172.htm

The answer to objection #3 addresses your concern.
June 07, 2019
On Friday, 7 June 2019 at 14:13:42 UTC, Yuxuan Shui wrote:
> 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:
>>> [...]
>>
>> 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.
>>
>> [...]
>
> See also: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4172.htm
>
> The answer to objection #3 addresses your concern.

A good idea to get data like this. But I think what will happen if/when we enable named arguments is that there will be a spike in the number of changes to parameter names. The idea being that now that they are apart of the interface, we will want to normalize names for things like opCmp, opEquals, copy functions, one value operation functions, etc.

square(x: 10);
cube(num: 10);
quad(val: 10);

These would be examples of functions that don't benefit from named arguments, but because we've exposed the parameter names of every function, we've add a new burden to maintain/normalize these names for no benefit. At least, no benefit for these particular functions.

If we make it "opt-in", we only need to be concerned with functions that make their parameter names public, and when we make them public, we can normalize the parameter names at the same time knowing that we aren't breaking anything.