DIP 1019--Named Arguments Lite--Community Review Round 2

Jonathan Marler johnnymarler at gmail.com
Fri Jun 7 03:52:24 UTC 2019


On Friday, 7 June 2019 at 02:44:19 UTC, Exil wrote:
> On Thursday, 6 June 2019 at 23:36:11 UTC, 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:
>>>>> On Thursday, 6 June 2019 at 20:10:06 UTC, Jonathan Marler 
>>>>> wrote:
>>>>>> Far to high of a cost just to allow some cases to be more 
>>>>>> readable.  However, if you make it opt-in, then you don't 
>>>>>> have to pay that cost for EVERY function, you only 
>>>>>> increase coupling in the cases that make sense.
>>>>>
>>>>> Making it optional makes it useless. Name the programming 
>>>>> languages that implement named parameters this way, and 
>>>>> I'll give a giant list of ones that don't. You can make 
>>>>> this exact argument for basically structs and everything 
>>>>> else.
>>>>
>>>> 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, please look that one up.  Understand what I'm 
>> saying before you respond.
>
> It's what private currently means. You are misunderstanding 
> what I am saying and throwing around strawman like it applies. 
> Encapsulation/private/public do not relate at all to what you 
> are suggesting.

I suggested that we could re-use the `public` keyword to allow a 
function to expose their parameter names to the caller.  It works 
because `public` currently has no meaning when you apply it to 
function parameters.  But you seem to be assigning the `private` 
modifier a meaning to function parameters that doesn't exist and 
that I didn't suggest, hence you are straw-manning my idea.

And the reason why this is "encapsulation" is because you are 
"encapsulating" the names of parameters from the caller, meaning 
that the library is free to change them without breaking 
compatibility.  Just like a library owner knows they can change 
their private field names without breaking compatibility with 
their library.

>
>>> Cause it doesn't make sense, not one wants to deal with that 
>>> address complexity because it provides zero benefit.
>>
>> Encapsulation = Zero Benefit?
>>
>> Well I can see we're not going to agree here :)
>
> This is not encapsulation. You are conflating the two. Talk 
> about strawman...

"conflating the two"?  Conflating encapsulation and what else?

Encapsulation is the only point I'm making here.

>
>>>>> When you use a library you are at the mercy of it's owner. 
>>>>> I've seen some people maintain an API that just literally 
>>>>> changed the style so basically every single line that used 
>>>>> that API now had to be updated.
>>>>
>>>> Even more reason not expose all the parameter names of all 
>>>> the functions in their library.  If the library owner 
>>>> changes any of their parameters names, they have broken 
>>>> compatibility with their library. This increases the 
>>>> opportunity for breakage dramatically.  That's the power and 
>>>> benefit of encapsulation, being able to change the internals 
>>>> without breaking your external facing API.
>>>
>>> That power is entirely depending on the person writing it. If 
>>> the maintainer wants to keep backwards compatibility with 
>>> named arguments it is very easy to do so. This is NOT 
>>> encapsulation, you can still access parameters. Making it 
>>> optional won't make maintainers be good maintainers, it will 
>>> just make the users suffer and avoid the feature for its 
>>> uselessness.
>>>
>>
>> You seem to be confusing what I said.  I didn't say the 
>> parameters are encapsulated...that doesn't make any sense.  
>> I'm talking about encapsulating the 'names' of the parameters.
>>  I think once you understand the distinction you'll see you're 
>> response here doesn't make much sense.
>
> And you are going on and on about encapsulation... I understand 
> what you are saying. That is not encapsulation, and what you 
> are proposing is not useful. It prevents a useful feature from 
> being used, if API maintainers don't want to maintain it, then 
> they don't have to. Just like everything else. But then no one 
> will use their API, and/or people will complain and it will be 
> fixed.

There's an expression for what I just read in this last 
paragraph.  "Talking out of both sides of your mouth". You said 
"This is not encapsulation" and then immediately afterwards said 
that if an API maintainer doesn't maintain this feature, then it 
will break their API and users won't use it.

If you can't understand why you contradicted yourself here, 
there's really nothing I can do.

>
>>>>> There's already enough attributes, we shouldn't be adding 
>>>>> more needlessly. I don't think this is a good enough reason 
>>>>> to.
>>>>
>>>> I didn't say we should add an attribute.  You're now 
>>>> demonstrating the "straw man fallacy" 
>>>> (https://en.wikipedia.org/wiki/Straw_man).
>>>
>>> What the, this isn't even the main argument and your pulling 
>>> that card? Come on now. I would be interested in hearing how 
>>> you will mark one function as optional and another as not 
>>> optional though. Someone suggested @named, I have yet to hear 
>>> anything better from you.
>>
>>
>> You just need a way to distinguish named from unnamed.  Opt-in 
>> and Opt out.  You could do so by putting all your named 
>> arguments in a struct and supporting some caller syntax to 
>> expand arguments into that struct.  You could use tuples, you 
>> could use a special type wrapper. And yes, you could use an 
>> attribute like "public", but you don't have too is the point.
>
> Those all sound like terrible ideas. I need an extra struct to 
> be able to use named and unnamed functions? So now named 
> parameters dictate the design? I can only imagine the 
> additional problems this would add. A special type wrapper 
> might be worse than an extra attribute.
>
>> I'm just weighing the pros and cons here.  I see a big con to 
>> enabling this by default for every function in D.  I see a 
>> small benefit from the feature altogether, as it's only useful 
>> for a small percentage of functions.
>
> It doesn't matter what percentage. That's the thing, you might 
> say this section of is more important and should use named 
> parameters. But I disagree, and I think this other section 
> should have named parameters. But you are the library 
> maintainer, so you make your choice and you chose to ignore 
> mine. Now I use your library and I am restricted to which 
> functions I can use a language feature on. I can't use the 
> language feature where I want to because of the maintainer's 
> opinion.
>
> struct A {
> private:
>     int a;
> }
>
>  A a;
>  a.a = 10; // error can't do it
>
> void foo( int value );
>
> foo( value: 10 ); // error not defined to use named parameters
> foo( 10 ); // functionally the same
>
> The whole idea of "encapsulating" the variable name is 
> completely bonkers to me. It's a feature that is mislabeling 
> something as encapsulation and is trying to shoehorn it is with 
> statements on the basis that "encapsulation" can't be bad. It 
> is when you don't know what it is or why it is useful.

I'm very confused why you keep saying that hiding parameter names 
isn't "encapsulation". The point is that if you expose the 
parameters names of all functions, you've increased the coupling 
between all functions and their callers and therefore decreased 
encapsulation.

If you want to say that parameters names are not very useful to 
encapsulate, then that's fine, you can have that opinion.  But 
saying that it's not encapsulation at all is demonstrably false.

You also said the "percentage didn't matter", which may be the 
case for you but not for me.

For me, the percentage of functions that would benefit from this 
tells me whether it should be "opt-in", "opt-out" or "always on" 
(the current DIP has proposed "always on"). If there is no 
downside to enabling them, then I would be fine with "always on", 
even if there usefulness is low.  But because I do see a big 
downside, and I think only about 15% of functions can benefit 
from it, it seems to me an "opt-in" option makes sense here.

Note here that I could also be convinced otherwise, but saying 
"this is not encapsulation" is not a convincing argument.

One thing that would be beneficial to discuss is what that 
percentage is.  I've actually proposed named parameters be added 
to another language (zig) here: 
https://github.com/ziglang/zig/issues/479

I came up with a list of cases when named arguments are helpful:

1. flag type parameters

add(1, 2, true); // what is true for?
add(1, 2, checkOverflow=true); // there we go

However in D, this one can be mitigated with Flag.  It's a bit 
less convenient though.

2. if the parameter is a "unit type" like seconds/meters

sleep(1); // is this seconds or milliseconds or what?
sleep(seconds = 1); // much better

D also has ways to mitigate this one as well, such as abstract 
types like Duration.  But like flag, these can be less convenient.

3. if the function takes multiple parameters of the same type 
whose order is important but not clear

can't think of a good example for this one at the moment


By my estimate the percentage of functions that fit any of these 
3 criteria is around 15%. This isn't backed by any real data, 
just an estimate.  I would love to see actual data on this, if 
someone wants to go through some druntime/phobos modules and 
count how many functions would benefit from named arguments.  And 
my criteria list could also be incomplete, I'm sure there are 
other cases where named parameters could be useful.  Please let 
me know if you can think of any more.  And if it turns out the 
percentage is much higher than my estimate, then I might change 
my mind and say that decreasing encapsulation is worth the 
benefit of having named parameters "always on".



More information about the Digitalmars-d mailing list