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

FeepingCreature feepingcreature at gmail.com
Thu Feb 28 08:32:22 UTC 2019


On Wednesday, 27 February 2019 at 12:49:52 UTC, Joseph Rushton 
Wakeling wrote:
> ...
> First, I think my core objection to this proposal is that 
> ultimately, it's a cosmetic change to language syntax that does 
> not make any meaningful improvement to the kinds of programs 
> one can write, or to the compiler's ability to prove their 
> safety and correctness

Yes it does!! That is in fact the main argument for it! It allows 
the compiler to do a *much* better job at ensuring the 
correctness of programs, by attaching parameters to semantic 
labels instead of passing them by arbitrary positions and hoping 
that the type system will happen to catch errors.

> even allowing that it's opt-in, implementing support is going 
> to be finnicky and intrusive, and risks nasty impacts on stuff 
> that affects _all_ programs (e.g. name mangling).
>

Only if you do it in a weird way. There's no *necessary* reason 
for named parameters to affect mangling at all.

> If we consider the languages where named arguments are a 
> feature, virtually all of them are scripting (or scriptable) 
> languages where it's common to use them via a REPL, and the 
> use-case is for functions that have a lot of parameters, where 
> in the typical use-case the caller only wants to specify the 
> ones that are non-default.
>
> In a scripting language, it's convenient to allow the user to 
> just make the one function call.  But in a systems programming 
> language it's both straightforward and arguably better 
> self-documenting to do something like:
>
> ```
> struct Config
> {
>     // default values for everything
>     int alpha = 23;
>     double beta = 0.25;
>     int gamma = 6;
>     double delta = 1.5;
>     // ...
>     int omega = 99;
> }
>
> double foo (Config config)
> {
>     with(config) {
>         // implementation
>     }
> }
> ```
>
> and then one can call with e.g.:
>
> ```
> Config config = { beta: 6.5, omega: 101 };
> auto result = foo(config);
> ```

And even that is one case where named parameters represent a 
*huge* improvement!

If a new parameter is added to Config, there is *absolutely* no 
way to require it to be passed. You have to use something like my 
own `boilerplate.Builder()`, and even that just gives you an 
exception at compiletime.

struct Foo
{
   int a;
   int b;
   mixin(GenerateThis);
}

with (Foo.Builder())
{
   a = 2;
   return value; // runtime error: necessary field b not assigned
   // but no compile error because :( :( :(
}

There is *no way* to statically enforce that a field was set in a 
struct. Parameters on the other hand do this effortlessly. I'd 
*love* to ditch Boilerplate's generated builders and replace them 
with named parameters. The lack of named parameters is why that 
hacky expensive feature even exists to begin with.

>
> As others have already pointed out, it needs only some small 
> improvements to the struct declaration mechanisms to allow us 
> to do something like:
>
> ```
> foo({ beta: 6.5, omega: 101 });
> ```
>
> ... without even needing to declare a separate Config instance.
>  This sort of approach will work naturally with UFCS:
>
> ```
> double bar (int a, Config config) { ... }
>
> x.bar({ delta: 9.125, gamma: 7});
> ```
>
> ... so one therefore has the effect of named parameters without 
> any real change to the language syntax or behaviour.
>

Yeah at the cost of breaking struct behavior, or you still don't 
have any way to have necessary parameters.

> On the question of "protecting against silent breakage in cases 
> when a function's parameters are repurposed and renamed": this 
> seems a very narrow protection compared to all the ways in 
> which one can introduce breaking change into a function.  And 
> by contrast it blocks something that can be very useful, which 
> is renaming a function parameter to better illustrate its 
> meaning, _without_ changing its purpose.
>

I have literally never done that, whereas I reorder function 
parameters relatively often. Do you really rename function 
parameters more often than inserting a new required parameter in 
the middle?



More information about the Digitalmars-d mailing list