February 28, 2011
> But then you're back to square one

Obviously, you'd do:

Size size;
size.width = 10;
size.height = 20;

Instead of Size(10, 20).


Another alternative is to give each element their own struct...

struct Width { int width; alias width this; }

foo(Width(10), Height(20));
February 28, 2011
On 02/28/2011 07:56 PM, bearophile wrote:
> spir:
>
>> Yes, I'm aware of that. This usage in fact conflicts with the general
>> "subtyping" semantics of ':'. But this conflict already exists with the usage
>> of ':' in dyn array notation, which is linguistically pretty close to a named
>> argument set; so...
>
> If I have understood what you mean here, then I think we'll just have to leave with this small clash. An alternative solution is to use the Ada syntax: foo(x =>  1, y=>2) but it's a bit longer because it requires two chars instead of one.

Agreed, and I'm not for adding non-obvious "signs". D is not Perl. Or else use ':=' ?

Denis
-- 
_________________
vita es estrany
spir.wikidot.com

February 28, 2011
On 02/28/2011 07:51 PM, Jonathan M Davis wrote:
> I'm not entirely against named arguments being in D, however I do think that any
> functions that actually need them should be refactored anyway.

???

> In actuality, if I were to vote on whether named arguments should be in the
> language, I would definitely vote against it (I just plain don't want the code
> clutter,  [...]

Just don't use them!

Denis
-- 
_________________
vita es estrany
spir.wikidot.com

February 28, 2011
Another alternative is to introduce named arguments and get rid of that extra housekeeping.
February 28, 2011
On Mon, 28 Feb 2011 14:56:15 -0500, Adam Ruppe <destructionator@gmail.com> wrote:

>> But then you're back to square one
>
> Obviously, you'd do:
>
> Size size;
> size.width = 10;
> size.height = 20;
>
> Instead of Size(10, 20).

I could also do:

int width = 10, height = 20;
foo(width, height);

The struct solution helps prevent incorrect ordering.  But other than that, it still looks more verbose than should be necessary.

> Another alternative is to give each element their own struct...
>
> struct Width { int width; alias width this; }
>
> foo(Width(10), Height(20));

This seems like extreme overkill.  I don't want to have to create a new struct for every parameter that I want to pass in a named fashion.

Why can't we just pass integers where integers make sense, and give them names that only exist at compile time?  I don't see the harm in the proposal.  Certainly every counter proposal I've seen to be able to "accomplish the same thing" with today's compiler is worse than just passing two ints.

-Steve
February 28, 2011
On 02/28/2011 08:01 PM, Bekenn wrote:
> On 2/28/11 5:59 AM, spir wrote:
>> +++ Make things simple!
>> Since positional arguments is the main & historic parameter-passing
>> method, just keep order.
>
> I think that would remove a huge chunk of the utility of having named
> arguments, and it doesn't make things easier at all from the compiler's
> perspective.
>
> Consider:
>
> Declaration:
> void func(int a = 0, int b = 1);
>
> Call:
> func(b: 3); // a is default
>
> Since b in the call is not in the same position as specified in the declaration
> (position 0 instead of position 1), the compiler already has to ignore the
> positioning of named arguments.

Yes, you are right on this. But it's because there is a confusion between default and optional parameter, no?

Denis
-- 
_________________
vita es estrany
spir.wikidot.com

February 28, 2011
And maybe sometimes you just want to update one field, e.g.:

void resize(int width=0, int height=0)
{
    if (width)
        // set new width
    if (height)
        // set new height
}

void main()
{
    resize(width:20, height:40);
    // more code..

    resize(width:50);  // only update width
}

Using a struct could potentially introduce bugs, e.g.:
void resize(Size size) { // this.size = size.. }
void main()
{
    Size size;
    size.width = 20;
    size.height = 40;
    resize(size);

    // more code
    size.width = 50;
    resize(size);
}

What if between the two calls to resize some other part of code has manipulated the height? The size struct still has its height member set to 40. So (for example) your window might suddenly jump in height even though the user has updated only the width field.

Now you have to do extra housekeeping to keep things in order (e.g. resetting the height field of the struct so the call to resize doesn't touch the window height).
February 28, 2011
Adam Ruppe:

> Size size;
> size.width = 10;
> size.height = 20;
> 
> Instead of Size(10, 20).

This adds more clutter compared to argument names and requires more lines...


> Another alternative is to give each element their own struct...
> 
> struct Width { int width; alias width this; }
> 
> foo(Width(10), Height(20));

Time ago in D there was typedef for this. There are many problems with this solution:
- You can't use this to give the arguments in a different order, or specify only part of the default arguments.
- this can't be used with functions written by other people that don't already use structs for arguments
- This forces you to always use those names at the calling point, while named arguments are usually optional at the calling point.
- you need to define a new struct for each argument you may want to call with a name, this requires code and increases binary size for nothing.
- Maybe there are problems with padding, like if the wrapped argument is an array ubyte[5].
- I think currently alias this is not fully transparent

Bye,
bearophile
February 28, 2011
Also the resize method would have to look similar to the first one, I messed that up, it should be:

void resize(Size size)
{
     if (size.width)
         this.width = size.width;
     if (size.height)
         this.height = size.height;
}
February 28, 2011
On 02/28/2011 08:33 PM, Jonathan M Davis wrote:
> On Monday, February 28, 2011 11:02:37 Steven Schveighoffer wrote:
>> On Mon, 28 Feb 2011 13:51:56 -0500, Jonathan M Davis<jmdavisProg@gmx.com>
>>
>> wrote:
>>> I'm not entirely against named arguments being in D, however I do think
>>> that any
>>> functions that actually need them should be refactored anyway. So,
>>> ultimately,
>>> I'm not sure that they're really all that useful. I'm sure that they'd
>>> be useful
>>> upon occasion, but if you actually need them, then your function is
>>> taking too
>>> many arguments.
>>>
>>> In actuality, if I were to vote on whether named arguments should be in
>>> the
>>> language, I would definitely vote against it (I just plain don't want
>>> the code
>>> clutter, and they strike me as a crutch to avoid writing functions with
>>> good
>>> signatures in spite of their usefulness in some situations), but I can
>>> see why
>>> some people might want them.
>>
>> Although I am not strongly for named arguments, I think they would be a
>> definite improvement.
>>
>> Bearophile brought up one of the strongest cases for them:
>>
>> foo(int width, int height) {}
>>
>> Seems simple enough, I don't see how you have "too many arguments", but
>> the call looks like this:
>>
>> foo(123, 456);
>>
>> So, looking at this call, can you tell which is width and which is
>> height?  I've seen some libs that use width and height do height first
>> also.  I usually have to go look up the API every time I'm reading/writing
>> one of these.
>>
>> But this is perfectly clear and resists API changes/differences:
>>
>> foo(width: 123, height: 456);
>>
>> The cool part about this is, named arguments are not required -- you can
>> always just not use them.  But when you do use them, the code becomes much
>> clearer.
>
> That does have some minimal benefit, but if you're really passing around width
> and height much, then I'd argue that they should be put in a struct rather than
> passed around bare like that, and then that fixes the issue.

Precisely! Named arguments are a way to make an actual-parameter set a kind of named tuple, meaning a "free struct".
Another place where it would be nice is return values:
    XYZ dimension (...) {
        ...
        return (width:123, height:456);
    }

<OT>
By the way, I wonder why people tend to systematically add one, and only one, space after ':', ',', ';' and never before. D code is not english! There is no reason to write "width: 123" rather than "width:123" or "width : 123". Rather the opposite, ':' expresses here a link which does not binds tightlier on left side than on right side ;-)
Same about ';': it's a separator that has no reason to stick on left side, and not on right side!
People are so conservative...
</OT>

Denis
-- 
_________________
vita es estrany
spir.wikidot.com