www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Re: Flag proposal

reply bearophile < bearophileHUGS lycos.com> writes:
Andrei:

 If we all get convinced that named parameters are worth it,

I think this is not going to happen because some people (two?) don't want this feature. I am for it, if it's well implemented. The reordering is one important part of this feature. An optional sub-feature is a way to deprecate argument names. Thankfully in D there is already the deprecated keyword; a first idea: void foo(int deprecated(y) x) {} Or: void foo(int deprecated{y} x) {} Bye, bearophile
Jun 13 2011
next sibling parent "Nick Sabalausky" <a a.a> writes:
"bearophile" < bearophileHUGS lycos.com> wrote in message 
news:it5gqj$a1g$1 digitalmars.com...
 Andrei:

 If we all get convinced that named parameters are worth it,

I think this is not going to happen because some people (two?) don't want this feature. I am for it, if it's well implemented. The reordering is one important part of this feature. An optional sub-feature is a way to deprecate argument names. Thankfully in D there is already the deprecated keyword; a first idea: void foo(int deprecated(y) x) {} Or: void foo(int deprecated{y} x) {}

I like it!
Jun 13 2011
prev sibling next sibling parent reply so <so so.so> writes:
On Mon, 13 Jun 2011 20:19:15 +0300, bearophile <  
<bearophileHUGS lycos.com> wrote:

 Andrei:

 If we all get convinced that named parameters are worth it,

I think this is not going to happen because some people (two?) don't want this feature.

I think they worth it and it is the right time to talk extensively why people think they don't. And reasoning should not be about its failure or success in another language, we better have our own rules. IMO named arguments in D at least should do: - Reordering (since we got default parameters, even better) - It is enabled only if we have access to the function declaration. - In a function call we either use named arguments for all the non-default arguments or call it with the usual syntax. No hybrid stuff, no confusion. fun(int a, int b, int c=3) fun(1, 2, 3) // fine - current fun(1, 2) // fine - current fun(a:1, b:3, c:5) // fine fun(a:1, b:3) // fine fun(b:1, c:3, a:5) // fine fun(b:1, a:3) // fine fun(b:1) // error fun(c:1) // error fun(2, b:1) // error fun(2, c:1) // error fun(2, c:2, 3) // error Thanks.
Jun 13 2011
next sibling parent reply Ary Manzana <ary esperanto.org.ar> writes:
On 6/14/11 8:36 AM, so wrote:
 On Mon, 13 Jun 2011 20:19:15 +0300, bearophile <
 <bearophileHUGS lycos.com> wrote:

 Andrei:

 If we all get convinced that named parameters are worth it,

I think this is not going to happen because some people (two?) don't want this feature.

I think they worth it and it is the right time to talk extensively why people think they don't. And reasoning should not be about its failure or success in another language, we better have our own rules. IMO named arguments in D at least should do: - Reordering (since we got default parameters, even better) - It is enabled only if we have access to the function declaration. - In a function call we either use named arguments for all the non-default arguments or call it with the usual syntax. No hybrid stuff, no confusion.

A different rule can be: - Named arguments come last. - Any previous arguments match the order.
 fun(int a, int b, int c=3)

 fun(1, 2, 3) // fine - current
 fun(1, 2) // fine - current

 fun(a:1, b:3, c:5) // fine
 fun(a:1, b:3) // fine
 fun(b:1, c:3, a:5) // fine
 fun(b:1, a:3) // fine
 fun(b:1) // error

 fun(c:1) // error

 fun(2, b:1) // error

 fun(2, c:1) // error

 fun(2, c:2, 3) // error

Jun 13 2011
parent reply "Nick Sabalausky" <a a.a> writes:
"so" <so so.so> wrote in message news:op.vw1msqy0mpw3zg so-pc...
 On Tue, 14 Jun 2011 04:46:54 +0300, Ary Manzana <ary esperanto.org.ar> 
 wrote:

 On 6/14/11 8:36 AM, so wrote:
 On Mon, 13 Jun 2011 20:19:15 +0300, bearophile <
 <bearophileHUGS lycos.com> wrote:

 Andrei:

 If we all get convinced that named parameters are worth it,

I think this is not going to happen because some people (two?) don't want this feature.

I think they worth it and it is the right time to talk extensively why people think they don't. And reasoning should not be about its failure or success in another language, we better have our own rules. IMO named arguments in D at least should do: - Reordering (since we got default parameters, even better) - It is enabled only if we have access to the function declaration. - In a function call we either use named arguments for all the non-default arguments or call it with the usual syntax. No hybrid stuff, no confusion.

A different rule can be: - Named arguments come last. - Any previous arguments match the order.

IMO the main that makes NAs confusing is allowing hybrid calls. I don't think allowing reordering then introducing two new rules on ordering is a good idea.

I think Ary's suggestion is very simple and easy to understand. Hybrid calls are *only* confusing when an unnamed parameter comes after a named one.
Jun 13 2011
next sibling parent reply Ary Manzana <ary esperanto.org.ar> writes:
On 6/14/11 12:58 PM, so wrote:
 On Tue, 14 Jun 2011 08:32:59 +0300, Nick Sabalausky <a a.a> wrote:

 I think Ary's suggestion is very simple and easy to understand. Hybrid
 calls
 are *only* confusing when an unnamed parameter comes after a named one.

An example to it. fun(int a, int b, int c, int d) Say we want to name only c: fun(2, 3, 1, c:5)

Remember, the third argument is positional so it's assigned to c. Then you are trying to assign c again. It's an error.
Jun 13 2011
parent Ary Manzana <ary esperanto.org.ar> writes:
On 6/14/11 1:38 PM, so wrote:
 On Tue, 14 Jun 2011 09:33:54 +0300, Ary Manzana <ary esperanto.org.ar>
 wrote:

 On 6/14/11 12:58 PM, so wrote:
 On Tue, 14 Jun 2011 08:32:59 +0300, Nick Sabalausky <a a.a> wrote:

 I think Ary's suggestion is very simple and easy to understand. Hybrid
 calls
 are *only* confusing when an unnamed parameter comes after a named one.

An example to it. fun(int a, int b, int c, int d) Say we want to name only c: fun(2, 3, 1, c:5)

Remember, the third argument is positional so it's assigned to c. Then you are trying to assign c again. It's an error.

Sorry i don't understand, what should i do?

You can't only name c. You can name arguments from the end to the beginning: fun(2, 3, 1, d: 99) fun(2, 3, c: 98, d:99) fun(2, 3, d: 98, c:99) fun(2, c: 97, b: 98, d:99) etc.
Jun 13 2011
prev sibling parent reply Ary Manzana <ary esperanto.org.ar> writes:
On 6/14/11 12:32 PM, Nick Sabalausky wrote:
 "so"<so so.so>  wrote in message news:op.vw1msqy0mpw3zg so-pc...
 On Tue, 14 Jun 2011 04:46:54 +0300, Ary Manzana<ary esperanto.org.ar>
 wrote:

 On 6/14/11 8:36 AM, so wrote:
 On Mon, 13 Jun 2011 20:19:15 +0300, bearophile<
 <bearophileHUGS lycos.com>  wrote:

 Andrei:

 If we all get convinced that named parameters are worth it,

I think this is not going to happen because some people (two?) don't want this feature.

I think they worth it and it is the right time to talk extensively why people think they don't. And reasoning should not be about its failure or success in another language, we better have our own rules. IMO named arguments in D at least should do: - Reordering (since we got default parameters, even better) - It is enabled only if we have access to the function declaration. - In a function call we either use named arguments for all the non-default arguments or call it with the usual syntax. No hybrid stuff, no confusion.

A different rule can be: - Named arguments come last. - Any previous arguments match the order.

IMO the main that makes NAs confusing is allowing hybrid calls. I don't think allowing reordering then introducing two new rules on ordering is a good idea.

I think Ary's suggestion is very simple and easy to understand. Hybrid calls are *only* confusing when an unnamed parameter comes after a named one.

Well, that's the way Ruby works :-) In fact, in Ruby there are no named arguments. So people came up with this idea. def some_function(param_a, param_b, options = {}) param_c = options['param_c'] || default_for_c param_d = options['param_d'] || default_for_d end The last argument is a hash (a dictionary) with a default value of an empty hash. So you can call it: some_function(1, 2) some_function(1, 2, {'param_c' => 3}) some_function(1, 2, {'param_c' => 3, 'param_d' => 4}) But in Ruby there's a rule: you can skip parenthesis. And you can skip the brackets for a hash if it's the last argument. And instead of strings symbols are much nicer and efficient. So... some_function 1, 2 some_function 1, 2, :param_c => 3 some_function 1, 3, :param_c => 3, :param_d => 4 Of course this won't work in D because passing hashes all the time would be very inneficcient. But I think positional arguments first, named arguments last is a simple rule that's easy to follow and probably implement (maybe when I'll go back to my country I'll try to implement it).
Jun 13 2011
next sibling parent Ary Manzana <ary esperanto.org.ar> writes:
On 6/14/11 1:58 PM, so wrote:
 On Tue, 14 Jun 2011 09:48:14 +0300, Ary Manzana <ary esperanto.org.ar>
 wrote:

 Well, that's the way Ruby works :-)

 In fact, in Ruby there are no named arguments. So people came up with
 this idea.

 def some_function(param_a, param_b, options = {})
 param_c = options['param_c'] || default_for_c
 param_d = options['param_d'] || default_for_d
 end

 The last argument is a hash (a dictionary) with a default value of an
 empty hash.

 So you can call it:

 some_function(1, 2)
 some_function(1, 2, {'param_c' => 3})
 some_function(1, 2, {'param_c' => 3, 'param_d' => 4})

 But in Ruby there's a rule: you can skip parenthesis. And you can skip
 the brackets for a hash if it's the last argument. And instead of
 strings symbols are much nicer and efficient. So...

 some_function 1, 2
 some_function 1, 2, :param_c => 3
 some_function 1, 3, :param_c => 3, :param_d => 4

 Of course this won't work in D because passing hashes all the time
 would be very inneficcient. But I think positional arguments first,
 named arguments last is a simple rule that's easy to follow and
 probably implement (maybe when I'll go back to my country I'll try to
 implement it).

Tell me this is not true! :)

:-P
 So ruby don't have named arguments and the community came up with a
 solution which is by the look of it heavily influenced by language
 capabilities. No offense and please no kicking butts but... This is
 madness!!!

Well, in fact I don't know if the community came up with this or if the creators came up with this. But I'm sure at some point they agreed on this because it's supported on the syntax level.
Jun 14 2011
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 6/14/11 1:58 AM, so wrote:
 Tell me this is not true! :)
 So ruby don't have named arguments and the community came up with a
 solution which is by the look of it heavily influenced by language
 capabilities. No offense and please no kicking butts but... This is
 madness!!!

Ha! My Flag chef d'oeuvre would enjoy appreciation, just in another language. Andrei
Jun 14 2011
prev sibling next sibling parent so <so so.so> writes:
On Tue, 14 Jun 2011 04:46:54 +0300, Ary Manzana <ary esperanto.org.ar>  
wrote:

 On 6/14/11 8:36 AM, so wrote:
 On Mon, 13 Jun 2011 20:19:15 +0300, bearophile <
 <bearophileHUGS lycos.com> wrote:

 Andrei:

 If we all get convinced that named parameters are worth it,

I think this is not going to happen because some people (two?) don't want this feature.

I think they worth it and it is the right time to talk extensively why people think they don't. And reasoning should not be about its failure or success in another language, we better have our own rules. IMO named arguments in D at least should do: - Reordering (since we got default parameters, even better) - It is enabled only if we have access to the function declaration. - In a function call we either use named arguments for all the non-default arguments or call it with the usual syntax. No hybrid stuff, no confusion.

A different rule can be: - Named arguments come last. - Any previous arguments match the order.

IMO the main that makes NAs confusing is allowing hybrid calls. I don't think allowing reordering then introducing two new rules on ordering is a good idea.
Jun 13 2011
prev sibling next sibling parent so <so so.so> writes:
On Tue, 14 Jun 2011 08:32:59 +0300, Nick Sabalausky <a a.a> wrote:

 I think Ary's suggestion is very simple and easy to understand. Hybrid  
 calls
 are *only* confusing when an unnamed parameter comes after a named one.

An example to it. fun(int a, int b, int c, int d) Say we want to name only c: fun(2, 3, 1, c:5) Ary's rules and function signature in mind, after you glance the call you'd do some calculations and eventually find out the caller meant: fun(a:2, b:3, d:1, c:5) This is only 4 parameters and i named only one. Now NAs supposed to ease to process of self-documenting, not complicate it even further. I'm in favor of keeping it as simple as possible without creating any confusion.
Jun 13 2011
prev sibling next sibling parent reply KennyTM~ <kennytm gmail.com> writes:
On Jun 14, 11 09:36, so wrote:
 On Mon, 13 Jun 2011 20:19:15 +0300, bearophile <
 <bearophileHUGS lycos.com> wrote:

 Andrei:

 If we all get convinced that named parameters are worth it,

I think this is not going to happen because some people (two?) don't want this feature.

I think they worth it and it is the right time to talk extensively why people think they don't. And reasoning should not be about its failure or success in another language, we better have our own rules. IMO named arguments in D at least should do: - Reordering (since we got default parameters, even better) - It is enabled only if we have access to the function declaration. - In a function call we either use named arguments for all the non-default arguments or call it with the usual syntax. No hybrid stuff, no confusion. fun(int a, int b, int c=3) fun(1, 2, 3) // fine - current fun(1, 2) // fine - current fun(a:1, b:3, c:5) // fine fun(a:1, b:3) // fine fun(b:1, c:3, a:5) // fine fun(b:1, a:3) // fine fun(b:1) // error fun(c:1) // error fun(2, b:1) // error fun(2, c:1) // error fun(2, c:2, 3) // error Thanks.

I'd rather have no reordering and allow hybrid call. Named argument is useful for specifying the nature of an argument. If the type is clear for all but one argument, the rest is just noisy redundant info. e.g. MoveWindow(hWnd, loc.x, loc.y, myWin.width, myWin.height, bRepaint:true); is no worse than MoveWindow(hWnd:hWnd, X:loc.x, Y:loc.y, nWidth:myWin.width, nHeight:myWin.height, bRepaint:true);
Jun 13 2011
parent reply KennyTM~ <kennytm gmail.com> writes:
On Jun 14, 11 14:46, so wrote:
 On Tue, 14 Jun 2011 09:18:42 +0300, KennyTM~ <kennytm gmail.com> wrote:

 I'd rather have no reordering and allow hybrid call. Named argument is
 useful for specifying the nature of an argument. If the type is clear
 for all but one argument, the rest is just noisy redundant info.

fun(bool, bool, bool, bool, bool...) Isn't the type clear for every argument here?

By "type" I mean the purpose of an argument, e.g. the first 'int' in MoveWindow is an x-coordinate, the second is a y-coordinate, etc. Sorry I don't know of a better term. When what one argument does is clear for the caller, forcing NA on it just annoys the programmer.
 e.g.

 MoveWindow(hWnd, loc.x, loc.y, myWin.width, myWin.height,
 bRepaint:true);

 is no worse than

 MoveWindow(hWnd:hWnd, X:loc.x, Y:loc.y,
 nWidth:myWin.width, nHeight:myWin.height, bRepaint:true);

Reordering is important an example: fun(int a, int b=2, int c=3) If you want to name c but not b what are you going to do?

That's skipping, not really reordering. 'a' still precedes 'c'. Also, I'm not against reordering, but I'm against using reordering as a reason to abandon hybrid.
 Named arguments isn't something to save typing.
 Also the first version of the MoveWindow indeed worse than the second,
 which again i think requires no explanation.

No, please explain. What does the extra hWnd, X, Y, nWidth, nHeight buy, when the respective arguments already show what they are?'
Jun 14 2011
parent reply KennyTM~ <kennytm gmail.com> writes:
On Jun 14, 11 16:39, so wrote:
 On Tue, 14 Jun 2011 11:23:12 +0300, KennyTM~ <kennytm gmail.com> wrote:

 On Jun 14, 11 14:46, so wrote:
 On Tue, 14 Jun 2011 09:18:42 +0300, KennyTM~ <kennytm gmail.com> wrote:

 I'd rather have no reordering and allow hybrid call. Named argument is
 useful for specifying the nature of an argument. If the type is clear
 for all but one argument, the rest is just noisy redundant info.

fun(bool, bool, bool, bool, bool...) Isn't the type clear for every argument here?

By "type" I mean the purpose of an argument, e.g. the first 'int' in MoveWindow is an x-coordinate, the second is a y-coordinate, etc. Sorry I don't know of a better term. When what one argument does is clear for the caller, forcing NA on it just annoys the programmer.

This is the whole point of NAs, it is not clear, you need to check the function definition whenever you read the call.

And yet, with loc.x, myWin.width etc, you don't need to check the definition to know those should be coordinates and widths.
 e.g.

 MoveWindow(hWnd, loc.x, loc.y, myWin.width, myWin.height,
 bRepaint:true);

 is no worse than

 MoveWindow(hWnd:hWnd, X:loc.x, Y:loc.y,
 nWidth:myWin.width, nHeight:myWin.height, bRepaint:true);

Reordering is important an example: fun(int a, int b=2, int c=3) If you want to name c but not b what are you going to do?

That's skipping, not really reordering. 'a' still precedes 'c'. Also, I'm not against reordering, but I'm against using reordering as a reason to abandon hybrid.

It is not a reason to abandon hybrid, it is a consequence of abandoning it.

You don't need to abandon hybrid to enable reordering. Ary's suggestion, for example, allows positional and named arguments to coexist.
 Named arguments isn't something to save typing.
 Also the first version of the MoveWindow indeed worse than the second,
 which again i think requires no explanation.

No, please explain. What does the extra hWnd, X, Y, nWidth, nHeight buy, when the respective arguments already show what they are?'

Matching, with fun(x:x, y:y) or fun(y:y, x:x) you are done, you don't ever need to check function definition again. With your reasoning you don't need named arguments at all.

Why do you need to check the function definition when you see 'moveTo(x, y)'?
 enum bRepaint=true;
 MoveWindow(... bRepaint)

Non sequitur. In my MoveWindow example hWnd, loc and myWin are assumed to be variables you got from elsewhere. The names of these variables already provide the semantics to the readers, making NA for those arguments redundant. If they were constants it's nothing wrong with MoveWindow(hWnd, X:0, Y:0, nWidth:200, nHeight:200, bRepaint:true);
Jun 14 2011
next sibling parent reply KennyTM~ <kennytm gmail.com> writes:
On Jun 14, 11 19:11, so wrote:
 On Tue, 14 Jun 2011 12:58:30 +0300, KennyTM~ <kennytm gmail.com> wrote:

 And yet, with loc.x, myWin.width etc, you don't need to check the
 definition to know those should be coordinates and widths.

loc.x on the caller side, it has no idea about function signature, and you don't know if it was 10th or 2nd argument in function. // definition fun(int x, int y) { } // call fun(x, y) // you need to check the definition if you think something wrong with parameters the second time you come here fun(y, x) // same fun(x:x, y:y) // you know there is nothing wrong with parameters fun(y:y, x:x) // same

If you have no idea about the function signature, you have no idea about the parameter names either.
 You don't need to abandon hybrid to enable reordering. Ary's
 suggestion, for example, allows positional and named arguments to
 coexist.

Allows reordering by introducing two new order restrictions which i still had trouble understanding, sorry Ary :)
 Why do you need to check the function definition when you see
 'moveTo(x, y)'?

Same question, why do you need named arguments?

You see the difference between variables and generic constants? RECT bounds; GetWindowRect(hWnd, &bounds); writeln("Please enter the coordinates."); auto x = readln().chomp().to!int(); auto y = readln().chomp().to!int(); auto width = bounds.right - bounds.left; auto height = bounds.bottom - bounds.top; MoveWindow(hWnd, x, y, width, height, bRepaint:true); vs. writeln("Resetting window dimensions"); ... MoveWindow(hWnd, X:0, Y:0, nWidth:800, nHeight:600, bRepaint:true); Named arguments provides clarification when the argument itself (e.g. 0, false, true) is meaningless. But with a variable which itself provides a meaning, forcing named argument on _every_argument_passed_ is just annoying.
 enum bRepaint=true;
 MoveWindow(... bRepaint)

Non sequitur. In my MoveWindow example hWnd, loc and myWin are assumed to be variables you got from elsewhere. The names of these variables already provide the semantics to the readers, making NA for those arguments redundant. If they were constants it's nothing wrong with MoveWindow(hWnd, X:0, Y:0, nWidth:200, nHeight:200, bRepaint:true);

Again, they are variables you get on the caller side, they got no idea about function signature.

See above.
 Also i don't understand why some think allowing hybrid calls has any
 merit. Just search "named arguments" and first thing you'd see is calls
 with all arguments named, no exception. Allowing unnamed arguments and
 named arguments in one call doesn't make any sense to me, it is almost
 opposite to the reasons named arguments designed for, you don't even
 need to talk about its drawbacks like the complications and confusions.

Yet all well-known languages that support named arguments that support reordering also support hybrid. (C# 4, VB 6, Python, CLisp, ...)
Jun 14 2011
parent reply KennyTM~ <kennytm gmail.com> writes:
On Jun 15, 11 00:45, so wrote:
 On Tue, 14 Jun 2011 15:18:09 +0300, KennyTM~ <kennytm gmail.com> wrote:

 loc.x on the caller side, it has no idea about function signature, and
 you don't know if it was 10th or 2nd argument in function.

 // definition
 fun(int x, int y) {
 }

 // call
 fun(x, y) // you need to check the definition if you think something
 wrong with parameters the second time you come here
 fun(y, x) // same
 fun(x:x, y:y) // you know there is nothing wrong with parameters
 fun(y:y, x:x) // same

If you have no idea about the function signature, you have no idea about the parameter names either.

I think you are just resisting here, if you write a call once with named arguments, you documented it in place, the next time you visit this call all you need to see is in the call site.

I'm just bringing up the fact. Why would you need to check the function signature when reading MoveWindow(hWnd, loc.x, loc.y, myWin.width, myWin.height, bRepaint:true); ? It's clear what each argument does. If you feel the need of duplicating the same information, fine, write MoveWindow(hWnd:hWnd, X:loc.x, Y:loc.y, nWidth:myWin.width, nHeight:myWin.height, bRepaint:true); in your code. But don't make it mandatory, it's a waste of time and space when the writer just wants to clarify that 'true' is a bRepaint.
 You see the difference between variables and generic constants?

 RECT bounds;
 GetWindowRect(hWnd, &bounds);

 writeln("Please enter the coordinates.");
 auto x = readln().chomp().to!int();
 auto y = readln().chomp().to!int();
 auto width = bounds.right - bounds.left;
 auto height = bounds.bottom - bounds.top;

 MoveWindow(hWnd, x, y, width, height, bRepaint:true);
 vs.

 writeln("Resetting window dimensions");
 ...
 MoveWindow(hWnd, X:0, Y:0, nWidth:800, nHeight:600, bRepaint:true);

 Named arguments provides clarification when the argument itself (e.g.
 0, false, true) is meaningless. But with a variable which itself
 provides a meaning, forcing named argument on _every_argument_passed_
 is just annoying.

Looks like i am just repeating myself but i don't understand how is pssing constants meaningless and variables, and why do you even need named arguments for those? enum x=... enum y=... ... fun(x, y)

If you want to disregard named argument, why go the complicated route and define enums? You could do as well fun(/*x*/0, /*y*/0); (and yes I'm currently using it.) But the point is it's ugly. Heck why do we need to defend NA. My point is only "hybrid should be allowed if I want to".
 Yet all well-known languages that support named arguments that support
 reordering also support hybrid. (C# 4, VB 6, Python, CLisp, ...)

This is not an argument.

Neither is 'Just search "named arguments" and first thing you'd see is calls with all arguments named, no exception.' Maybe another argument: D's static struct initializer already supports hybrid and reordering. Extending that to function arguments is natural. ------------------------------------ struct S { int x; int y; } void main() { S s0 = {4, 5}; S s1 = {x:4, 5}; S s2 = {4, y:5}; S s3 = {x:4, y:5}; // S s4 = {y:4, 5}; // error S s5 = {y:5, x:4}; } ------------------------------------
Jun 14 2011
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
so:

 I didn't know they work this way, i agree it is a good argument (finally  
 we agree on something!)

To not waste all the good discussions I suggest to write down a DEP (D Enhancement Proposal), that tries to list what to do in all corner cases, even just a "?" where you don't know what to do (and including my Scala-style deprecated(oldArgName) idea). Even writing a pre-DEP will be a good starting point. Even if in the end named arguments don't get added to D, having this DEP will be good to avoid further future discussions, or as starting point for a future desire to try adding them again. Bye, bearophile
Jun 15 2011
parent KennyTM~ <kennytm gmail.com> writes:
On Jun 16, 11 00:43, bearophile wrote:
 so:

 I didn't know they work this way, i agree it is a good argument (finally
 we agree on something!)

To not waste all the good discussions I suggest to write down a DEP (D Enhancement Proposal), that tries to list what to do in all corner cases, even just a "?" where you don't know what to do (and including my Scala-style deprecated(oldArgName) idea). Even writing a pre-DEP will be a good starting point. Even if in the end named arguments don't get added to D, having this DEP will be good to avoid further future discussions, or as starting point for a future desire to try adding them again. Bye, bearophile

You mean a DIP :)
Jun 15 2011
prev sibling parent reply "Nick Sabalausky" <a a.a> writes:
"KennyTM~" <kennytm gmail.com> wrote in message 
news:it8f4s$1gve$1 digitalmars.com...
 On Jun 15, 11 00:45, so wrote:
 On Tue, 14 Jun 2011 15:18:09 +0300, KennyTM~ <kennytm gmail.com> wrote:

 loc.x on the caller side, it has no idea about function signature, and
 you don't know if it was 10th or 2nd argument in function.

 // definition
 fun(int x, int y) {
 }

 // call
 fun(x, y) // you need to check the definition if you think something
 wrong with parameters the second time you come here
 fun(y, x) // same
 fun(x:x, y:y) // you know there is nothing wrong with parameters
 fun(y:y, x:x) // same

If you have no idea about the function signature, you have no idea about the parameter names either.

I think you are just resisting here, if you write a call once with named arguments, you documented it in place, the next time you visit this call all you need to see is in the call site.

I'm just bringing up the fact. Why would you need to check the function signature when reading MoveWindow(hWnd, loc.x, loc.y, myWin.width, myWin.height, bRepaint:true); ? It's clear what each argument does.

Because it might be wrong.
 If you feel the need of duplicating the same information, fine, write

     MoveWindow(hWnd:hWnd, X:loc.x, Y:loc.y,
                nWidth:myWin.width, nHeight:myWin.height, bRepaint:true);

 in your code. But don't make it mandatory, it's a waste of time and space 
 when the writer just wants to clarify that 'true' is a bRepaint.

I don't think anyone suggested named arguments should be manditory.
Jun 19 2011
parent KennyTM~ <kennytm gmail.com> writes:
On Jun 20, 11 03:03, Nick Sabalausky wrote:
 "KennyTM~"<kennytm gmail.com>  wrote in message
 news:it8f4s$1gve$1 digitalmars.com...
 On Jun 15, 11 00:45, so wrote:
 On Tue, 14 Jun 2011 15:18:09 +0300, KennyTM~<kennytm gmail.com>  wrote:

 loc.x on the caller side, it has no idea about function signature, and
 you don't know if it was 10th or 2nd argument in function.

 // definition
 fun(int x, int y) {
 }

 // call
 fun(x, y) // you need to check the definition if you think something
 wrong with parameters the second time you come here
 fun(y, x) // same
 fun(x:x, y:y) // you know there is nothing wrong with parameters
 fun(y:y, x:x) // same

If you have no idea about the function signature, you have no idea about the parameter names either.

I think you are just resisting here, if you write a call once with named arguments, you documented it in place, the next time you visit this call all you need to see is in the call site.

I'm just bringing up the fact. Why would you need to check the function signature when reading MoveWindow(hWnd, loc.x, loc.y, myWin.width, myWin.height, bRepaint:true); ? It's clear what each argument does.

Because it might be wrong.
 If you feel the need of duplicating the same information, fine, write

      MoveWindow(hWnd:hWnd, X:loc.x, Y:loc.y,
                 nWidth:myWin.width, nHeight:myWin.height, bRepaint:true);

 in your code. But don't make it mandatory, it's a waste of time and space
 when the writer just wants to clarify that 'true' is a bRepaint.

I don't think anyone suggested named arguments should be manditory.

Right, no one suggested named arguments should be mandatory, but so's original suggestion is either "all on" or "all off", which makes this example pretty much mandatory because of a 'bRepaint: true'.
Jun 19 2011
prev sibling parent reply KennyTM~ <kennytm gmail.com> writes:
On Jun 14, 11 19:11, so wrote:
[snip]
 Also i don't understand why some think allowing hybrid calls has any
 merit. Just search "named arguments" and first thing you'd see is calls
 with all arguments named, no exception. Allowing unnamed arguments and
 named arguments in one call doesn't make any sense to me, it is almost
 opposite to the reasons named arguments designed for, you don't even
 need to talk about its drawbacks like the complications and confusions.

And if you think it's complicated, you're just thinking in a too complicated way. The rule is simple. Say there is a function pure nothrow S parseString(S=const(char)[], C) (ref C[] input, out ConversionResult result, char quote='"', bool recognizePrefix=true) if (...); and you call it as string s = `"hello"`; ConversionResult detailResult; auto parsed = parseString(s, recognizePrefix:false, result:detailResult); The first step is identify all positional arguments ('s' here), and fill them in in-order. input <- s result <- ... quote <- ... recognizePrefix <- ... next, we match the named args input <- s result <- detailResult quote <- ... recognizePrefix <- false finally we fill in the optional parameters input <- s result <- detailResult quote <- '"' recognizePrefix <- false what's so complicated? Actually, reordering creates more complication than hybrid (e.g. ambiguity in selecting an overload).
Jun 14 2011
next sibling parent KennyTM~ <kennytm gmail.com> writes:
On Jun 15, 11 01:18, so wrote:
 On Tue, 14 Jun 2011 16:01:20 +0300, KennyTM~ <kennytm gmail.com> wrote:

 On Jun 14, 11 19:11, so wrote:
 [snip]
 Also i don't understand why some think allowing hybrid calls has any
 merit. Just search "named arguments" and first thing you'd see is calls
 with all arguments named, no exception. Allowing unnamed arguments and
 named arguments in one call doesn't make any sense to me, it is almost
 opposite to the reasons named arguments designed for, you don't even
 need to talk about its drawbacks like the complications and confusions.

And if you think it's complicated, you're just thinking in a too complicated way. The rule is simple. Say there is a function pure nothrow S parseString(S=const(char)[], C) (ref C[] input, out ConversionResult result, char quote='"', bool recognizePrefix=true) if (...); and you call it as string s = `"hello"`; ConversionResult detailResult; auto parsed = parseString(s, recognizePrefix:false, result:detailResult); The first step is identify all positional arguments ('s' here), and fill them in in-order. input <- s result <- ... quote <- ... recognizePrefix <- ... next, we match the named args input <- s result <- detailResult quote <- ... recognizePrefix <- false finally we fill in the optional parameters input <- s result <- detailResult quote <- '"' recognizePrefix <- false what's so complicated? Actually, reordering creates more complication than hybrid (e.g. ambiguity in selecting an overload).

So complicated because it took you this long to match the parameters with the variables, you still need to check function definition because you have parameters that have no match. These are the very things named arguments needs to solve or am i missing something? You could just drop it and go read the function signature everytime, it'd save you time :P

What you're missing may be that what I'm outlining is how the /compiler/ matches the parameters. The /compiler/ of course needs to check the function definition every time, otherwise how could it emit errors when you give a wrong name? :)
Jun 14 2011
prev sibling parent "Nick Sabalausky" <a a.a> writes:
"so" <so so.so> wrote in message news:op.vw2s1b19mpw3zg tan-pc...
 On Tue, 14 Jun 2011 16:01:20 +0300, KennyTM~ <kennytm gmail.com> wrote:

 On Jun 14, 11 19:11, so wrote:
 [snip]
 Also i don't understand why some think allowing hybrid calls has any
 merit. Just search "named arguments" and first thing you'd see is calls
 with all arguments named, no exception. Allowing unnamed arguments and
 named arguments in one call doesn't make any sense to me, it is almost
 opposite to the reasons named arguments designed for, you don't even
 need to talk about its drawbacks like the complications and confusions.

And if you think it's complicated, you're just thinking in a too complicated way. The rule is simple. Say there is a function pure nothrow S parseString(S=const(char)[], C) (ref C[] input, out ConversionResult result, char quote='"', bool recognizePrefix=true) if (...); and you call it as string s = `"hello"`; ConversionResult detailResult; auto parsed = parseString(s, recognizePrefix:false, result:detailResult); The first step is identify all positional arguments ('s' here), and fill them in in-order. input <- s result <- ... quote <- ... recognizePrefix <- ... next, we match the named args input <- s result <- detailResult quote <- ... recognizePrefix <- false finally we fill in the optional parameters input <- s result <- detailResult quote <- '"' recognizePrefix <- false what's so complicated? Actually, reordering creates more complication than hybrid (e.g. ambiguity in selecting an overload).

So complicated because it took you this long to match the parameters with the variables, you still need to check function definition because you have parameters that have no match. These are the very things named arguments needs to solve or am i missing something?

Simple rule for combining hybrid and reordering: Look at the caller's args one at a time: as soon as one is reordered, the rest of the args must be named (otherwise you wouldn't know which param it's supposed to be).
Jun 19 2011
prev sibling next sibling parent so <so so.so> writes:
On Tue, 14 Jun 2011 09:33:54 +0300, Ary Manzana <ary esperanto.org.ar>  
wrote:

 On 6/14/11 12:58 PM, so wrote:
 On Tue, 14 Jun 2011 08:32:59 +0300, Nick Sabalausky <a a.a> wrote:

 I think Ary's suggestion is very simple and easy to understand. Hybrid
 calls
 are *only* confusing when an unnamed parameter comes after a named one.

An example to it. fun(int a, int b, int c, int d) Say we want to name only c: fun(2, 3, 1, c:5)

Remember, the third argument is positional so it's assigned to c. Then you are trying to assign c again. It's an error.

Sorry i don't understand, what should i do?
Jun 13 2011
prev sibling next sibling parent so <so so.so> writes:
On Tue, 14 Jun 2011 09:18:42 +0300, KennyTM~ <kennytm gmail.com> wrote:

 I'd rather have no reordering and allow hybrid call. Named argument is  
 useful for specifying the nature of an argument. If the type is clear  
 for all but one argument, the rest is just noisy redundant info.

fun(bool, bool, bool, bool, bool...) Isn't the type clear for every argument here?
 e.g.

      MoveWindow(hWnd, loc.x, loc.y, myWin.width, myWin.height,
                 bRepaint:true);

 is no worse than

      MoveWindow(hWnd:hWnd, X:loc.x, Y:loc.y,
                 nWidth:myWin.width, nHeight:myWin.height, bRepaint:true);

Reordering is important an example: fun(int a, int b=2, int c=3) If you want to name c but not b what are you going to do? Named arguments isn't something to save typing. Also the first version of the MoveWindow indeed worse than the second, which again i think requires no explanation.
Jun 13 2011
prev sibling next sibling parent so <so so.so> writes:
On Tue, 14 Jun 2011 09:48:14 +0300, Ary Manzana <ary esperanto.org.ar>  
wrote:

 Well, that's the way Ruby works :-)

 In fact, in Ruby there are no named arguments. So people came up with  
 this idea.

 def some_function(param_a, param_b, options = {})
    param_c = options['param_c'] || default_for_c
    param_d = options['param_d'] || default_for_d
 end

 The last argument is a hash (a dictionary) with a default value of an  
 empty hash.

 So you can call it:

 some_function(1, 2)
 some_function(1, 2, {'param_c' => 3})
 some_function(1, 2, {'param_c' => 3, 'param_d' => 4})

 But in Ruby there's a rule: you can skip parenthesis. And you can skip  
 the brackets for a hash if it's the last argument. And instead of  
 strings symbols are much nicer and efficient. So...

 some_function 1, 2
 some_function 1, 2, :param_c => 3
 some_function 1, 3, :param_c => 3, :param_d => 4

 Of course this won't work in D because passing hashes all the time would  
 be very inneficcient. But I think positional arguments first, named  
 arguments last is a simple rule that's easy to follow and probably  
 implement (maybe when I'll go back to my country I'll try to implement  
 it).

Tell me this is not true! :) So ruby don't have named arguments and the community came up with a solution which is by the look of it heavily influenced by language capabilities. No offense and please no kicking butts but... This is madness!!!
Jun 13 2011
prev sibling next sibling parent so <so so.so> writes:
 Reordering is important an example:

 fun(int a, int b=2, int c=3)
 If you want to name c but not b what are you going to do?

In fact, i was wrong on this one, you'd simply call fun(a, c:4). Reordering is nice because if you remove hybrid calls you no longer need an order, you are free to change priority.
Jun 14 2011
prev sibling next sibling parent so <so so.so> writes:
On Tue, 14 Jun 2011 11:23:12 +0300, KennyTM~ <kennytm gmail.com> wrote:

 On Jun 14, 11 14:46, so wrote:
 On Tue, 14 Jun 2011 09:18:42 +0300, KennyTM~ <kennytm gmail.com> wrote:

 I'd rather have no reordering and allow hybrid call. Named argument is
 useful for specifying the nature of an argument. If the type is clear
 for all but one argument, the rest is just noisy redundant info.

fun(bool, bool, bool, bool, bool...) Isn't the type clear for every argument here?

By "type" I mean the purpose of an argument, e.g. the first 'int' in MoveWindow is an x-coordinate, the second is a y-coordinate, etc. Sorry I don't know of a better term. When what one argument does is clear for the caller, forcing NA on it just annoys the programmer.

This is the whole point of NAs, it is not clear, you need to check the function definition whenever you read the call.
 e.g.

 MoveWindow(hWnd, loc.x, loc.y, myWin.width, myWin.height,
 bRepaint:true);

 is no worse than

 MoveWindow(hWnd:hWnd, X:loc.x, Y:loc.y,
 nWidth:myWin.width, nHeight:myWin.height, bRepaint:true);

Reordering is important an example: fun(int a, int b=2, int c=3) If you want to name c but not b what are you going to do?

That's skipping, not really reordering. 'a' still precedes 'c'. Also, I'm not against reordering, but I'm against using reordering as a reason to abandon hybrid.

It is not a reason to abandon hybrid, it is a consequence of abandoning it.
 Named arguments isn't something to save typing.
 Also the first version of the MoveWindow indeed worse than the second,
 which again i think requires no explanation.

No, please explain. What does the extra hWnd, X, Y, nWidth, nHeight buy, when the respective arguments already show what they are?'

Matching, with fun(x:x, y:y) or fun(y:y, x:x) you are done, you don't ever need to check function definition again. With your reasoning you don't need named arguments at all. enum bRepaint=true; MoveWindow(... bRepaint)
Jun 14 2011
prev sibling next sibling parent so <so so.so> writes:
On Tue, 14 Jun 2011 12:58:30 +0300, KennyTM~ <kennytm gmail.com> wrote:

 And yet, with loc.x, myWin.width etc, you don't need to check the  
 definition to know those should be coordinates and widths.

loc.x on the caller side, it has no idea about function signature, and you don't know if it was 10th or 2nd argument in function. // definition fun(int x, int y) { } // call fun(x, y) // you need to check the definition if you think something wrong with parameters the second time you come here fun(y, x) // same fun(x:x, y:y) // you know there is nothing wrong with parameters fun(y:y, x:x) // same
 You don't need to abandon hybrid to enable reordering. Ary's suggestion,  
 for example, allows positional and named arguments to coexist.

Allows reordering by introducing two new order restrictions which i still had trouble understanding, sorry Ary :)
 Why do you need to check the function definition when you see 'moveTo(x,  
 y)'?

Same question, why do you need named arguments?
 enum bRepaint=true;
 MoveWindow(... bRepaint)

Non sequitur. In my MoveWindow example hWnd, loc and myWin are assumed to be variables you got from elsewhere. The names of these variables already provide the semantics to the readers, making NA for those arguments redundant. If they were constants it's nothing wrong with MoveWindow(hWnd, X:0, Y:0, nWidth:200, nHeight:200, bRepaint:true);

Again, they are variables you get on the caller side, they got no idea about function signature. Also i don't understand why some think allowing hybrid calls has any merit. Just search "named arguments" and first thing you'd see is calls with all arguments named, no exception. Allowing unnamed arguments and named arguments in one call doesn't make any sense to me, it is almost opposite to the reasons named arguments designed for, you don't even need to talk about its drawbacks like the complications and confusions.
Jun 14 2011
prev sibling next sibling parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2011-06-13 21:36:01 -0400, so <so so.so> said:

 IMO named arguments in D at least should do:
 
 - Reordering (since we got default parameters, even better)
 
 - It is enabled only if we have access to the function declaration.
 
 - In a function call we either use named arguments for all the 
 non-default  arguments or call it with the usual syntax. No hybrid 
 stuff, no confusion.
 
    fun(int a, int b, int c=3)
 
    fun(1, 2, 3) // fine - current
    fun(1, 2) // fine - current
 
    fun(a:1, b:3, c:5) // fine
    fun(a:1, b:3) // fine
    fun(b:1, c:3, a:5) // fine
    fun(b:1, a:3) // fine
    fun(b:1) // error
    fun(c:1) // error
    fun(2, b:1) // error
    fun(2, c:1) // error
    fun(2, c:2, 3) // error

There's much more to named arguments as it first appears. Have you thought about: 1. variadic arguments? 2. named template arguments? 3. template variadic arguments (tuples) and how they expand as function parameters? Also, with reordering, if you have two overloaded functions of this form: void fun(int a, string b) {} void fun(string b, int a) {} which one does this calls: fun(a: 1, b: "hello"); ? Does the call become ambiguous when using named arguments? It wouldn't be ambiguous if reordering wasn't allowed. What does C# does with this? -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jun 14 2011
next sibling parent KennyTM~ <kennytm gmail.com> writes:
On Jun 14, 11 20:34, Michel Fortin wrote:
 On 2011-06-13 21:36:01 -0400, so <so so.so> said:

 IMO named arguments in D at least should do:

 - Reordering (since we got default parameters, even better)

 - It is enabled only if we have access to the function declaration.

 - In a function call we either use named arguments for all the
 non-default arguments or call it with the usual syntax. No hybrid
 stuff, no confusion.

 fun(int a, int b, int c=3)

 fun(1, 2, 3) // fine - current
 fun(1, 2) // fine - current

 fun(a:1, b:3, c:5) // fine
 fun(a:1, b:3) // fine
 fun(b:1, c:3, a:5) // fine
 fun(b:1, a:3) // fine
 fun(b:1) // error
 fun(c:1) // error
 fun(2, b:1) // error
 fun(2, c:1) // error
 fun(2, c:2, 3) // error

There's much more to named arguments as it first appears. Have you thought about: 1. variadic arguments? 2. named template arguments?

partition!(ss:SwapStrategy.stable, predicate:"a>0") (r:[1,2,3,4]); Variadic is a real problem though. IIRC C# doesn't allow it.
 3. template variadic arguments (tuples) and how they expand as function
 parameters?

 Also, with reordering, if you have two overloaded functions of this form:

 void fun(int a, string b) {}
 void fun(string b, int a) {}

 which one does this calls:

 fun(a: 1, b: "hello");

 ? Does the call become ambiguous when using named arguments? It wouldn't
 be ambiguous if reordering wasn't allowed. What does C# does with this?

Looks like the last one get the precedence. At least for Mono (see http://ideone.com/REXC0). MSDN says ============================================ Use of named and optional arguments affects overload resolution in the following ways: - A method, indexer, or constructor is a candidate for execution if each of its parameters either is optional or corresponds, by name or by position, to a single argument in the calling statement, and that argument can be converted to the type of the parameter. - If more than one candidate is found, overload resolution rules for preferred conversions are applied to the arguments that are explicitly specified. Omitted arguments for optional parameters are ignored. - If two candidates are judged to be equally good, preference goes to a candidate that does not have optional parameters for which arguments were omitted in the call. This is a consequence of a general preference in overload resolution for candidates that have fewer parameters. ============================================ It doesn't cover your case. Of course this is bad. But this isn't much different from another solved problem... ---------------------------------------- void f(float s){} void f(double s){} void main() { f(3); } ---------------------------------------- x.d(5): Error: function x.f called with argument types: ((int)) matches both: x.f(float s) and: x.f(double s) ---------------------------------------- We could do the same for named arguments. ---------------------------------------- void fun(int a, string b) {} void fun(string b, int a) {} void main() { fun(a: 1, b: "hello"); } ---------------------------------------- x.d(5): Error: function x.fun called with argument names and types: ((int a, string b)) matches both: x.f(int a, string b) and: x.f(string b, int a) ----------------------------------------
Jun 14 2011
prev sibling parent "Nick Sabalausky" <a a.a> writes:
"Michel Fortin" <michel.fortin michelf.com> wrote in message 
news:it7kq2$26ha$1 digitalmars.com...
 Also, with reordering, if you have two overloaded functions of this form:

 void fun(int a, string b) {}
 void fun(string b, int a) {}

 which one does this calls:

 fun(a: 1, b: "hello");

 ? Does the call become ambiguous when using named arguments?

I'd say "yes". But even if you said "no, the winner is whichever matches the order given, if there is a perfect match", that would be fine too. I'd further argue that either way it's not a significant problem, because it seems that situation would be extremely rare. And the only realistic case I can think of where it would might occur is if the callee wants to allow re-ordered params. But that would already solved by re-orderable names arguments anyway.
 It wouldn't be ambiguous if reordering wasn't allowed. What does C# does 
 with this?

Jun 14 2011
prev sibling next sibling parent so <so so.so> writes:
On Tue, 14 Jun 2011 15:18:09 +0300, KennyTM~ <kennytm gmail.com> wrote:

 loc.x on the caller side, it has no idea about function signature, and
 you don't know if it was 10th or 2nd argument in function.

 // definition
 fun(int x, int y) {
 }

 // call
 fun(x, y) // you need to check the definition if you think something
 wrong with parameters the second time you come here
 fun(y, x) // same
 fun(x:x, y:y) // you know there is nothing wrong with parameters
 fun(y:y, x:x) // same

If you have no idea about the function signature, you have no idea about the parameter names either.

I think you are just resisting here, if you write a call once with named arguments, you documented it in place, the next time you visit this call all you need to see is in the call site.
 You see the difference between variables and generic constants?

       RECT bounds;
       GetWindowRect(hWnd, &bounds);

       writeln("Please enter the coordinates.");
       auto x = readln().chomp().to!int();
       auto y = readln().chomp().to!int();
       auto width = bounds.right - bounds.left;
       auto height = bounds.bottom - bounds.top;

       MoveWindow(hWnd, x, y, width, height, bRepaint:true);
 vs.

       writeln("Resetting window dimensions");
       ...
       MoveWindow(hWnd, X:0, Y:0, nWidth:800, nHeight:600, bRepaint:true);

 Named arguments provides clarification when the argument itself (e.g. 0,  
 false, true) is meaningless. But with a variable which itself provides a  
 meaning, forcing named argument on _every_argument_passed_ is just  
 annoying.

Looks like i am just repeating myself but i don't understand how is pssing constants meaningless and variables, and why do you even need named arguments for those? enum x=... enum y=... ... fun(x, y)
 Yet all well-known languages that support named arguments that support  
 reordering also support hybrid. (C# 4, VB 6, Python, CLisp, ...)

This is not an argument.
Jun 14 2011
prev sibling next sibling parent so <so so.so> writes:
On Tue, 14 Jun 2011 16:01:20 +0300, KennyTM~ <kennytm gmail.com> wrote:

 On Jun 14, 11 19:11, so wrote:
 [snip]
 Also i don't understand why some think allowing hybrid calls has any
 merit. Just search "named arguments" and first thing you'd see is calls
 with all arguments named, no exception. Allowing unnamed arguments and
 named arguments in one call doesn't make any sense to me, it is almost
 opposite to the reasons named arguments designed for, you don't even
 need to talk about its drawbacks like the complications and confusions.

And if you think it's complicated, you're just thinking in a too complicated way. The rule is simple. Say there is a function pure nothrow S parseString(S=const(char)[], C) (ref C[] input, out ConversionResult result, char quote='"', bool recognizePrefix=true) if (...); and you call it as string s = `"hello"`; ConversionResult detailResult; auto parsed = parseString(s, recognizePrefix:false, result:detailResult); The first step is identify all positional arguments ('s' here), and fill them in in-order. input <- s result <- ... quote <- ... recognizePrefix <- ... next, we match the named args input <- s result <- detailResult quote <- ... recognizePrefix <- false finally we fill in the optional parameters input <- s result <- detailResult quote <- '"' recognizePrefix <- false what's so complicated? Actually, reordering creates more complication than hybrid (e.g. ambiguity in selecting an overload).

So complicated because it took you this long to match the parameters with the variables, you still need to check function definition because you have parameters that have no match. These are the very things named arguments needs to solve or am i missing something? You could just drop it and go read the function signature everytime, it'd save you time :P
Jun 14 2011
prev sibling parent so <so so.so> writes:
 I'm just bringing up the fact. Why would you need to check the function  
 signature when reading

      MoveWindow(hWnd, loc.x, loc.y, myWin.width, myWin.height,
                 bRepaint:true);

 ? It's clear what each argument does. If you feel the need of  
 duplicating the same information, fine, write

      MoveWindow(hWnd:hWnd, X:loc.x, Y:loc.y,
                 nWidth:myWin.width, nHeight:myWin.height, bRepaint:true);

 in your code. But don't make it mandatory, it's a waste of time and  
 space when the writer just wants to clarify that 'true' is a bRepaint.

Waste of time? so is writing docs and comments, so is checking the library everytime you have trouble understanding a call. It is designed to ease understanding your own or others code. I have no idea how you can think about writing a few chars more as if something bad. In programming we waste our times not when we are actually writing but while doing everything else!
 Looks like i am just repeating myself but i don't understand how is
 pssing constants meaningless and variables, and why do you even need
 named arguments for those?

 enum x=...
 enum y=...
 ...
 fun(x, y)

If you want to disregard named argument, why go the complicated route and define enums? You could do as well fun(/*x*/0, /*y*/0);

No, you are the one suggesting that, in your example you called MoveWindow(hwnd) and said it was all you need, then i gave this example to prove if all you need is that, you don't need NAs anyways since it is just so easy to treat other things as "hwnd".
 (and yes I'm currently using it.) But the point is it's ugly. Heck why  
 do we need to defend NA. My point is only "hybrid should be allowed if I  
 want to".

It is ugly but it is not heck, it does nothing, it gives you no guaranties, compiler does no matching. It is no better than fun(0, 0). We came this far but we still don't think the NAs same way, and i am starting to lose my hope explaining myself.
 Yet all well-known languages that support named arguments that support
 reordering also support hybrid. (C# 4, VB 6, Python, CLisp, ...)

This is not an argument.

Neither is 'Just search "named arguments" and first thing you'd see is calls with all arguments named, no exception.'

Why not? first thing you would encounter is its prototype, its best usage that makes most sense, i told it because you seem to give its primary function no value at all.
 Maybe another argument: D's static struct initializer already supports  
 hybrid and reordering. Extending that to function arguments is natural.

 ------------------------------------
 struct S { int x; int y; }
 void main() {
      S s0 = {4, 5};
      S s1 = {x:4, 5};
      S s2 = {4, y:5};
      S s3 = {x:4, y:5};
 //  S s4 = {y:4, 5};    // error
      S s5 = {y:5, x:4};
 }
 ------------------------------------

I didn't know they work this way, i agree it is a good argument (finally we agree on something!) Though i have to say it looks quite confusing and verbose (rules). Then again, it looks like i am alone on this one, quite possibly i am wrong :)
Jun 15 2011
prev sibling parent so <so so.so> writes:
On Tue, 14 Jun 2011 15:34:53 +0300, Michel Fortin  
<michel.fortin michelf.com> wrote:

 There's much more to named arguments as it first appears. Have you  
 thought about:

 1. variadic arguments?

There is already a syntax for this in the language. fun(a:1, var:{3,5,7})
 2. named template arguments?

Do we need this?
 3. template variadic arguments (tuples) and how they expand as function  
 parameters?

This one is a bit tricky but wouldn't 1 also apply here?
 Also, with reordering, if you have two overloaded functions of this form:

 	void fun(int a, string b) {}
 	void fun(string b, int a) {}

Only solution i can think of to this would be changing argument names, otherwise an error.
Jun 14 2011