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

Jonathan Marler johnnymarler at gmail.com
Sat Jun 8 18:05:43 UTC 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

Unlike the other cases, this one seems particularly surprising.

>     snoopy(t:t, i, s:s); // A
>     snoopy(s:s, t:t, i); // A

This is another re-ordering case, which makes my brain have to 
strain for a second.

>
> 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 see value in allowing a caller to omit arguments that have 
default values, but what is the value in allowing the caller to 
reorder them?

Allowing re-ordering seems to cause surprising results, such as 
the ones I noted above, and also causes a new decision to made, 
namely, which order should arguments be evaluated in (which you 
noted).  It also means that in order to understand what overload 
you are calling, you need to check EVERY argument before you can 
determine this.  If you don't allow re-ordering, you can rule out 
overloads sooner as you only need to check whether the next named 
argument matches the next named parameter.  To demonstrate, in 
the above example, if I saw

>     snoopy(t:t,...

I can immediately rule out overload B since parameter `s` must 
always come before `t`.  I don't have to check the rest of the 
arguments to see if there is a "s: ...", and then make sure to 
remember that it does as I move through the rest of the 
parameters.  The amount of memory a human will need to track 
while evaluating which overload is taken as the number of 
parameters grows will be unmanageable if re-ordering is allowed.  
And, usually the most useful cases for this are the ones where 
there are alot of parameters.




More information about the Digitalmars-d mailing list