www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Pretty please: Named arguments

reply Bekenn <leaveme alone.com> writes:
Consider the following line from a project I'm playing around with:

	HRESULT hr = m_Device.Present(null, null, null, null);

Quick: What behavior does that third argument specify?  If you said, 
"Well, /obviously/, that's a handle to an alternative destination window 
for the render operation; by passing null, you're choosing not to 
provide an alternative render target." then... well, gee, I have no 
answer to that.

With named arguments, it becomes a bit easier to understand:

	HRESULT hr = m_Device.Present(pSourceRect: null, pDestRect: null, 
hDestWindowOverride: null, pDirtyRegion: null);

If I remember right, Python has this (optional) feature; I'm not aware 
of anyone ever complaining about it.  It also nicely provides a solution 
to the bool argument problem: 
http://blogs.msdn.com/b/oldnewthing/archive/2006/08/28/728349.aspx

But wait, there's more!

Named arguments get a +1 synergy bonus with default arguments.  When 
using parameter names to specify arguments, the order in which those 
arguments are passed no longer matters.  Imagine if the Present() method 
above provided the default argument null for each parameter:

interface IDirect3DDevice9 : IUnknown
{
	...
	HRESULT Present(const(RECT)* pSourceRect = null, const(RECT)* pDestRect 
= null, HWND hDestWindowOverride = null, const(RGNDATA)* pDirtyRegion = 
null);
	...
}

We can do this in the D binding without running afoul of any linkage 
issues, and it simplifies the Present() call for its most common usage, 
which I think is a good thing.  Now, let's say I'm doing something 
special; suppose I'm not worried about source and destination rectangles 
or dirty regions, but I do want to supply a different render target. 
With named arguments, that's easy to do without making things messy:

	HRESULT hr = m_Device.Present(hDestWindowOverride: hOverride);

Named arguments should also play nicely with positional arguments:

	auto wrappedString = wrap(reallyLongString, colmuns: 120, tabsize: 4);

Lastly, wouldn't be an entirely new feature; D already supports named 
arguments for static struct initializers.  I merely propose sharing the 
love with normal functions and struct literals.

Here are the rules I have in mind:

1) Named arguments are not a replacement for positional arguments. 
Arguments fall into three categories: positional, named positional, and 
named non-positional.  An argument is positional if no name is supplied. 
  An argument is named positional if a name is supplied and its position 
matches the parameter's position in the function declaration.  An 
argument is named non-positional if a name is supplied and either a) its 
position does not match the parameter's position in the function 
declaration, or b) it is immediately preceded by a named non-positional 
argument.

2) No positional argument may appear after a named non-positional argument.

3) Named non-positional arguments may appear in any order.


Potential problems:  The only problems I can foresee here are variations 
on the situation when there are two (or more) versions of a function 
with the same number, type, and names of parameters, but in non-matching 
order, like this:

void func(int a, char b);
void func(char b, int a);

In such a case, the compiler should diagnose an error if named arguments 
are employed.

Thoughts?
Feb 27 2011
next sibling parent reply Russel Winder <russel russel.org.uk> writes:
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Sun, 2011-02-27 at 23:03 -0800, Bekenn wrote:
[ . . . ]
 If I remember right, Python has this (optional) feature; I'm not aware=

 of anyone ever complaining about it.  It also nicely provides a solution=

 to the bool argument problem:=20
 http://blogs.msdn.com/b/oldnewthing/archive/2006/08/28/728349.aspx
=20
 But wait, there's more!
=20
 Named arguments get a +1 synergy bonus with default arguments.  When=20
 using parameter names to specify arguments, the order in which those=20
 arguments are passed no longer matters.  Imagine if the Present() method=

 above provided the default argument null for each parameter:

Pythons parameter passing system is fantastic: the combination of positional parameters, keyword arguments, default values, "rest of positionals", "rest of keyword arguments" means that handling C and C++ libraries where many functions/methods have many parameters (some of the graphics libraries have functions with 10s of parameters) far easier than using C or C++ directly. It is no surprise to me that the scientific community is taking to the Python/C/C++ combination in droves. Python is a great coordination and top-level UI language leaving the grunt computation to C and C++ -- well to be honest there is a huge amount of Fortran as well. It is clear to me that most of the "Big Science" codes need a rewrite, but it just isn't going to happen, so for all "number crunching" that doesn't involve brand new codes, interfacing to C, C++ and Fortran is mandatory. It should be noted that the Python parameter passing only works as beautifully as it does because everything in Python is handled with dictionaries (aka maps).=20 [ . . . ]
 1) Named arguments are not a replacement for positional arguments.=20
 Arguments fall into three categories: positional, named positional, and=

 named non-positional.  An argument is positional if no name is supplied.=

   An argument is named positional if a name is supplied and its position=

 matches the parameter's position in the function declaration.  An=20
 argument is named non-positional if a name is supplied and either a) its=

 position does not match the parameter's position in the function=20
 declaration, or b) it is immediately preceded by a named non-positional=

 argument.
=20
 2) No positional argument may appear after a named non-positional argumen=

=20
 3) Named non-positional arguments may appear in any order.

Or just pick up the Python approach in its entirety? The huge downside of any named parameter approach is that you have data coupling between the source of the callee and the caller. This is fine in a language such as Python where you distribute source and documentation tools so you can always find out the names of parameters, this is going to be a bit of a problem in languages where only the compiled form may be the only distributed form. Programmers rely on some other form of documentation other than the source and this leads to error,
 Potential problems:  The only problems I can foresee here are variations=

 on the situation when there are two (or more) versions of a function=20
 with the same number, type, and names of parameters, but in non-matching=

 order, like this:
=20
 void func(int a, char b);
 void func(char b, int a);
=20
 In such a case, the compiler should diagnose an error if named arguments=

 are employed.
=20
 Thoughts?

The Python mechanism relies on the fact that despatch is by name and not by signature. Languages that dispatch by signature will have significantly greater problems!=20 --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel russel.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Feb 27 2011
next sibling parent reply Bekenn <leaveme alone.com> writes:
On 2/27/2011 11:32 PM, Russel Winder wrote:
 The Python mechanism relies on the fact that despatch is by name and not
 by signature.  Languages that dispatch by signature will have
 significantly greater problems!

I don't follow; the compiler has to look up the correct function signature whether you use named arguments or not. How is this significantly different?
Feb 27 2011
parent reply Bekenn <leaveme alone.com> writes:
On 2/28/2011 12:04 AM, Jonathan M Davis wrote:
 You could be linking to code where you don't _have_ the source and don't _have_
 the names of the variables. It's all done by the function signature in C, C++,
 Java, C#, D, etc. The names of the variables are completely irrelevant to
 calling the function, and so any linkers that follow C conventions (as with
 happens with D) _must_ be able to deal with function calls based on their
 signatures. That doesn't necessarily mean that it would be _impossible_ to
find a
 way to have named arguments in D, but it makes it _far_ harder.

 - Jonathna M Davis

Again, I don't see why that's a problem; you can't call a function if you don't have a function declaration somewhere (perhaps in a .di file). The compiler would do parameter name lookup based on the current module's view of the function space. If you truly don't have a declaration, then that means you're calling through a function pointer or a delegate. Again, no problem: either a) the function pointer or the delegate specifies names for the arguments, or b) it doesn't, in which case you simply can't use named arguments. I'm absolutely not suggesting that parameter names should be part of the ABI, nor am I suggesting that function declarations must present parameter names; if names aren't available to the module at compile time, then you can't use named arguments. Where's the problem?
Feb 28 2011
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 2/28/11 2:22 AM, Bekenn wrote:
 On 2/28/2011 12:04 AM, Jonathan M Davis wrote:
 You could be linking to code where you don't _have_ the source and
 don't _have_
 the names of the variables. It's all done by the function signature in
 C, C++,
 Java, C#, D, etc. The names of the variables are completely irrelevant to
 calling the function, and so any linkers that follow C conventions (as
 with
 happens with D) _must_ be able to deal with function calls based on their
 signatures. That doesn't necessarily mean that it would be
 _impossible_ to find a
 way to have named arguments in D, but it makes it _far_ harder.

 - Jonathna M Davis

Again, I don't see why that's a problem; you can't call a function if you don't have a function declaration somewhere (perhaps in a .di file). The compiler would do parameter name lookup based on the current module's view of the function space. If you truly don't have a declaration, then that means you're calling through a function pointer or a delegate. Again, no problem: either a) the function pointer or the delegate specifies names for the arguments, or b) it doesn't, in which case you simply can't use named arguments. I'm absolutely not suggesting that parameter names should be part of the ABI, nor am I suggesting that function declarations must present parameter names; if names aren't available to the module at compile time, then you can't use named arguments. Where's the problem?

I don't see any. One more thing, order of evaluation should still be left-to-right, not in order of arguments. This means the feature cannot be a syntactic rewrite (not a big issue, but definitely something to keep in mind). Andrei
Feb 28 2011
next sibling parent reply Bekenn <leaveme alone.com> writes:
On 2/28/11 5:48 AM, Andrei Alexandrescu wrote:
 One more thing, order of evaluation should still be left-to-right, not
 in order of arguments. This means the feature cannot be a syntactic
 rewrite (not a big issue, but definitely something to keep in mind).


 Andrei

I was thinking that order of evaluation should remain lexically left-to-right at the point of call (that is, in the order the arguments are specified, with any remaining default parameters coming after); is there a reason that would be bad or wouldn't work?
Feb 28 2011
next sibling parent Jim <bitcirkel yahoo.com> writes:
Bekenn Wrote:

 On 2/28/11 5:48 AM, Andrei Alexandrescu wrote:
 One more thing, order of evaluation should still be left-to-right, not
 in order of arguments. This means the feature cannot be a syntactic
 rewrite (not a big issue, but definitely something to keep in mind).


 Andrei

I was thinking that order of evaluation should remain lexically left-to-right at the point of call (that is, in the order the arguments are specified, with any remaining default parameters coming after); is there a reason that would be bad or wouldn't work?

No, the called function could be from a linked library, for all we know. Reordering the evaluation of the arguments would not have any effect on the function itself. Left-to-right evaluation at the point of call would concur with the Principle of Least Astonishment: void fun(int foo, int bar); int moo(); // might have side-effects! fun(bar:moo(), foo:moo());
Feb 28 2011
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 2/28/11 12:38 PM, Bekenn wrote:
 On 2/28/11 5:48 AM, Andrei Alexandrescu wrote:
 One more thing, order of evaluation should still be left-to-right, not
 in order of arguments. This means the feature cannot be a syntactic
 rewrite (not a big issue, but definitely something to keep in mind).


 Andrei

I was thinking that order of evaluation should remain lexically left-to-right at the point of call (that is, in the order the arguments are specified, with any remaining default parameters coming after); is there a reason that would be bad or wouldn't work?

I meant the same as you. Andrei
Feb 28 2011
parent Stewart Gordon <smjg_1998 yahoo.com> writes:
On 01/03/2011 11:59, spir wrote:
<snip>
 On the other hand, I would like it still be possible to write:
 void f (x=0, y=0) {...}
 ...
 f(y=1);

It would. And it would still set the variable y in the calling scope to 1, and then call f(1, 0). Stewart.
Mar 02 2011
prev sibling parent bearophile <bearophileHUGS lycos.com> writes:
Andrei:

 One more thing, order of evaluation should still be left-to-right, not 
 in order of arguments. This means the feature cannot be a syntactic 
 rewrite (not a big issue, but definitely something to keep in mind).

In this case then I suggest the compiler to just refuse the compilation of that line of code. Better to disallow something than allowing something that breaks one of the (future!) D rules. Bye, bearophile
Feb 28 2011
prev sibling parent spir <denis.spir gmail.com> writes:
On 03/01/2011 02:36 AM, Andrei Alexandrescu wrote:
 On 2/28/11 12:38 PM, Bekenn wrote:
 On 2/28/11 5:48 AM, Andrei Alexandrescu wrote:
 One more thing, order of evaluation should still be left-to-right, not
 in order of arguments. This means the feature cannot be a syntactic
 rewrite (not a big issue, but definitely something to keep in mind).


 Andrei

I was thinking that order of evaluation should remain lexically left-to-right at the point of call (that is, in the order the arguments are specified, with any remaining default parameters coming after); is there a reason that would be bad or wouldn't work?

I meant the same as you.

I agree with this. Keeping order makes things simpler, probably helps implementation of the feature (I guess), and removes nearly nothing imo. Named params are about helping reading code. On the other hand, I would like it still be possible to write: void f (x=0, y=0) {...} ... f(y=1); This is unorderd strictly speaking... (Sorry for my possibly wrong English) Denis -- _________________ vita es estrany spir.wikidot.com
Mar 01 2011
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 2/28/11 1:32 AM, Russel Winder wrote:
 The huge downside of any named parameter approach is that you have data
 coupling between the source of the callee and the caller.  This is fine
 in a language such as Python where you distribute source and
 documentation tools so you can always find out the names of parameters,
 this is going to be a bit of a problem in languages where only the
 compiled form may be the only distributed form.  Programmers rely on
 some other form of documentation other than the source and this leads to
 error,

It's not all that bad. Walter and I discussed a couple of times adding such a feature. As long as the function signature in the .d or .di file does specify a parameter name, that can be used.
 Potential problems:  The only problems I can foresee here are variations
 on the situation when there are two (or more) versions of a function
 with the same number, type, and names of parameters, but in non-matching
 order, like this:

 void func(int a, char b);
 void func(char b, int a);

 In such a case, the compiler should diagnose an error if named arguments
 are employed.

 Thoughts?

The Python mechanism relies on the fact that despatch is by name and not by signature. Languages that dispatch by signature will have significantly greater problems!

A good subset of Python's approach to parameter passing sugar can be done without using maps or dispatch by name. Andrei
Feb 28 2011
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Sunday 27 February 2011 23:40:41 Bekenn wrote:
 On 2/27/2011 11:32 PM, Russel Winder wrote:
 The Python mechanism relies on the fact that despatch is by name and not
 by signature.  Languages that dispatch by signature will have
 significantly greater problems!

I don't follow; the compiler has to look up the correct function signature whether you use named arguments or not. How is this significantly different?

You could be linking to code where you don't _have_ the source and don't _have_ the names of the variables. It's all done by the function signature in C, C++, Java, C#, D, etc. The names of the variables are completely irrelevant to calling the function, and so any linkers that follow C conventions (as with happens with D) _must_ be able to deal with function calls based on their signatures. That doesn't necessarily mean that it would be _impossible_ to find a way to have named arguments in D, but it makes it _far_ harder. - Jonathna M Davis
Feb 28 2011
prev sibling next sibling parent "Vladimir Panteleev" <vladimir thecybershadow.net> writes:
On Mon, 28 Feb 2011 10:04:31 +0200, Jonathan M Davis <jmdavisProg gmx.com>  
wrote:

 On Sunday 27 February 2011 23:40:41 Bekenn wrote:
 On 2/27/2011 11:32 PM, Russel Winder wrote:
 The Python mechanism relies on the fact that despatch is by name and  

 by signature.  Languages that dispatch by signature will have
 significantly greater problems!

I don't follow; the compiler has to look up the correct function signature whether you use named arguments or not. How is this significantly different?

You could be linking to code where you don't _have_ the source and don't _have_ the names of the variables. It's all done by the function signature in C, C++, Java, C#, D, etc. The names of the variables are completely irrelevant to calling the function, and so any linkers that follow C conventions (as with happens with D) _must_ be able to deal with function calls based on their signatures. That doesn't necessarily mean that it would be _impossible_ to find a way to have named arguments in D, but it makes it _far_ harder.

I don't see the problem here. Either mangle the argument names (just as C++ and D mangle argument types), or just ignore this problem completely and use the parameter names in the function declaration. -- Best regards, Vladimir mailto:vladimir thecybershadow.net
Feb 28 2011
prev sibling next sibling parent spir <denis.spir gmail.com> writes:
On 02/28/2011 08:03 AM, Bekenn wrote:
 Consider the following line from a project I'm playing around with:

 HRESULT hr = m_Device.Present(null, null, null, null);

 Quick: What behavior does that third argument specify? If you said, "Well,
 /obviously/, that's a handle to an alternative destination window for the
 render operation; by passing null, you're choosing not to provide an
 alternative render target." then... well, gee, I have no answer to that.

 With named arguments, it becomes a bit easier to understand:

 HRESULT hr = m_Device.Present(pSourceRect: null, pDestRect: null,
 hDestWindowOverride: null, pDirtyRegion: null);

 If I remember right, Python has this (optional) feature; I'm not aware of
 anyone ever complaining about it. It also nicely provides a solution to the
 bool argument problem:
 http://blogs.msdn.com/b/oldnewthing/archive/2006/08/28/728349.aspx

 But wait, there's more!

 Named arguments get a +1 synergy bonus with default arguments. When using
 parameter names to specify arguments, the order in which those arguments are
 passed no longer matters. Imagine if the Present() method above provided the
 default argument null for each parameter:

 interface IDirect3DDevice9 : IUnknown
 {
 ...
 HRESULT Present(const(RECT)* pSourceRect = null, const(RECT)* pDestRect = null,
 HWND hDestWindowOverride = null, const(RGNDATA)* pDirtyRegion = null);
 ...
 }

 We can do this in the D binding without running afoul of any linkage issues,
 and it simplifies the Present() call for its most common usage, which I think
 is a good thing. Now, let's say I'm doing something special; suppose I'm not
 worried about source and destination rectangles or dirty regions, but I do want
 to supply a different render target. With named arguments, that's easy to do
 without making things messy:

 HRESULT hr = m_Device.Present(hDestWindowOverride: hOverride);

 Named arguments should also play nicely with positional arguments:

 auto wrappedString = wrap(reallyLongString, colmuns: 120, tabsize: 4);

 Lastly, wouldn't be an entirely new feature; D already supports named arguments
 for static struct initializers. I merely propose sharing the love with normal
 functions and struct literals.

 Here are the rules I have in mind:

 1) Named arguments are not a replacement for positional arguments. Arguments
 fall into three categories: positional, named positional, and named
 non-positional. An argument is positional if no name is supplied. An argument
 is named positional if a name is supplied and its position matches the
 parameter's position in the function declaration. An argument is named
 non-positional if a name is supplied and either a) its position does not match
 the parameter's position in the function declaration, or b) it is immediately
 preceded by a named non-positional argument.

 2) No positional argument may appear after a named non-positional argument.

 3) Named non-positional arguments may appear in any order.


 Potential problems: The only problems I can foresee here are variations on the
 situation when there are two (or more) versions of a function with the same
 number, type, and names of parameters, but in non-matching order, like this:

 void func(int a, char b);
 void func(char b, int a);

 In such a case, the compiler should diagnose an error if named arguments are
 employed.

 Thoughts?

I'm all for a feature of named arguments. I consider it a _base_ feature D is sadly lacking for the moment. Unlike tons of other issues, it is not a rare, weird, or sophisticated request. Thus, it should have the highest priority once 64-bit support has reached a workable state. There does not seem to be any feature requests for this on the issue tracker. On the other hand, this feature may be very simple and still handy: either all args are named, or none. E basta! Denis -- _________________ vita es estrany spir.wikidot.com
Feb 28 2011
prev sibling next sibling parent spir <denis.spir gmail.com> writes:
On 02/28/2011 08:32 AM, Russel Winder wrote:
 Thoughts?

by signature. Languages that dispatch by signature will have significantly greater problems!

The Python system also has a weak point: confusion of 'optional' and 'default' notions. These are 2 orthogonal aspects python forces you to mess up. There are optional args with no default values, and mandatory ones with defaults. If you want to define an optional arg, python wants you to "invent" a fake default value. This is bad --even more in that it tends to load 'None'(common choice for fake value) with application semantics. Denis -- _________________ vita es estrany spir.wikidot.com
Feb 28 2011
prev sibling next sibling parent Russel Winder <russel russel.org.uk> writes:
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Sun, 2011-02-27 at 23:40 -0800, Bekenn wrote:
 On 2/27/2011 11:32 PM, Russel Winder wrote:
 The Python mechanism relies on the fact that despatch is by name and no=


 by signature.  Languages that dispatch by signature will have
 significantly greater problems!

I don't follow; the compiler has to look up the correct function=20 signature whether you use named arguments or not. How is this=20 significantly different?

In C, C++ and D yes, in Python despatch is only by function name, not by signature -- exactly because of the parameter passing mechanism. Put it another way, Python does not have function overloading. --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel russel.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Feb 28 2011
prev sibling next sibling parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2011-02-28 02:03:46 -0500, Bekenn <leaveme alone.com> said:

 Potential problems:  The only problems I can foresee here are 
 variations on the situation when there are two (or more) versions of a 
 function with the same number, type, and names of parameters, but in 
 non-matching order, like this:
 
 void func(int a, char b);
 void func(char b, int a);
 
 In such a case, the compiler should diagnose an error if named 
 arguments are employed.
 
 Thoughts?

Another problem is what happens if you override a function by using different parameter names. For instance: class A { void func(int foo); } class B : A { void func(int bar); } Currently, the above is allowed. Would it now become an error? I think it'd be much easier to support named arguments if we didn't allow reordering. I know I'm stripping the proposal from one of its main benefits, but I think the essence remains. This would make the rather common pattern of adding a comment for each argument compiler-verifiable without disrupting things too much: draw(null, // text null, // font 12, // size 0, // flags ); draw(text: null, font: null, size: 12, flags: 0); It would be implemented as a check for equality of the argument names after overload resolution. No ABI change, no interaction with overloading, just an extra check that if an argument name is specified it must match the one in the declaration. There'd still be a funny interaction with overriding (see my first example), but you can always leave your argument unnamed if the definition keep changing the name in unpredictable ways. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Feb 28 2011
next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 28 Feb 2011 07:41:06 -0500, Michel Fortin  
<michel.fortin michelf.com> wrote:

 On 2011-02-28 02:03:46 -0500, Bekenn <leaveme alone.com> said:

 Potential problems:  The only problems I can foresee here are  
 variations on the situation when there are two (or more) versions of a  
 function with the same number, type, and names of parameters, but in  
 non-matching order, like this:
  void func(int a, char b);
 void func(char b, int a);
  In such a case, the compiler should diagnose an error if named  
 arguments are employed.
  Thoughts?

Another problem is what happens if you override a function by using different parameter names. For instance: class A { void func(int foo); } class B : A { void func(int bar); } Currently, the above is allowed. Would it now become an error? I think it'd be much easier to support named arguments if we didn't allow reordering. I know I'm stripping the proposal from one of its main benefits, but I think the essence remains. This would make the rather common pattern of adding a comment for each argument compiler-verifiable without disrupting things too much: draw(null, // text null, // font 12, // size 0, // flags ); draw(text: null, font: null, size: 12, flags: 0); It would be implemented as a check for equality of the argument names after overload resolution. No ABI change, no interaction with overloading, just an extra check that if an argument name is specified it must match the one in the declaration. There'd still be a funny interaction with overriding (see my first example), but you can always leave your argument unnamed if the definition keep changing the name in unpredictable ways.

All these 'what if' ambiguities are simple to resolve -- if you use positional arguments, it works. If you use named arguments, and it matches more than one overload, it fails. In fact, the case you give is unambiguous -- if you have an A, you can use foo, if you have a B, you can use bar. Note that the confusion is all to the person, and is completely avoidable. It's like naming your arguments xy234m5 -- nobody knows what that means, so just choose a better name. But it's not illegal. I would say this would be a huge improvement to D. But I would also say from my recollection, Walter is very against this. I think it would take a motivated developer creating a pull request to get it done... -Steve
Feb 28 2011
parent reply bearophile <bearophileHUGS lycos.com> writes:
Steven Schveighoffer:

 I would say this would be a huge improvement to D.  But I would also say  
  from my recollection, Walter is very against this.  I think it would take  
 a motivated developer creating a pull request to get it done...

Well implemented named arguments are my #1 enhancement request for D (my #2 request is the tuple unpacking syntax, another thing that's useful all the time). They are present in some languages as Python. Or in Ada language, where they are named "named arguments": http://en.wikibooks.org/wiki/Ada_Programming/Subprograms#Named_parameters In recent C# versions: http://msdn.microsoft.com/en-us/library/dd264739.aspx http://geekswithblogs.net/michelotti/archive/2009/01/22/c-4.0-named-parameters-for-bett r-code-quality.aspx ) If you use named arguments in Python, you learn how much useful they are, I use them often. They don't increase much the complexity of the language for the programmer, they make code less bug-prone, more handy to write, and more self-annotated with compiled-verified annotations. You have a function like: void drawRectangle(int height, int width) {...} You call it with: drawRectangle(640, 480); But you may be wrong, having inverted the two values: drawRectangle(480, 640); With good named argument you remove that bug source: drawRectangle(width: 640, height: 480); Named arguments are so useful that they justify little changes in the compiler too, if necessary. Bye, bearophile
Feb 28 2011
parent Bekenn <leaveme alone.com> writes:
On 2/28/11 5:11 AM, bearophile wrote:
 In recent C# versions:
 http://msdn.microsoft.com/en-us/library/dd264739.aspx
 http://geekswithblogs.net/michelotti/archive/2009/01/22/c-4.0-named-parameters-for-bett
r-code-quality.aspx  )

I had no idea C# had adopted this feature. Thanks! Looking through that first link, it looks like their rules are very nearly a match for what I came up with; the only difference I can see is that they'd prohibit the use of positional arguments following a named argument (even if the named argument is in the expected position). My argument in favor of named positional arguments (after which you *can* continue to specify positional arguments) is that the name becomes a compiler-verified annotation.
Feb 28 2011
prev sibling next sibling parent reply spir <denis.spir gmail.com> writes:
On 02/28/2011 01:41 PM, Michel Fortin wrote:
 On 2011-02-28 02:03:46 -0500, Bekenn <leaveme alone.com> said:

 Potential problems: The only problems I can foresee here are variations on
 the situation when there are two (or more) versions of a function with the
 same number, type, and names of parameters, but in non-matching order, like
 this:

 void func(int a, char b);
 void func(char b, int a);

 In such a case, the compiler should diagnose an error if named arguments are
 employed.

 Thoughts?

Another problem is what happens if you override a function by using different parameter names. For instance: class A { void func(int foo); } class B : A { void func(int bar); } Currently, the above is allowed. Would it now become an error? I think it'd be much easier to support named arguments if we didn't allow reordering. I know I'm stripping the proposal from one of its main benefits, but I think the essence remains. This would make the rather common pattern of adding a comment for each argument compiler-verifiable without disrupting things too much: draw(null, // text null, // font 12, // size 0, // flags ); draw(text: null, font: null, size: 12, flags: 0); It would be implemented as a check for equality of the argument names after overload resolution. No ABI change, no interaction with overloading, just an extra check that if an argument name is specified it must match the one in the declaration.

+++ Make things simple! Since positional arguments is the main & historic parameter-passing method, just keep order. For me, allowing unordered arguments is just a (somewhat nice) side-effect of naming. The huge gain by far is "semantic unload" talen out of programmer shoulders ; and self-documentation. Just like in your example. The latter point (self-doc) also has a big benefit in terms of language learning: if code samples use named args, then understanding and memorising common funcs and other tools can be far easier.
 There'd still be a funny interaction with overriding (see my first example),
 but you can always leave your argument unnamed if the definition keep changing
 the name in unpredictable ways.

I would say: name mismatch --> error. Meaning "x.func(foo=1)" throws if method lookup ends up selecting "B.func" (meaning x is a B); conversely "x.func(bar=1)" throws if method lookup ends up selecting "A.func" (meaning x is an A but not a B). Denis -- _________________ vita es estrany spir.wikidot.com
Feb 28 2011
parent Bekenn <leaveme alone.com> writes:
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.
Feb 28 2011
prev sibling parent Bekenn <leaveme alone.com> writes:
On 2/28/11 4:41 AM, Michel Fortin wrote:
 Another problem is what happens if you override a function by using
 different parameter names. For instance:

 class A {
 void func(int foo);
 }
 class B : A {
 void func(int bar);
 }

 Currently, the above is allowed. Would it now become an error?

Definitely not an error! This feature should not break any existing code. Method lookup already happens based on the static type of your object reference; that shouldn't change: A a = new A; a.func(foo = 3); // ok a.func(bar = 3); // Error, argument name does not match parameter name B b = new B; b.func(foo = 3); // Error, argument name does not match parameter name b.func(bar = 3); // ok A c = new B; c.func(foo = 3); // ok c.func(bar = 3); // Error
Feb 28 2011
prev sibling next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
I prefer using the equals sign:
foo(action = "dofoo", times = 100)

This is how Python does it.
Feb 28 2011
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 2/28/11 6:48 AM, Andrej Mitrovic wrote:
 I prefer using the equals sign:
 foo(action = "dofoo", times = 100)

 This is how Python does it.

// in a module far, far away void fun(double x); // In a module importing it int x = 42; fun(x = 43); Andrei
Feb 28 2011
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 2/28/11 8:16 AM, Andrej Mitrovic wrote:
 On 2/28/11, Andrei Alexandrescu<SeeWebsiteForEmail erdani.org>  wrote:
 On 2/28/11 6:48 AM, Andrej Mitrovic wrote:
 I prefer using the equals sign:
 foo(action = "dofoo", times = 100)

 This is how Python does it.

// in a module far, far away void fun(double x); // In a module importing it int x = 42; fun(x = 43); Andrei

Yes, I've mentioned I was wrong in my next-to-last post. :)

Apologies - I replied to posts this morning as I was seeing them, a practice I need to change. Andrei
Feb 28 2011
prev sibling next sibling parent reply spir <denis.spir gmail.com> writes:
On 02/28/2011 02:01 PM, Steven Schveighoffer wrote:
 On Mon, 28 Feb 2011 07:48:24 -0500, Andrej Mitrovic
 <andrej.mitrovich gmail.com> wrote:

 I prefer using the equals sign:
 foo(action = "dofoo", times = 100)

 This is how Python does it.

This syntax already means something in D: string action; int times; foo(action = "dofoo", times = 100); // set action to "dofoo" and times to 100 and pass those to the function.

This is *very* bad imo. But since it's inherited from C we cannot change it (acoording to D design principles). So, let's use ':'. Denis -- _________________ vita es estrany spir.wikidot.com
Feb 28 2011
next sibling parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2011-02-28 09:34:30 -0500, spir <denis.spir gmail.com> said:

 So, let's use ':'.

Note however that ':' already has a meaning in templates arguments. Using ':' for named function arguments would preclude having named template arguments (or force template arguments to use yet another syntax). -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Feb 28 2011
next sibling parent Michel Fortin <michel.fortin michelf.com> writes:
On 2011-02-28 09:55:54 -0500, Michel Fortin <michel.fortin michelf.com> said:

 On 2011-02-28 09:34:30 -0500, spir <denis.spir gmail.com> said:
 
 So, let's use ':'.

Note however that ':' already has a meaning in templates arguments. Using ':' for named function arguments would preclude having named template arguments (or force template arguments to use yet another syntax).

Oops, sorry. I was mixing up template definition and template instanciation. Turns out there's no real problem: template Test(T : U) { } Test!(T: int); -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Feb 28 2011
prev sibling next sibling parent spir <denis.spir gmail.com> writes:
On 02/28/2011 04:02 PM, Steven Schveighoffer wrote:
 On Mon, 28 Feb 2011 09:55:54 -0500, Michel Fortin <michel.fortin michelf.com>
 wrote:

 On 2011-02-28 09:34:30 -0500, spir <denis.spir gmail.com> said:

 So, let's use ':'.

Note however that ':' already has a meaning in templates arguments. Using ':' for named function arguments would preclude having named template arguments (or force template arguments to use yet another syntax).

I think you are confusing template declarations with template instantiations. ':' is not used in instantiations (that I know of) e.g. the usage would be: template foo(T = int, U = string) {...} foo!(U : int)...;

Yes, but the semantic conflict remains: on left hand, subtyping; on right hand plain naming. Denis -- _________________ vita es estrany spir.wikidot.com
Feb 28 2011
prev sibling next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
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. Bye, bearophile
Feb 28 2011
parent Bekenn <leaveme alone.com> writes:
On 2/28/11 11:53 AM, spir wrote:
 Agreed, and I'm not for adding non-obvious "signs". D is not Perl. Or
 else use ':=' ?

 Denis

I think we should stick with ':' due to its existing use in static struct initializers.
Feb 28 2011
prev sibling next sibling parent spir <denis.spir gmail.com> writes:
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
Feb 28 2011
prev sibling next sibling parent spir <denis.spir gmail.com> writes:
On 02/28/2011 08:39 PM, Steven Schveighoffer wrote:
 On Mon, 28 Feb 2011 14:32:52 -0500, Andrej Mitrovic
 <andrej.mitrovich gmail.com> wrote:

 On 2/28/11, spir <denis.spir gmail.com> wrote:
 But this conflict already exists with the
 usage
 of ':' in dyn array notation

Wait, when is ':' used with dynamic arrays?

Think he meant AA.

You're right, Steve. Sorry, distraction... Denis -- _________________ vita es estrany spir.wikidot.com
Feb 28 2011
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2011-02-28 20:39, Steven Schveighoffer wrote:
 On Mon, 28 Feb 2011 14:32:52 -0500, Andrej Mitrovic
 <andrej.mitrovich gmail.com> wrote:

 On 2/28/11, spir <denis.spir gmail.com> wrote:
 But this conflict already exists with the
 usage
 of ':' in dyn array notation

Wait, when is ':' used with dynamic arrays?

Think he meant AA. -Steve

Or static arrays. -- /Jacob Carlborg
Feb 28 2011
prev sibling parent spir <denis.spir gmail.com> writes:
On 02/28/2011 03:55 PM, Michel Fortin wrote:
 On 2011-02-28 09:34:30 -0500, spir <denis.spir gmail.com> said:

 So, let's use ':'.

Note however that ':' already has a meaning in templates arguments. Using ':' for named function arguments would preclude having named template arguments (or force template arguments to use yet another syntax).

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... Denis -- _________________ vita es estrany spir.wikidot.com
Feb 28 2011
prev sibling parent Bekenn <leaveme alone.com> writes:
On 2/28/11 4:48 AM, Andrej Mitrovic wrote:
 I prefer using the equals sign:
 foo(action = "dofoo", times = 100)

 This is how Python does it.

I went with : because that's what's already used in static struct initializers.
Feb 28 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 28 Feb 2011 07:48:24 -0500, Andrej Mitrovic  
<andrej.mitrovich gmail.com> wrote:

 I prefer using the equals sign:
 foo(action = "dofoo", times = 100)

 This is how Python does it.

This syntax already means something in D: string action; int times; foo(action = "dofoo", times = 100); // set action to "dofoo" and times to 100 and pass those to the function. -Steve
Feb 28 2011
prev sibling next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2011-02-28 08:03, Bekenn wrote:
 Consider the following line from a project I'm playing around with:

 HRESULT hr = m_Device.Present(null, null, null, null);

 Quick: What behavior does that third argument specify? If you said,
 "Well, /obviously/, that's a handle to an alternative destination window
 for the render operation; by passing null, you're choosing not to
 provide an alternative render target." then... well, gee, I have no
 answer to that.

 With named arguments, it becomes a bit easier to understand:

 HRESULT hr = m_Device.Present(pSourceRect: null, pDestRect: null,
 hDestWindowOverride: null, pDirtyRegion: null);

 If I remember right, Python has this (optional) feature; I'm not aware
 of anyone ever complaining about it. It also nicely provides a solution
 to the bool argument problem:
 http://blogs.msdn.com/b/oldnewthing/archive/2006/08/28/728349.aspx

 But wait, there's more!

 Named arguments get a +1 synergy bonus with default arguments. When
 using parameter names to specify arguments, the order in which those
 arguments are passed no longer matters. Imagine if the Present() method
 above provided the default argument null for each parameter:

 interface IDirect3DDevice9 : IUnknown
 {
 ...
 HRESULT Present(const(RECT)* pSourceRect = null, const(RECT)* pDestRect
 = null, HWND hDestWindowOverride = null, const(RGNDATA)* pDirtyRegion =
 null);
 ...
 }

 We can do this in the D binding without running afoul of any linkage
 issues, and it simplifies the Present() call for its most common usage,
 which I think is a good thing. Now, let's say I'm doing something
 special; suppose I'm not worried about source and destination rectangles
 or dirty regions, but I do want to supply a different render target.
 With named arguments, that's easy to do without making things messy:

 HRESULT hr = m_Device.Present(hDestWindowOverride: hOverride);

 Named arguments should also play nicely with positional arguments:

 auto wrappedString = wrap(reallyLongString, colmuns: 120, tabsize: 4);

 Lastly, wouldn't be an entirely new feature; D already supports named
 arguments for static struct initializers. I merely propose sharing the
 love with normal functions and struct literals.

 Here are the rules I have in mind:

 1) Named arguments are not a replacement for positional arguments.
 Arguments fall into three categories: positional, named positional, and
 named non-positional. An argument is positional if no name is supplied.
 An argument is named positional if a name is supplied and its position
 matches the parameter's position in the function declaration. An
 argument is named non-positional if a name is supplied and either a) its
 position does not match the parameter's position in the function
 declaration, or b) it is immediately preceded by a named non-positional
 argument.

 2) No positional argument may appear after a named non-positional argument.

 3) Named non-positional arguments may appear in any order.


 Potential problems: The only problems I can foresee here are variations
 on the situation when there are two (or more) versions of a function
 with the same number, type, and names of parameters, but in non-matching
 order, like this:

 void func(int a, char b);
 void func(char b, int a);

 In such a case, the compiler should diagnose an error if named arguments
 are employed.

 Thoughts?

It's possible to implement this as a library: http://dsource.org/projects/orange/browser/orange/util/Reflection.d#L135 Not a complete solution but it works. -- /Jacob Carlborg
Feb 28 2011
parent reply Bekenn <leaveme alone.com> writes:
On 2/28/11 5:05 AM, Jacob Carlborg wrote:
 It's possible to implement this as a library:
 http://dsource.org/projects/orange/browser/orange/util/Reflection.d#L135

 Not a complete solution but it works.

That has scary syntax; no thanks.
Feb 28 2011
parent "Nick Sabalausky" <a a.a> writes:
"Bekenn" <leaveme alone.com> wrote in message 
news:ikgs96$9in$3 digitalmars.com...
 On 2/28/11 5:05 AM, Jacob Carlborg wrote:
 It's possible to implement this as a library:
 http://dsource.org/projects/orange/browser/orange/util/Reflection.d#L135

 Not a complete solution but it works.

That has scary syntax; no thanks.

It is a pretty gnarly syntax. And it doesn't support return values, and the arg values are mixed into the wrong context. But it's a hell of a lot better than nothing: calling certain functions without using named arguments scares the shit out of me. I think I'll probably use it (or something like it) on funcs that really need it. One thing that could help is if it was modified slightly to work like this: ---------------------- int foo(int a, int b) {...} // We need better string-mixin syntax!!!! auto x = mixin( namedArgs(q{ foo(a=10,b=27) }) ); // Turns into --> auto x = foo(10,27); ---------------------- If we could ever manage to get string-producing CTFEs that are implicitly mixed-in, which we desparately need anyway, then that would be: ---------------------- auto x = namedArgs(q{ foo(a=10,b=27) }); ---------------------- Which I think would be a perfectly acceptable stop-gap solution until we can get *real* named arguments.
Feb 28 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 2/28/11, Steven Schveighoffer <schveiguy yahoo.com> wrote:
 This syntax already means something in D:

 string action;
 int times;
 foo(action = "dofoo", times = 100); // set action to "dofoo" and times to
 100 and pass those to the function.

 -Steve

Except that doesn't do what you'd expect it to do: void foo(ref int time) { } void main() { int times; foo(times = 100); // set times to 100 and pass to the function. } Error: function test.foo (ref int time) is not callable using argument types (int) Error: times = 100 is not an lvalue
Feb 28 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 28 Feb 2011 08:15:02 -0500, Andrej Mitrovic  
<andrej.mitrovich gmail.com> wrote:

 On 2/28/11, Steven Schveighoffer <schveiguy yahoo.com> wrote:
 This syntax already means something in D:

 string action;
 int times;
 foo(action = "dofoo", times = 100); // set action to "dofoo" and times  
 to
 100 and pass those to the function.

 -Steve

Except that doesn't do what you'd expect it to do: void foo(ref int time) { } void main() { int times; foo(times = 100); // set times to 100 and pass to the function. }

When I said "pass those" I meant "pass those values". I was not assuming ref arguments. In any case, your syntax for named arguments is not possible. x = y is an expression, and can be used anywhere an expression can be used. -Steve
Feb 28 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 2/28/11, Steven Schveighoffer <schveiguy yahoo.com> wrote:
 In any case, your syntax for named arguments is not possible.  x = y is an
 expression, and can be used anywhere an expression can be used.

I agree. I'm thinking there would be more ambiguity with the Python syntax: void foo(int value = 50) { } void main() { int value = 20; foo(value=40); // does main.value change? }
Feb 28 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Would named arguments work with compile-time/template arguments as well?
Feb 28 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 2/28/11, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:
 On 2/28/11 6:48 AM, Andrej Mitrovic wrote:
 I prefer using the equals sign:
 foo(action = "dofoo", times = 100)

 This is how Python does it.

// in a module far, far away void fun(double x); // In a module importing it int x = 42; fun(x = 43); Andrei

Yes, I've mentioned I was wrong in my next-to-last post. :)
Feb 28 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 28 Feb 2011 09:55:54 -0500, Michel Fortin  
<michel.fortin michelf.com> wrote:

 On 2011-02-28 09:34:30 -0500, spir <denis.spir gmail.com> said:

 So, let's use ':'.

Note however that ':' already has a meaning in templates arguments. Using ':' for named function arguments would preclude having named template arguments (or force template arguments to use yet another syntax).

I think you are confusing template declarations with template instantiations. ':' is not used in instantiations (that I know of) e.g. the usage would be: template foo(T = int, U = string) {...} foo!(U : int)...; -Steve
Feb 28 2011
prev sibling next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Sunday, February 27, 2011 23:03:46 Bekenn wrote:
 Consider the following line from a project I'm playing around with:
 
 	HRESULT hr = m_Device.Present(null, null, null, null);
 
 Quick: What behavior does that third argument specify?  If you said,
 "Well, /obviously/, that's a handle to an alternative destination window
 for the render operation; by passing null, you're choosing not to
 provide an alternative render target." then... well, gee, I have no
 answer to that.
 
 With named arguments, it becomes a bit easier to understand:
 
 	HRESULT hr = m_Device.Present(pSourceRect: null, pDestRect: null,
 hDestWindowOverride: null, pDirtyRegion: null);
 
 If I remember right, Python has this (optional) feature; I'm not aware
 of anyone ever complaining about it.  It also nicely provides a solution
 to the bool argument problem:
 http://blogs.msdn.com/b/oldnewthing/archive/2006/08/28/728349.aspx
 
 But wait, there's more!
 
 Named arguments get a +1 synergy bonus with default arguments.  When
 using parameter names to specify arguments, the order in which those
 arguments are passed no longer matters.  Imagine if the Present() method
 above provided the default argument null for each parameter:
 
 interface IDirect3DDevice9 : IUnknown
 {
 	...
 	HRESULT Present(const(RECT)* pSourceRect = null, const(RECT)* pDestRect
 = null, HWND hDestWindowOverride = null, const(RGNDATA)* pDirtyRegion =
 null);
 	...
 }
 
 We can do this in the D binding without running afoul of any linkage
 issues, and it simplifies the Present() call for its most common usage,
 which I think is a good thing.  Now, let's say I'm doing something
 special; suppose I'm not worried about source and destination rectangles
 or dirty regions, but I do want to supply a different render target.
 With named arguments, that's easy to do without making things messy:
 
 	HRESULT hr = m_Device.Present(hDestWindowOverride: hOverride);
 
 Named arguments should also play nicely with positional arguments:
 
 	auto wrappedString = wrap(reallyLongString, colmuns: 120, tabsize: 4);
 
 Lastly, wouldn't be an entirely new feature; D already supports named
 arguments for static struct initializers.  I merely propose sharing the
 love with normal functions and struct literals.
 
 Here are the rules I have in mind:
 
 1) Named arguments are not a replacement for positional arguments.
 Arguments fall into three categories: positional, named positional, and
 named non-positional.  An argument is positional if no name is supplied.
   An argument is named positional if a name is supplied and its position
 matches the parameter's position in the function declaration.  An
 argument is named non-positional if a name is supplied and either a) its
 position does not match the parameter's position in the function
 declaration, or b) it is immediately preceded by a named non-positional
 argument.
 
 2) No positional argument may appear after a named non-positional argument.
 
 3) Named non-positional arguments may appear in any order.
 
 
 Potential problems:  The only problems I can foresee here are variations
 on the situation when there are two (or more) versions of a function
 with the same number, type, and names of parameters, but in non-matching
 order, like this:
 
 void func(int a, char b);
 void func(char b, int a);
 
 In such a case, the compiler should diagnose an error if named arguments
 are employed.
 
 Thoughts?

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. - Jonathan M Davis
Feb 28 2011
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Jonathan M Davis:

 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.

After your have refactored a function, I sometimes want to named arguments again. And sometimes you can't refactor an API, etc.
 (I just plain don't want the code clutter,

It's about as clutter as giving names to variables. And it's optional, you are not forced to call a function with named arguments in D (this sometimes happens in Python when the function accepts a **kwrg).
 and they strike me as a crutch to avoid writing functions with good 
 signatures in spite of their usefulness in some situations),

I'd like good signatures too. Bye, bearophile
Feb 28 2011
prev sibling next sibling parent Bekenn <leaveme alone.com> writes:
On 2/28/11 10:51 AM, 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.

Are you the author of every function and method you call in your code?
Feb 28 2011
prev sibling next sibling parent reply Adam Ruppe <destructionator gmail.com> writes:
 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));
Feb 28 2011
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
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
Feb 28 2011
prev sibling next sibling parent reply Adam Ruppe <destructionator gmail.com> writes:
Steven Schveighoffer:
 But other than that, it still looks more verbose than should be
 necessary.

This is the real problem. We already have named arguments in today's D. You can do some stringof magic to get the parameter names and ParameterTypeTuple to assign them. I haven't written it, but there should be no blocker in combining these: void foo(int width, int height); auto args = NamedParameterTypeTuple!(foo); args.width = 10; args.height = 20; foo(args); But, that's just like the struct for length of code... If someone wanted to write the code to add the foo(width:10, height:10), I wouldn't likely object to it's inclusion. But, I don't see it as a big deal.
Feb 28 2011
parent Jacob Carlborg <doob me.com> writes:
On 2011-02-28 21:44, Adam Ruppe wrote:
 Steven Schveighoffer:
 But other than that, it still looks more verbose than should be
 necessary.

This is the real problem. We already have named arguments in today's D. You can do some stringof magic to get the parameter names and ParameterTypeTuple to assign them. I haven't written it, but there should be no blocker in combining these: void foo(int width, int height); auto args = NamedParameterTypeTuple!(foo); args.width = 10; args.height = 20; foo(args); But, that's just like the struct for length of code... If someone wanted to write the code to add the foo(width:10, height:10), I wouldn't likely object to it's inclusion. But, I don't see it as a big deal.

http://dsource.org/projects/orange/browser/orange/util/Reflection.d#L135 -- /Jacob Carlborg
Feb 28 2011
prev sibling parent reply KennyTM~ <kennytm gmail.com> writes:
On Mar 1, 11 05:04, Simen kjaeraas wrote:
 Adam Ruppe <destructionator gmail.com> wrote:

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

 struct Width { int width; alias width this; }

 foo(Width(10), Height(20));

Clearly this can be done better: struct _(string s) { int data; alias data this; } foo(_!"width"(10), _!"height"(20));

How are these better than foo(/*width*/ 10, /*height*/ 20); ? One advantage of named parameter is the compiler can verify you've passed in the correct order, and all these alternatives cannot.
Feb 28 2011
parent Adam Ruppe <destructionator gmail.com> writes:
 ? One advantage of named parameter is the compiler can verify you've
 passed in the correct order, and all these alternatives cannot.

Separate structs would be checked because doing them out of order would be a type mistmatch.
Feb 28 2011
prev sibling parent reply spir <denis.spir gmail.com> writes:
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
Feb 28 2011
parent bearophile <bearophileHUGS lycos.com> writes:
spir:

 <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!

You want to break English and Math rules only when you have a good reason. In Python PEP8 is quite specific:
    - Immediately before a comma, semicolon, or colon:

      Yes: if x == 4: print x, y; x, y = y, x
      No:  if x == 4 : print x , y ; x , y = y , x

 There is no reason to write "width: 123" rather than "width:123" or "width :
123".

"width :123" breaks an English rule for no purpose, and "width:123" is less readable, because there are less spaces that help the eye tell apart the parts of the text. "width : 123" looks more acceptable when you use it as a binding symbol. In functional languages sometimes you use ":" to tie list elements, and you use it with a space on both sides. 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!

In D the ";" is used for purposes similar to English ones, as punctuation to denote when something (like a line) ends, so sticking it to the left is the right thing to do, because both English and most D is read from left to right. Bye, bearophile
Feb 28 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
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. -Steve
Feb 28 2011
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
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. - Jonathan M Davis
Feb 28 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 2/28/11, Bekenn <leaveme alone.com> wrote:
 I went with : because that's what's already used in static struct
 initializers.

I even forgot about those! It's also used in static arrays and static unions.
Feb 28 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 2/28/11, spir <denis.spir gmail.com> wrote:
 But this conflict already exists with the
 usage
 of ':' in dyn array notation

Wait, when is ':' used with dynamic arrays?
Feb 28 2011
prev sibling next sibling parent Tomek =?ISO-8859-2?B?U293afFza2k=?= <just ask.me> writes:
Steven Schveighoffer napisa=B3:

 Although I am not strongly for named arguments, I think they would be a =

 definite improvement.
=20
 Bearophile brought up one of the strongest cases for them:
=20
 foo(int width, int height) {}
=20
 Seems simple enough, I don't see how you have "too many arguments", but =

 the call looks like this:
=20
 foo(123, 456);
=20
 So, looking at this call, can you tell which is width and which is =20
 height?  I've seen some libs that use width and height do height first =20
 also.  I usually have to go look up the API every time I'm reading/writin=

 one of these.
=20
 But this is perfectly clear and resists API changes/differences:
=20
 foo(width: 123, height: 456);
=20
 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 muc=

 clearer.

The classic beneficiary of named parameters is the widely understood user i= nterface. Presentation code (layout, formatting, graphics) is naturally awa= sh in options and switches. Take construction of std.format.FormatSpec as a next-door example. --=20 Tomek
Feb 28 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 28 Feb 2011 14:33:55 -0500, Jonathan M Davis <jmdavisProg gmx.com>  
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  

 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  

 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  

 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.

foo(dimensions(123, 456)); // not helping -Steve
Feb 28 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 28 Feb 2011 14:32:52 -0500, Andrej Mitrovic  
<andrej.mitrovich gmail.com> wrote:

 On 2/28/11, spir <denis.spir gmail.com> wrote:
 But this conflict already exists with the
 usage
 of ':' in dyn array notation

Wait, when is ':' used with dynamic arrays?

Think he meant AA. -Steve
Feb 28 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 2/28/11, Jonathan M Davis <jmdavisProg gmx.com> wrote:
 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.

But then you're back to square one: void foo(Size size) { } struct Size { int width, height; } void main() { auto size = Size(10, 20); // so what is 10 and what is 20? foo(size); }
Feb 28 2011
prev sibling next sibling parent reply spir <denis.spir gmail.com> writes:
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
Feb 28 2011
parent reply Don <nospam nospam.com> writes:
spir wrote:
 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.


I agree. CreateFont() in the Windows API, I'm looking at you. (For Linux people, that function has about 12 parameters).
 ???
 
 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!

You don't have that option. At least, if you're a library developer, you don't. (I'm a bit sick of people saying "you don't have to use it if you don't want to" in language design. If it is in the language, you don't have a choice. You will encounter it). There are a couple of things that I really, really don't like about the names argument idea: 1. It makes parameter names part of the API. Providing no way for the function writer to control whether it is part of the API or not, and especially, doing it retrospectively, strikes me as extremely rude. 2. It introduces a different syntax for calling a function. foo(4, 5); foo(x: 4, y: 5); They look different, but they do exactly the same thing. I don't like that redundancy. Especially since, as far as I can tell, the named arguments are just comments (which the compiler can check). If so, a syntax like this would be possible, with no language change at all: pragma(namedarguments); // applies to whole module foo(/*x*/ 4, /*y*/ 5); ---> if a function parameter has a comment which forms a valid identifier, it's a named parameter. But I still don't see the need for this feature. Aren't people using IDEs where the function signature (with parameter names) pops up when you're entering the function, and when you move the mouse over the function call? And if you really want to see them all the time, why not build that feature into the IDE? ("hit ctrl-f9 to show all parameter names, hit it again to hide them").
Feb 28 2011
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Don:

You don't have that option. At least, if you're a library developer, you

don't want to" in language design. If it is in the language, you don't have a choice. You will encounter it).< If you add named arguments to D, you are free to not use them when you call Phobos functions or functions from libraries not written by you. You have to see them only if you modify code written by other people that uses named arguments.
 There are a couple of things that I really, really don't like about the
 names argument idea:
 1. It makes parameter names part of the API.
 Providing no way for the function writer to control whether it is part
 of the API or not,

Probably I am don't understand something here. Function arguments need to be well chosen, so I don't mind them becoming part of the API. (In theory an annotation may be used to disallow the usage of named arguments for a specific function, but I think this is not necessary).
 and especially, doing it retrospectively, strikes me
 as extremely rude.

There is not much D2 code around, most D2 code is in the future, where this feature will hopefully be known to be present.
 2. It introduces a different syntax for calling a function.
 foo(4, 5);
 foo(x: 4, y: 5);
 They look different, but they do exactly the same thing. I don't like
 that redundancy.

In SPARK (Ada) they avoid that redundancy because you must use named arguments :-) To me they look the same, but the second also tells me what I am assigning numbers to.
 Especially since, as far as I can tell, the named arguments are just
 comments (which the compiler can check).
 If so, a syntax like this would be possible, with no language change at all:
 
 pragma(namedarguments); // applies to whole module
 
 foo(/*x*/ 4, /*y*/ 5);
 
 ---> if a function parameter has a comment which forms a valid
 identifier, it's a named parameter.

The two following are the same thing: foo(x: 4, y: 5); foo(y: 5, x: 4); While the following ones are not the same call: foo(/*x*/ 4, /*y*/ 5); foo(/*y*/ 5, /*x*/ 4); And if your function is: void foo(int x = 1, int y = 2) {} You are also able to write: foo(y: 5); That's not equivalent to: foo(/*y*/ 5); In Mathematica and Python there are plotting functions that have lot of parameters, all of them have a default argument. With named arguments you are able to choose to modify only one or few arguments, keeping your code readable and short and bug-free.
 But I still don't see the need for this feature. Aren't people using
 IDEs where the function signature (with parameter names) pops up when
 you're entering the function, and when you move the mouse over the
 function call?

If you print code on a book or you show code on the web, etc, you don't have an IDE to help you. D isn't designed to require an IDE. And C# devs have added named arguments even if most C# programmers use an IDE. Bye, bearophile
Feb 28 2011
next sibling parent Don <nospam nospam.com> writes:
bearophile wrote:
 Don:
 
 You don't have that option. At least, if you're a library developer, you

don't want to" in language design. If it is in the language, you don't have a choice. You will encounter it).< If you add named arguments to D, you are free to not use them when you call Phobos functions or functions from libraries not written by you.

You have to see them only if you modify code written by other people that uses
named arguments.

This is complete rubbish. You cannot prevent someone from relying on your argument names. Changes to the language *always* affect everyone.
 There are a couple of things that I really, really don't like about the
 names argument idea:
 1. It makes parameter names part of the API.
 Providing no way for the function writer to control whether it is part
 of the API or not,

Probably I am don't understand something here. Function arguments need to be well chosen,

so I don't mind them becoming part of the API. Currently, they are documentation. Readable by a human. Making them part of the API is much more restrictive. Essentially, my chief objection to named arguments is that they severely limit your ability to improve the documentation after the function has been written. (In theory an annotation may be used to disallow the usage of named arguments for a specific function, but I think this is not necessary).
 
 
 and especially, doing it retrospectively, strikes me
 as extremely rude.

There is not much D2 code around, most D2 code is in the future, where this feature will hopefully be known to be present.

No, there's a huge body of existing code, most of it is in C.
 2. It introduces a different syntax for calling a function.
 foo(4, 5);
 foo(x: 4, y: 5);
 They look different, but they do exactly the same thing. I don't like
 that redundancy.

In SPARK (Ada) they avoid that redundancy because you must use named arguments :-) To me they look the same, but the second also tells me what I am assigning numbers to.
 Especially since, as far as I can tell, the named arguments are just
 comments (which the compiler can check).
 If so, a syntax like this would be possible, with no language change at all:

 pragma(namedarguments); // applies to whole module

 foo(/*x*/ 4, /*y*/ 5);

 ---> if a function parameter has a comment which forms a valid
 identifier, it's a named parameter.

The two following are the same thing: foo(x: 4, y: 5); foo(y: 5, x: 4);

Well, if you allowing changes in parameter ordering, it's a very much more complicated feature, that frankly I find very scary. It's of limited use but enormous complexity.
 But I still don't see the need for this feature. Aren't people using
 IDEs where the function signature (with parameter names) pops up when
 you're entering the function, and when you move the mouse over the
 function call?

If you print code on a book or you show code on the web, etc, you don't have an IDE to help you.

You can always put comments in.
 D isn't designed to require an IDE. 

Yes, but this seems like a personal preference.
 And C# devs have added named arguments even if most C# programmers use an IDE. 
 
 Bye,
 bearophile

Mar 01 2011
prev sibling parent Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
On 28/02/2011 22:13, bearophile wrote:
 But I still don't see the need for this feature. Aren't people using
  IDEs where the function signature (with parameter names) pops up when
  you're entering the function, and when you move the mouse over the
  function call?


D isn't designed to require an IDE. And C# devs have added named arguments even if most C# programmers use an IDE. Bye, bearophile

This doesn't make it *required* to have an IDE. It perhaps just makes it better. The question that should be asked is if D should be optimized for IDE usage or not... -- Bruno Medeiros - Software Engineer
Mar 08 2011
prev sibling next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Jonathan M Davis:

 All of a sudden you could have
 
 foo(4, 5);
 foo(x : 4, y : 5);
 foo(y : 5, X : 4);
 
 all making _exactly_ the same function call. That seem _very_ bug-prone and 
 confusing to me.

(You have used an upper case X, this bug will be caught by the compiler). For me the #1 purpose of named arguments is to make code more explicit/readable and often less buggy. If you swap all arguments in your program, using named arguments, you are probably making your program a little more bug-prone. So as most other features there's a way to misuse it. But in most cases you don't swap arguments, and you use names more semantically meaningful than just x and y, so swapped arguments sticks out more. And you also need to train yourself a bit, to see the arguments of function calls not in their of their order, but in term of their names, their semantics. If you use MatPlotLib (from Python) you learn to see the names of function arguments and mostly ignore the order you give them to functions (because the order is much less significant), so this feature needs a bit of training for the mind/attitude of the programmer too. Bye, bearophile
Feb 28 2011
prev sibling next sibling parent reply Bekenn <leaveme alone.com> writes:
On 2/28/11 1:38 PM, Don wrote:
 spir wrote:
 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.


I agree. CreateFont() in the Windows API, I'm looking at you. (For Linux people, that function has about 12 parameters).

That's a great example of where named parameters can come in very handy. As a consumer of the API, you do not have the option of refactoring CreateFont(); you have to play the cards you're dealt. Named arguments allow you to annotate in a compiler-verified fashion.
 Just don't use them!

You don't have that option. At least, if you're a library developer, you don't. (I'm a bit sick of people saying "you don't have to use it if you don't want to" in language design. If it is in the language, you don't have a choice. You will encounter it).

You may encounter it, but nothing says you ever have to write it. There is no way to write a function such that callers would have to use named arguments in the function call. (If there were, then I'd agree with you -- that would be bad.)
 There are a couple of things that I really, really don't like about the
 names argument idea:
 1. It makes parameter names part of the API.
 Providing no way for the function writer to control whether it is part
 of the API or not, and especially, doing it retrospectively, strikes me
 as extremely rude.

A valid point. I think I would already consider parameter names to be part of the API, though; generated documentation relies upon them, as do contracts. Admittedly, this would be the first place where they leak directly into caller code.
 2. It introduces a different syntax for calling a function.
 foo(4, 5);
 foo(x: 4, y: 5);
 They look different, but they do exactly the same thing. I don't like
 that redundancy.

You're right, it is redundant. So is this: Declaration: void func(int a = 0); Use: func(); // ok func(0); // same as above Are you also against default arguments, then?
 Especially since, as far as I can tell, the named arguments are just
 comments (which the compiler can check).

Look again at my example from the first post: HRESULT hr = m_Device.Present(hDestWindowOverride: hOverride); In this usage, the named argument allows me to skip over the first two parameters, which receive their default arguments. This seems highly valuable to me.
 But I still don't see the need for this feature. Aren't people using
 IDEs where the function signature (with parameter names) pops up when
 you're entering the function, and when you move the mouse over the
 function call?

The point (in the annotation use case) is less in the writing than in the reading.
Feb 28 2011
next sibling parent Jim <bitcirkel yahoo.com> writes:
Jonathan M Davis Wrote:

 On Monday, February 28, 2011 14:25:05 Bekenn wrote:
 On 2/28/11 1:38 PM, Don wrote:
 spir wrote:
 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.


I agree. CreateFont() in the Windows API, I'm looking at you. (For Linux people, that function has about 12 parameters).

That's a great example of where named parameters can come in very handy. As a consumer of the API, you do not have the option of refactoring CreateFont(); you have to play the cards you're dealt. Named arguments allow you to annotate in a compiler-verified fashion.
 Just don't use them!

You don't have that option. At least, if you're a library developer, you don't. (I'm a bit sick of people saying "you don't have to use it if you don't want to" in language design. If it is in the language, you don't have a choice. You will encounter it).

You may encounter it, but nothing says you ever have to write it. There is no way to write a function such that callers would have to use named arguments in the function call. (If there were, then I'd agree with you -- that would be bad.)
 There are a couple of things that I really, really don't like about the
 names argument idea:
 1. It makes parameter names part of the API.
 Providing no way for the function writer to control whether it is part
 of the API or not, and especially, doing it retrospectively, strikes me
 as extremely rude.

A valid point. I think I would already consider parameter names to be part of the API, though; generated documentation relies upon them, as do contracts. Admittedly, this would be the first place where they leak directly into caller code.

And that's a _big_ problem. For instance, how many parameter names in Phobos were chosen with the idea that a caller would use them? _None_. And now, if named arguments are added, all of a sudden, you can't rename parameters without breaking code. I, for one, do not want to _increase_ the number of things that I can't change in code without breaking other people's code. And at least with functions, I could rename them and leave a deprecated alias. With parameters, I don't have that option. A poorly named parameter would be set in stone unless the whole function were renamed or we were willing to break other people's code. Named arguments _decrease_ flexibility as far as the API goes. On top of that, we would then have to worry about having high consistency in parameter names instead of just in function names. From the perspective of the library writer, this causes _more_ problems at _no_ benefit. From the perspective of the library user, it does provide some benefit, but I honestly do not think that func(x : 4, y : 5); is easier to read than func(4, 5); Sure, you have to know what func's parameters are, but you have to know that anyway. Only now, with named arguments, you have to care about what their _names_ are in addition to what they're for. I do _not_ want to have to read code which uses named arguments. It's just more clutter and more intellectual overhead. The sole type of case that I have seen where named arguments are of real benefit is where you're dealing with horribly written functions that have a ton of parameters, and I would _hope_ that that kind of nonsense would be restricted to old C APIs and the like. And if you have to deal with such C APIs from D, you can write a wrapper which uses a proper struct or whatnot to encapsulate that mess. Such horrendous functions shouldn't be the norm at all. As a library user, I see little benefit to named arguments and a definite problem with them in terms the added code clutter and intellectual overhead. As a library writer, it gives me _no_ benefit and definitely makes my life harder. Parameter names have never been part of a function's signature, and I _don't_ want them to start being a part of it now. The more I think about this, the more I'm against the idea of named arguments. - Jonathan M Davis

I think it could be a real boon for generic code: class House(Roof = Clay, Door = Wood, Window = Glass) { Roof _roof; Door[] _doors; Window[] _windows; } auto home = new House(Roof: Gingerbread, Window: Sugar)(); You would probably parameterize as much as possible, like the container types for _doors and _windows -- i.e. anything that isn't limited by the algorithm of your choice. Everything being optional of course, and all the work is all done at compile time. This would give you _rich_ generic types with plain interfaces. You only specify what's important to you. How's that for a template library where every part can be shifted and replaced?
Feb 28 2011
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 2/28/11 6:03 PM, Jonathan M Davis wrote:
 The more I think about this, the more I'm against the idea of named arguments.

I think you have been blessed to work with only small, clean APIs. Certain domains definitely promote large argument lists. Though the designs could certainly be refactored to e.g. group parameters into separate objects, it's overkill to do that. I'm afraid sheer experience is showing that your counterarguments are not based. Andrei
Feb 28 2011
parent dsimcha <dsimcha yahoo.com> writes:
On 2/28/2011 8:48 PM, Andrei Alexandrescu wrote:
 On 2/28/11 6:03 PM, Jonathan M Davis wrote:
 The more I think about this, the more I'm against the idea of named
 arguments.

I think you have been blessed to work with only small, clean APIs. Certain domains definitely promote large argument lists. Though the designs could certainly be refactored to e.g. group parameters into separate objects, it's overkill to do that. I'm afraid sheer experience is showing that your counterarguments are not based. Andrei

Agreed. I don't know how many times, when designing an API, I've considered making something configurable and instead just hard coded it to avoid bloating things with yet another regular (must be passed in-order) function argument or (if I put the options in a struct) yet another type. Besides, using structs to hold options requires boilerplate for the user of the library. What would you rather write? A: Options options; options.someOption = someValue; fun(mandatoryArg1, mandatoryArg2, options); B: fun(mandatoryArg1, mandatoryArg2, someOption = someValue); The beauty of named arguments with defaults is that they allow you to make things configurable with as little boilerplate code as possible for the library writer and as little boilerplate as possible for the user in the case where such configurability isn't needed.
Feb 28 2011
prev sibling parent spir <denis.spir gmail.com> writes:
On 03/01/2011 02:48 AM, Andrei Alexandrescu wrote:
 On 2/28/11 6:03 PM, Jonathan M Davis wrote:
 The more I think about this, the more I'm against the idea of named arguments.

I think you have been blessed to work with only small, clean APIs. Certain domains definitely promote large argument lists. Though the designs could certainly be refactored to e.g. group parameters into separate objects, it's overkill to do that. I'm afraid sheer experience is showing that your counterarguments are not based.

It seems to me the core point is whether what params mean, and their order, is obvious. Rather than their sheer number. Reading code using names for params is a huge help in understanding it, and also in learning the APIs. Meaning what one can do, why it is useful, and how to proceed concretely. I would be for all tutorial-like code (esp in "official" ref doc), examples, and even unittests more or less intended as code samples, to use named params everywhere. Denis -- _________________ vita es estrany spir.wikidot.com
Mar 01 2011
prev sibling next sibling parent Bekenn <leaveme alone.com> writes:
On 2/28/11 1:50 PM, Jonathan M Davis wrote:
 However, I consider them to
 be a big _problem_, not a feature - _especially_ the ability to rearrange the
 function arguments. All of a sudden you could have

 foo(4, 5);
 foo(x : 4, y : 5);
 foo(y : 5, X : 4);

 all making _exactly_ the same function call. That seem _very_ bug-prone and
 confusing to me.

Of those three calls, the highest potential for confusion exists with the first. Admittedly, the third is of uncertain value.
Feb 28 2011
prev sibling next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, February 28, 2011 14:25:05 Bekenn wrote:
 On 2/28/11 1:38 PM, Don wrote:
 spir wrote:
 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.


I agree. CreateFont() in the Windows API, I'm looking at you. (For Linux people, that function has about 12 parameters).

That's a great example of where named parameters can come in very handy. As a consumer of the API, you do not have the option of refactoring CreateFont(); you have to play the cards you're dealt. Named arguments allow you to annotate in a compiler-verified fashion.
 Just don't use them!

You don't have that option. At least, if you're a library developer, you don't. (I'm a bit sick of people saying "you don't have to use it if you don't want to" in language design. If it is in the language, you don't have a choice. You will encounter it).

You may encounter it, but nothing says you ever have to write it. There is no way to write a function such that callers would have to use named arguments in the function call. (If there were, then I'd agree with you -- that would be bad.)
 There are a couple of things that I really, really don't like about the
 names argument idea:
 1. It makes parameter names part of the API.
 Providing no way for the function writer to control whether it is part
 of the API or not, and especially, doing it retrospectively, strikes me
 as extremely rude.

A valid point. I think I would already consider parameter names to be part of the API, though; generated documentation relies upon them, as do contracts. Admittedly, this would be the first place where they leak directly into caller code.

And that's a _big_ problem. For instance, how many parameter names in Phobos were chosen with the idea that a caller would use them? _None_. And now, if named arguments are added, all of a sudden, you can't rename parameters without breaking code. I, for one, do not want to _increase_ the number of things that I can't change in code without breaking other people's code. And at least with functions, I could rename them and leave a deprecated alias. With parameters, I don't have that option. A poorly named parameter would be set in stone unless the whole function were renamed or we were willing to break other people's code. Named arguments _decrease_ flexibility as far as the API goes. On top of that, we would then have to worry about having high consistency in parameter names instead of just in function names. From the perspective of the library writer, this causes _more_ problems at _no_ benefit. From the perspective of the library user, it does provide some benefit, but I honestly do not think that func(x : 4, y : 5); is easier to read than func(4, 5); Sure, you have to know what func's parameters are, but you have to know that anyway. Only now, with named arguments, you have to care about what their _names_ are in addition to what they're for. I do _not_ want to have to read code which uses named arguments. It's just more clutter and more intellectual overhead. The sole type of case that I have seen where named arguments are of real benefit is where you're dealing with horribly written functions that have a ton of parameters, and I would _hope_ that that kind of nonsense would be restricted to old C APIs and the like. And if you have to deal with such C APIs from D, you can write a wrapper which uses a proper struct or whatnot to encapsulate that mess. Such horrendous functions shouldn't be the norm at all. As a library user, I see little benefit to named arguments and a definite problem with them in terms the added code clutter and intellectual overhead. As a library writer, it gives me _no_ benefit and definitely makes my life harder. Parameter names have never been part of a function's signature, and I _don't_ want them to start being a part of it now. The more I think about this, the more I'm against the idea of named arguments. - Jonathan M Davis
Feb 28 2011
parent reply "Nick Sabalausky" <a a.a> writes:
"Jonathan M Davis" <jmdavisProg gmx.com> wrote in message 
news:mailman.2069.1298937813.4748.digitalmars-d puremagic.com...
 And that's a _big_ problem. For instance, how many parameter names in 
 Phobos
 were chosen with the idea that a caller would use them? _None_.

If Phobos parameter names are that bad, then Phobos has both a code-quality problem and a documentation-quality problem.
 And now, if
 named arguments are added, all of a sudden, you can't rename parameters 
 without
 breaking code.

 I, for one, do not want to _increase_ the number of things that I
 can't change in code without breaking other people's code.  And at least 
 with
 functions, I could rename them and leave a deprecated alias. With 
 parameters, I
 don't have that option. A poorly named parameter would be set in stone 
 unless
 the whole function were renamed or we were willing to break other people's 
 code.
 Named arguments _decrease_ flexibility as far as the API goes.

I don't understand why people have such a problem with changed names in an API. Updating calls to use a new name is fucking trivial. How many seconds of terrible, miserable, back-breaking work did you have to suffer through to update your code for the new name changes in DMD 2.052? Granted it would be a problem if they were constantly changing everything's name around, but nobody does that even for private symbols. And if you really want to be obsessive-compulsive about it, there's always this: void foo(int a) { alias a b; ... }
 On top of that, we would then have to worry about having high consistency 
 in
 parameter names instead of just in function names. From the perspective of 
 the
 library writer, this causes _more_ problems at _no_ benefit.

The "problem" is downright trivial, and as a library writer I'd certainly consider providing my users with a less error-prone API to be of benefit to me.
 From the perspective
 of the library user, it does provide some benefit, but I honestly do not 
 think
 that

 func(x : 4, y : 5);

 is easier to read than

 func(4, 5);

 Sure, you have to know what func's parameters are, but you have to know 
 that
 anyway.

But you no longer have to give a shit what their arbitrarily chosen order is. X and Y may have an obvious natural ordering, but a lot of things don't.
 Only now, with named arguments, you have to care about what their
 _names_ are in addition to what they're for. I do _not_ want to have to 
 read
 code which uses named arguments. It's just more clutter and more 
 intellectual
 overhead.

I do _not_ want to have to read code like this: box(10, 15, 5, 12) Quiz: Could you tell which of the following that is without referring to any docs?: - box(top, bottom, left, right) - box(top, right, bottom, left) - box(x, y, width, height) - box(x, y, rgb color, alpha) - box(x, y, z, hsl color) - box(id#, x, y, line thickness) - Or maybe the API author was stupid and made it something like box(height, x, width, y) One could argue the code is more likely like this: int x = 1; int y = 2; int width = 3; int height = 4; ... box(x, y, width, height) But if you look at that, do you actually *know* the API is "x, y, width, height"? Nope. Could be a bug staring you right in the face. Other people have addressed the "IDE API pop-up" issue. Additionally, I do _not_ want to have to read code like this: Rect rect; rect.top = 1; rect.bottom = 2; rect.left = 3; rect.right = 4; box(rect) (And yes, there's "with", but IMO that makes it even worse.) And note that that's only 4 params, not remotely "a ton". MS has a lot of APIs like that and even for small structs (*especially* for small structs) it quickly makes the user code a mess.
Feb 28 2011
parent Bekenn <leaveme alone.com> writes:
On 2/28/11 9:07 PM, Nick Sabalausky wrote:
 One could argue the code is more likely like this:

      int x = 1;
      int y = 2;
      int width = 3;
      int height = 4;
      ...
      box(x, y, width, height)

Right, at which point you're essentially using named arguments anyway, except that here, a) it's not verified by the compiler, b) you've added stack or static variables (perhaps needlessly), and c) you're polluting the local namespace.
Mar 01 2011
prev sibling next sibling parent reply Steven Wawryk <stevenw acres.com.au> writes:
On 01/03/11 08:08, Don wrote:
 2. It introduces a different syntax for calling a function.
 foo(4, 5);
 foo(x: 4, y: 5);
 They look different, but they do exactly the same thing. I don't like
 that redundancy.

So, out of consistency, I suppose you must be against foreach, scope(exit) and every other kind of lowering?
Feb 28 2011
parent Steven Wawryk <stevenw acres.com.au> writes:
On 01/03/11 18:25, Jonathan M Davis wrote:
 On Monday 28 February 2011 23:24:00 Steven Wawryk wrote:
 On 01/03/11 08:08, Don wrote:
 2. It introduces a different syntax for calling a function.
 foo(4, 5);
 foo(x: 4, y: 5);
 They look different, but they do exactly the same thing. I don't like
 that redundancy.

So, out of consistency, I suppose you must be against foreach, scope(exit) and every other kind of lowering?

Except that they actually do something different. All adding the variable names really do in this case is document the name of the variable that each argument is tied to and enforce that the names you give are valid. While it does allow for some increased flexibility in cases where a function takes multiple default arguments, for the most part it's just documentation. For the most part, it's not actually doing anything for you. It's not even syntactic sugar. Now, obviously there are a number of people here who think that this compiler- verified documentation is worth having, but for the most part, that's all this is. It's not cutting down on boiler plate code or reducing how much you have to type to do a particular type of operation (in fact, it's increasing it). So, this is not at all comparable to foreach or scope or other features which use lowering to transform code. At most, this results in the re-ordering of arguments. It's a totally different type of feature. Really, named arguments are compiler-enforced documentation which allow you to do a couple of things that you wouldn't be able to do normally (re-order arguments and give arguments for parameters with default arguments without giving arguments for parameters earlier in the parameter list which have default arguments). They're not really anything fancier than that. So, they're not really comparable to foreach or scope statements. In my opinion (and Don's it seems), they just don't pull their weight, unlike features such as foreach and scope statements. We appear to be outnumbered however. - Jonathan M Davis

Weight-pulling is the crux of the whole matter, and it is a highly subjective judgement. My comment was in response to "They look different, but they do exactly the same thing. I don't like that redundancy.". I was highlighting that redundancy like that is not in and of itself a bad thing. D uses it extensively and, as long as it's not frivolous, it contributes a great deal to the usability of the language. Back to the subjective judgement, it appears to me that the majority of people participating in this thread believe that the compiler-enforced documentation it provides *does* pull its weight.
Mar 01 2011
prev sibling next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2011-02-28 22:38, Don wrote:
 But I still don't see the need for this feature. Aren't people using
 IDEs where the function signature (with parameter names) pops up when
 you're entering the function, and when you move the mouse over the
 function call?
 And if you really want to see them all the time, why not build that
 feature into the IDE?
 ("hit ctrl-f9 to show all parameter names, hit it again to hide them").

That's very true. I'm used to that with Descent. On the other hand, I don't know how many editors that support this that also supports D. -- /Jacob Carlborg
Feb 28 2011
parent Jacek Nowak <jaceknowak wp.eu> writes:
This thread caught my attention. As an outsider to D (tried it for some time,
but
went back to C++/Java anyway), I'd argue IDE can be a huge asset when it comes
to
promoting a language. Take a look at DevCpp, it is considered one of the worst
IDEs around because of lack of updates, but the mere fact that it comes packaged
with a compiler (old one) and click-to-build capability makes it very popular
even if people are aware of it's drawbacks. Visual C++ also comes packaged with
a
compiler and it's dumb easy to create a new project and compile&run it.
Yes, an experienced programmer is used to configuring his compiler, setting all
the paths, even writing his own makefiles, but if you are to bring new people to
D, I'd say a packaged IDE + compiler working out-of-box would be a great
feature.
Mar 01 2011
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday 28 February 2011 23:24:00 Steven Wawryk wrote:
 On 01/03/11 08:08, Don wrote:
 2. It introduces a different syntax for calling a function.
 foo(4, 5);
 foo(x: 4, y: 5);
 They look different, but they do exactly the same thing. I don't like
 that redundancy.

So, out of consistency, I suppose you must be against foreach, scope(exit) and every other kind of lowering?

Except that they actually do something different. All adding the variable names really do in this case is document the name of the variable that each argument is tied to and enforce that the names you give are valid. While it does allow for some increased flexibility in cases where a function takes multiple default arguments, for the most part it's just documentation. For the most part, it's not actually doing anything for you. It's not even syntactic sugar. Now, obviously there are a number of people here who think that this compiler- verified documentation is worth having, but for the most part, that's all this is. It's not cutting down on boiler plate code or reducing how much you have to type to do a particular type of operation (in fact, it's increasing it). So, this is not at all comparable to foreach or scope or other features which use lowering to transform code. At most, this results in the re-ordering of arguments. It's a totally different type of feature. Really, named arguments are compiler-enforced documentation which allow you to do a couple of things that you wouldn't be able to do normally (re-order arguments and give arguments for parameters with default arguments without giving arguments for parameters earlier in the parameter list which have default arguments). They're not really anything fancier than that. So, they're not really comparable to foreach or scope statements. In my opinion (and Don's it seems), they just don't pull their weight, unlike features such as foreach and scope statements. We appear to be outnumbered however. - Jonathan M Davis
Feb 28 2011
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday 28 February 2011 23:49:56 Jacob Carlborg wrote:
 On 2011-02-28 22:38, Don wrote:
 But I still don't see the need for this feature. Aren't people using
 IDEs where the function signature (with parameter names) pops up when
 you're entering the function, and when you move the mouse over the
 function call?
 And if you really want to see them all the time, why not build that
 feature into the IDE?
 ("hit ctrl-f9 to show all parameter names, hit it again to hide them").

That's very true. I'm used to that with Descent. On the other hand, I don't know how many editors that support this that also supports D.

Unfortunately, D is going to have to become fairly mature before we have much in the way of really good IDE support. There _are_ options out there, but for the most part, when programming in D, I expect that the average programmer is forgoing the majority of benefits that a good IDE provides. So, while IDEs may help a great deal with certain things in the long run, I wouldn't expect many people to think that an IDE feature was a decent solution at this point (regardless of what you're talking about), since they're probably not using an IDE with such a feature at this point. - Jonathan M Davis
Mar 01 2011
prev sibling next sibling parent Don <nospam nospam.com> writes:
Steven Schveighoffer wrote:
 On Mon, 28 Feb 2011 16:38:34 -0500, Don <nospam nospam.com> wrote:
 
 spir wrote:
  Just don't use them!

You don't have that option. At least, if you're a library developer, you don't. (I'm a bit sick of people saying "you don't have to use it if you don't want to" in language design. If it is in the language, you don't have a choice. You will encounter it).

encounter *reading* it or encounter *using it*? You shouldn't ever have to use named parameters if you don't want to. Just like you can specify all defaulted parameters, or specify all template args when calling templated functions. I could live without named parameters (obviously!), but I certainly think reading a call with named parameters can be much easier with the parameter names than without, and I don't think you could ever say the opposite (that name-less parameters would be clearer).

For sure they can be clearer with nameless parameters! printf(formatstr: "Hello World!\n");
 In essense, the parameter names are ALREADY an essential part of the 
 API.  If we didn't name the parameters (entirely possible with .di 
 files!), how shitty would programming be?

The names are for humans to read. They are documentation. That's a big difference.
Mar 01 2011
prev sibling next sibling parent Russel Winder <russel russel.org.uk> writes:
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Tue, 2011-03-01 at 00:26 -0800, Jonathan M Davis wrote:
[ . . . ]
 Unfortunately, D is going to have to become fairly mature before we have =

 the way of really good IDE support. There _are_ options out there, but fo=

 most part, when programming in D, I expect that the average programmer is=

 forgoing the majority of benefits that a good IDE provides. So, while IDE=

 help a great deal with certain things in the long run, I wouldn't expect =

 people to think that an IDE feature was a decent solution at this point=

 (regardless of what you're talking about), since they're probably not usi=

 IDE with such a feature at this point.

I wouldn't say mature, I would say has traction, or has market penetration. Basically the language can be as mature as Fortran, but still be unused and hence have no community wishing to create tooling. There is also the question of whether to fit in with something pre-existing or create something new. Eclipse, IntelliJ IDEA, Code::Blocks, NetBeans, Emacs, Vim? For good or ill, the metric seems to be Eclipse support: no Eclipse tooling means no users. C++ has dealt with this. --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel russel.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Mar 01 2011
prev sibling next sibling parent reply spir <denis.spir gmail.com> writes:
On 02/28/2011 11:13 PM, Steven Schveighoffer wrote:
 But I still don't see the need for this feature. Aren't people using IDEs
 where the function signature (with parameter names) pops up when you're
 entering the function, and when you move the mouse over the function call?


You are wrong Don, this is not an argument. The feature is *not* for writing code, but for reading it (first your own code). Obviously, if you can write parameter names, this means you know them somehow, lol! The names provide highly valuable info at /reading/ time.
 Dunno, vim doesn't do that for me currently.  Also, if reviewing code on
 github, there is no ide.

Geany does it, but only for currently open files. Meaning, to have it work when programming in D, I should have the whole stdlib open in geany tabs... Anyway, as said above, this feature is 'orthogonal' to the question discussed in this thread. I'm fed up with people opposing to features very relevant for code clarity, which they are not forced to use, and can hardly bother when reading code themselves. Is the second statement below really that hard to read? p = new Point([1,2,3], [3,2,1]); p = new Point(color:[1,2,3], pos:[3,2,1]); Denis -- _________________ vita es estrany spir.wikidot.com
Mar 01 2011
next sibling parent reply Max Samukha <spam spam.com> writes:
On 01.03.2011 13:20, spir wrote:
 I'm fed up with people opposing to features very relevant for code
 clarity, which they are not forced to use, and can hardly bother when
 reading code themselves. Is the second statement below really that hard
 to read?
      p = new Point([1,2,3], [3,2,1]);
      p = new Point(color:[1,2,3], pos:[3,2,1]);

I hate that "explicitness improves code clarity and readability" argument. It may be true in some cases but most of the time explicitness creates unnecessary redundancy that actually impairs readability. Add a couple more Point instances with explicitly specified argument names and you will have useless and annoying noise. Named arguments are definitely useful when one needs to avoid specifying default parameter values but I still think we can live a happy life without them. At least until D3.
Mar 01 2011
next sibling parent Dmitry Olshansky <dmitry.olsh gmail.com> writes:
On 01.03.2011 15:52, Max Samukha wrote:
 On 01.03.2011 13:20, spir wrote:
 I'm fed up with people opposing to features very relevant for code
 clarity, which they are not forced to use, and can hardly bother when
 reading code themselves. Is the second statement below really that hard
 to read?
      p = new Point([1,2,3], [3,2,1]);
      p = new Point(color:[1,2,3], pos:[3,2,1]);

I hate that "explicitness improves code clarity and readability" argument. It may be true in some cases but most of the time explicitness creates unnecessary redundancy that actually impairs readability. Add a couple more Point instances with explicitly specified argument names and you will have useless and annoying noise. Named arguments are definitely useful when one needs to avoid specifying default parameter values but I still think we can live a happy life without them. At least until D3.

-- Dmitry Olshansky
Mar 01 2011
prev sibling parent reply Bekenn <leaveme alone.com> writes:
On 3/1/11 4:52 AM, Max Samukha wrote:
 I hate that "explicitness improves code clarity and readability"
 argument. It may be true in some cases but most of the time explicitness
 creates unnecessary redundancy that actually impairs readability.

Correct. However, named arguments are not a "most of the time" feature. Just look at some Python code, where named arguments have been supported for a very long time; you'll still mostly see people making calls using positional arguments, which is as it should be. Named arguments are there for when they're helpful, and get out of the way when they're not.
Mar 01 2011
parent reply Max Samukha <spam spam.com> writes:
On 01.03.2011 20:55, Bekenn wrote:
 On 3/1/11 4:52 AM, Max Samukha wrote:
 I hate that "explicitness improves code clarity and readability"
 argument. It may be true in some cases but most of the time explicitness
 creates unnecessary redundancy that actually impairs readability.

Correct. However, named arguments are not a "most of the time" feature. Just look at some Python code, where named arguments have been supported for a very long time; you'll still mostly see people making calls using positional arguments, which is as it should be. Named arguments are there for when they're helpful, and get out of the way when they're not.

I am not against named arguments. What I wanted to say is that writef(formatstr: "...", ) does not make the code more readable. Also, I shudder at the thought that the compiler guys may stop working on the toolchain issues and rush to implement named arguments instead.
Mar 02 2011
parent Bekenn <leaveme alone.com> writes:
On 3/2/2011 1:34 AM, Max Samukha wrote:
 I am not against named arguments. What I wanted to say is that
 writef(formatstr: "...", ) does not make the code more readable.

Right, agreed. This is one of the "not helpful" cases, where you simply don't use named arguments. I'd expect (and hope for) most function calls to fall into that category.
 Also, I
 shudder at the thought that the compiler guys may stop working on the
 toolchain issues and rush to implement named arguments instead.

I'm only just becoming aware of the scope of the toolchain issues, so I'm not really qualified to comment on that. This doesn't have to go to the front of the queue, but it'd be nice to see it scheduled for D2.
Mar 02 2011
prev sibling parent Bekenn <leaveme alone.com> writes:
On 3/1/11 4:40 AM, Lars T. Kyllingstad wrote:
 I just think that, at this late point in D2's development, the
 cost of adding them outweighs the benefits.  I mean, have you looked at
 the spec for D2 lately?  It's starting to look like the OOXML spec!

I started out a few weeks ago by reading through the entire spec as posted on the digitalmars site. It only took a few days of off-time reading. It's maybe a tenth the size of the C++ spec, if even that. Which is great -- I wouldn't want to needlessly bloat the spec -- but I don't think that argument carries much weight.
Mar 01 2011
prev sibling next sibling parent spir <denis.spir gmail.com> writes:
On 03/01/2011 08:49 AM, Jacob Carlborg wrote:
 On 2011-02-28 22:38, Don wrote:
 But I still don't see the need for this feature. Aren't people using
 IDEs where the function signature (with parameter names) pops up when
 you're entering the function, and when you move the mouse over the
 function call?
 And if you really want to see them all the time, why not build that
 feature into the IDE?
 ("hit ctrl-f9 to show all parameter names, hit it again to hide them").

That's very true. I'm used to that with Descent. On the other hand, I don't know how many editors that support this that also supports D.

And how does this feature help the reader and decode: f(1,"a",true); ? Denis -- _________________ vita es estrany spir.wikidot.com
Mar 01 2011
prev sibling next sibling parent spir <denis.spir gmail.com> writes:
On 03/01/2011 12:48 PM, Lars T. Kyllingstad wrote:
 On Tue, 01 Mar 2011 12:20:22 +0100, spir wrote:

 On 02/28/2011 11:13 PM, Steven Schveighoffer wrote:
 But I still don't see the need for this feature. Aren't people using
 IDEs where the function signature (with parameter names) pops up when
 you're entering the function, and when you move the mouse over the
 function call?


You are wrong Don, this is not an argument. The feature is *not* for writing code, but for reading it (first your own code). Obviously, if you can write parameter names, this means you know them somehow, lol! The names provide highly valuable info at /reading/ time.
 Dunno, vim doesn't do that for me currently.  Also, if reviewing code
 on github, there is no ide.

Geany does it, but only for currently open files. Meaning, to have it work when programming in D, I should have the whole stdlib open in geany tabs... Anyway, as said above, this feature is 'orthogonal' to the question discussed in this thread. I'm fed up with people opposing to features very relevant for code clarity, which they are not forced to use, and can hardly bother when reading code themselves. Is the second statement below really that hard to read? p = new Point([1,2,3], [3,2,1]); p = new Point(color:[1,2,3], pos:[3,2,1]);

Are the following really that hard to read? p = new Point(/* color */ [1,2,3], /* pos */ [3,2,1]); p = new Point( [1, 2, 3], // color [3, 2, 1], // pos );

Just like the unittest feature is very simple and brings no new functionality (you can very easily write unittests w/o the feature), but having them an official feature makes it nicer, obvious, and used everywhere. Denis -- _________________ vita es estrany spir.wikidot.com
Mar 01 2011
prev sibling next sibling parent Bekenn <leaveme alone.com> writes:
On 3/1/11 1:51 AM, Lars T. Kyllingstad wrote:
 I think I agree with you and Don here.  As for "skipping" default
 parameters, I suggest the following syntax:

    void foo(int i, bool b = true, real r = 3.14, string s = "")
    { ... }

    foo(1, , , "Hello World!");

 This is a much smaller language change than named parameters.

 -Lars

When reading existing code, can you easily spot the difference between: foo(1,,, "Hello World!"); and foo(1,,,, "Hello World!"); ? Unlike named arguments, I'd argue this syntax makes things quite a bit /less/ readable.
Mar 01 2011
prev sibling next sibling parent reply Bekenn <leaveme alone.com> writes:
On 2/28/11 1:38 PM, Don wrote:
 1. It makes parameter names part of the API.

I wrote earlier that this would probably be the first time parameter names "leaked" into user code, but I was wrong. Jacob Carlborg has pointed out his library implementation of this feature: http://dsource.org/projects/orange/browser/orange/util/Reflection.d#L135 If you look through his implementation, you'll see that it uses the .stringof property to extract parameter names from the function definition. In essence, parameter names are /already/ part of the API, because code can be written that depends on them. And the fact that a library implementation exists specifically to facilitate the use of named arguments implies that code already /has/ been written that depends on parameter names. Like it or not, parameter names are already part of the API. Adding named arguments as a language feature doesn't change that.
Mar 01 2011
parent reply Jim <bitcirkel yahoo.com> writes:
Jonathan M Davis Wrote:

 On Tuesday, March 01, 2011 11:22:17 Bekenn wrote:
 On 2/28/11 1:38 PM, Don wrote:
 1. It makes parameter names part of the API.

I wrote earlier that this would probably be the first time parameter names "leaked" into user code, but I was wrong. Jacob Carlborg has pointed out his library implementation of this feature: http://dsource.org/projects/orange/browser/orange/util/Reflection.d#L135 If you look through his implementation, you'll see that it uses the .stringof property to extract parameter names from the function definition. In essence, parameter names are /already/ part of the API, because code can be written that depends on them. And the fact that a library implementation exists specifically to facilitate the use of named arguments implies that code already /has/ been written that depends on parameter names. Like it or not, parameter names are already part of the API. Adding named arguments as a language feature doesn't change that.

You're talking about a third party library that's trying to hack in named arguments, not the language nor the standard library. The parameter names of a function are _not_ currently part of its signature. You could have a .di file without any parameter names or with totally different parameter names than the original .d file and it would have _zero_ effect on anything calling those functions. The function signature does _not_ include the name of its parameters - just their types. Adding named arguments would change that. - Jonathan M Davis

Neither are aliases signatures but they can still be imported. If the library writer choose to expose argument names in the .di file then I'd say they are part of the API.
Mar 02 2011
parent reply Don <nospam nospam.com> writes:
Jim wrote:
 Jonathan M Davis Wrote:
 
 On Tuesday, March 01, 2011 11:22:17 Bekenn wrote:
 On 2/28/11 1:38 PM, Don wrote:
 1. It makes parameter names part of the API.

names "leaked" into user code, but I was wrong. Jacob Carlborg has pointed out his library implementation of this feature: http://dsource.org/projects/orange/browser/orange/util/Reflection.d#L135 If you look through his implementation, you'll see that it uses the .stringof property to extract parameter names from the function definition. In essence, parameter names are /already/ part of the API, because code can be written that depends on them. And the fact that a library implementation exists specifically to facilitate the use of named arguments implies that code already /has/ been written that depends on parameter names. Like it or not, parameter names are already part of the API. Adding named arguments as a language feature doesn't change that.

arguments, not the language nor the standard library. The parameter names of a function are _not_ currently part of its signature. You could have a .di file without any parameter names or with totally different parameter names than the original .d file and it would have _zero_ effect on anything calling those functions. The function signature does _not_ include the name of its parameters - just their types. Adding named arguments would change that. - Jonathan M Davis

Neither are aliases signatures but they can still be imported. If the library writer choose to expose argument names in the .di file then I'd say they are part of the API.

The library writer has no choice. Templates function implementation must be included in the .di file. This exposes the parameter names. The proposal introduces additional coupling between library code and user code, which is useless in the majority of cases. I can see the value in an opt-in annotation (*not* opt-out) for those problem domains where large numbers of function parameters are normal. But I would strongly oppose it in general.
Mar 02 2011
next sibling parent reply Jim <bitcirkel yahoo.com> writes:
Steven Schveighoffer Wrote:

 On Wed, 02 Mar 2011 08:45:43 -0500, Jason E. Aten <j.e.aten gmail.com>  
 wrote:
 
 I find this an interesting discussion.  Coming from writing alot of code  
 in
 language that makes extensive and
 highly effective use of named arguments (R), I can say that optional  
 named
 arguments
 (as in Lisp, and descendants like Python and R) do have big software
 engineering benefits,
 but also come with a substantial costs in terms of complexity of the
 function call sequence.

 That is, named arguments can be expensive in a typical interpreted
 implementation
 (probably one reason why R and Python are much slower to execute than the
 other
 interpreted languages), presumably because each function call has to
 invoke hash
 table lookups to determine the canonical formal position of each actual
 argument, and deal with variadic
 cases, to rearrange the order of the arguments to match expectations of  
 the
 callee.

 Someone familiar with lisp compilers could probably tell you if the heavy
 speed tax is intrinsic
 or just the price of interpretation.

 It would indeed be an interesting challenge to see if the compile-time
 metaprogramming
 features of D would allow one to include named arguments in an opt-in
 fashion without speed reduction.

Considering that calling a function with parameters by name directly translates at compile time to a function call by position, there should be zero speed impact. The interpretation of the parameter names, which is done at runtime for Python, would be done at compile time in D. -Steve

In addition to that, named template arguments would allow you to create very customizable, yet lean types. It would be possible to parameterize all components. Basically, if you're not pleased with the default search algorithm or container type of a more complex object then you can specify your own.
Mar 02 2011
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 3/2/11 8:45 AM, Jim wrote:
 In addition to that, named template arguments would allow you to
 create very customizable, yet lean types. It would be possible to
 parameterize all components. Basically, if you're not pleased with
 the default search algorithm or container type of a more complex
 object then you can specify your own.

Got to say, named template arguments would be pretty awesome for policy-based design. There are other ways to deal with that (just accept variadic arguments and detect policies by signatures) but that's less clear for the client and aggravates the library writer. Andrei
Mar 02 2011
prev sibling parent Bekenn <leaveme alone.com> writes:
On 3/2/11 8:45 AM, spir wrote:
 I had never thought at that, but I'm surprised: what prevents Python's
 "compiler" (say, a semantic phase after parsing) to check number and
 names of arguments. (Number seems not to be checked before runtime
 neither.)
 All required information is in the AST. For named params, Python could
 translate to position params just like D. This would certainly remove a
 relevant amount of runtime "speed-down", I guess. (Only type-check of
 builtin func args must remain at runtime.)

 Denis

What follows is speculation; I'm not a Python programmer, but I am loosely familiar with the language. If I'm completely wrong, I'm sure someone will point it out: A Python "compiler" certainly can (and probably does) check function arguments, but the runtime is still heavily involved in argument passing. The complexity in Python is an artifact of how arguments are delivered at run-time: in a big (dynamically created, of course) dictionary. Essentially, The interpreter matches argument positions with parameter names -- at run time -- and then supplies those name/argument pairs as entries in the dictionary. (This is a logical view of the language, and may not precisely match implementations. For instance, I'd expect that "compiled" .pyc files throw out positional information ahead of time.) Looked at another way, *everything* is passed by name, not position; positional arguments are merely a shorthand notation. This is vastly different from how named arguments would be handled in D. D passes arguments by position -- end of story. Named arguments provide an alternative method of specifying the position of a given argument, which is determined by the compiler long before the linker or the runtime get involved.
Mar 02 2011
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Tuesday, March 01, 2011 11:22:17 Bekenn wrote:
 On 2/28/11 1:38 PM, Don wrote:
 1. It makes parameter names part of the API.

I wrote earlier that this would probably be the first time parameter names "leaked" into user code, but I was wrong. Jacob Carlborg has pointed out his library implementation of this feature: http://dsource.org/projects/orange/browser/orange/util/Reflection.d#L135 If you look through his implementation, you'll see that it uses the .stringof property to extract parameter names from the function definition. In essence, parameter names are /already/ part of the API, because code can be written that depends on them. And the fact that a library implementation exists specifically to facilitate the use of named arguments implies that code already /has/ been written that depends on parameter names. Like it or not, parameter names are already part of the API. Adding named arguments as a language feature doesn't change that.

You're talking about a third party library that's trying to hack in named arguments, not the language nor the standard library. The parameter names of a function are _not_ currently part of its signature. You could have a .di file without any parameter names or with totally different parameter names than the original .d file and it would have _zero_ effect on anything calling those functions. The function signature does _not_ include the name of its parameters - just their types. Adding named arguments would change that. - Jonathan M Davis
Mar 01 2011
prev sibling next sibling parent "Jason E. Aten" <j.e.aten gmail.com> writes:
--0016e6dee8341872a4049d80219b
Content-Type: text/plain; charset=ISO-8859-1

I find this an interesting discussion.  Coming from writing alot of code in
language that makes extensive and
highly effective use of named arguments (R), I can say that optional named
arguments
(as in Lisp, and descendants like Python and R) do have big software
engineering benefits,
but also come with a substantial costs in terms of complexity of the
function call sequence.

That is, named arguments can be expensive in a typical interpreted
implementation
(probably one reason why R and Python are much slower to execute than the
other
interpreted languages), presumably because each function call has to
invoke hash
table lookups to determine the canonical formal position of each actual
argument, and deal with variadic
cases, to rearrange the order of the arguments to match expectations of the
callee.

Someone familiar with lisp compilers could probably tell you if the heavy
speed tax is intrinsic
or just the price of interpretation.

It would indeed be an interesting challenge to see if the compile-time
metaprogramming
features of D would allow one to include named arguments in an opt-in
fashion without speed reduction.

Jason

On Wed, Mar 2, 2011 at 6:16 AM, Don <nospam nospam.com> wrote:

 Jim wrote:

 Jonathan M Davis Wrote:

  On Tuesday, March 01, 2011 11:22:17 Bekenn wrote:
 On 2/28/11 1:38 PM, Don wrote:

 1. It makes parameter names part of the API.

names "leaked" into user code, but I was wrong. Jacob Carlborg has pointed out his library implementation of this feature: http://dsource.org/projects/orange/browser/orange/util/Reflection.d#L135 If you look through his implementation, you'll see that it uses the .stringof property to extract parameter names from the function definition. In essence, parameter names are /already/ part of the API, because code can be written that depends on them. And the fact that a library implementation exists specifically to facilitate the use of named arguments implies that code already /has/ been written that depends on parameter names. Like it or not, parameter names are already part of the API. Adding named arguments as a language feature doesn't change that.

arguments, not the language nor the standard library. The parameter names of a function are _not_ currently part of its signature. You could have a .di file without any parameter names or with totally different parameter names than the original .d file and it would have _zero_ effect on anything calling those functions. The function signature does _not_ include the name of its parameters - just their types. Adding named arguments would change that. - Jonathan M Davis

Neither are aliases signatures but they can still be imported. If the library writer choose to expose argument names in the .di file then I'd say they are part of the API.

The library writer has no choice. Templates function implementation must be included in the .di file. This exposes the parameter names. The proposal introduces additional coupling between library code and user code, which is useless in the majority of cases. I can see the value in an opt-in annotation (*not* opt-out) for those problem domains where large numbers of function parameters are normal. But I would strongly oppose it in general.

--0016e6dee8341872a4049d80219b Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable I find this an interesting discussion. =A0Coming from writing alot of code = in language that makes extensive and<div>highly effective use of named argu= ments (R), I can say that optional named arguments=A0<div>(as in Lisp, and = descendants like Python and R) do have big software engineering benefits,= =A0</div> <div>but also come with a substantial=A0costs in terms of complexity of the= function call sequence.</div><div><br></div><div>That is, named arguments = can be expensive in a typical interpreted implementation</div><div>(probabl= y one reason why R and Python are much slower to execute than the other</di= v> <div>interpreted languages), presumably=A0because each function call has to= invoke=A0hash=A0</div><div>table lookups to determine the canonical formal= position of each actual argument, and deal with variadic</div><div>cases, = to rearrange the order of the arguments to match=A0expectations of the call= ee.</div> <div><br></div><div>Someone familiar with lisp compilers could probably tel= l you if the heavy speed tax is intrinsic</div><div>or just the price of in= terpretation.=A0</div><div><br></div><div>It would indeed be an interesting= challenge to see if the compile-time metaprogramming</div> <div>features of D would allow one to include named arguments in an opt-in = fashion without speed reduction.</div><div><br></div><div>Jason</div><div><= div><br><div class=3D"gmail_quote">On Wed, Mar 2, 2011 at 6:16 AM, Don <spa= n dir=3D"ltr">&lt;<a href=3D"mailto:nospam nospam.com">nospam nospam.com</a=
&gt;</span> wrote:<br>

x #ccc solid;padding-left:1ex;"><div><div></div><div class=3D"h5">Jim wrote= :<br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> Jonathan M Davis Wrote:<br> <br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> On Tuesday, March 01, 2011 11:22:17 Bekenn wrote:<br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> On 2/28/11 1:38 PM, Don wrote:<br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> 1. It makes parameter names part of the API.<br> </blockquote> I wrote earlier that this would probably be the first time parameter<br> names &quot;leaked&quot; into user code, but I was wrong. =A0Jacob Carlborg= has<br> pointed out his library implementation of this feature:<br> <br> <a href=3D"http://dsource.org/projects/orange/browser/orange/util/Reflectio= n.d#L135" target=3D"_blank">http://dsource.org/projects/orange/browser/oran= ge/util/Reflection.d#L135</a><br> <br> If you look through his implementation, you&#39;ll see that it uses the<br> .stringof property to extract parameter names from the function<br> definition. =A0In essence, parameter names are /already/ part of the API,<b= r> because code can be written that depends on them. =A0And the fact that a<br=

named arguments implies that code already /has/ been written that<br> depends on parameter names.<br> <br> Like it or not, parameter names are already part of the API. =A0Adding<br> named arguments as a language feature doesn&#39;t change that.<br> </blockquote> You&#39;re talking about a third party library that&#39;s trying to hack in= named arguments, not the language nor the standard library.<br> <br> The parameter names of a function are _not_ currently part of its signature= . You could have a .di file without any parameter names or with totally dif= ferent parameter names than the original .d file and it would have _zero_ e= ffect on anything calling those functions. The function signature does _not= _ include the name of its parameters - just their types. Adding named argum= ents would change that.<br> <br> - Jonathan M Davis<br> </blockquote> <br> <br> Neither are aliases signatures but they can still be imported. If the libra= ry writer choose to expose argument names in the .di file then I&#39;d say = they are part of the API.<br> </blockquote> <br></div></div> The library writer has no choice.<br> Templates function implementation must be included in the .di file. This ex= poses the parameter names.<br> <br> The proposal introduces additional coupling between library code and user c= ode, which is useless in the majority of cases.<br> <br> I can see the value in an opt-in annotation (*not* opt-out) for those probl= em domains where large numbers of function parameters are normal. But I wou= ld strongly oppose it in general.<br> <br> </blockquote></div><br><br> </div></div></div> --0016e6dee8341872a4049d80219b--
Mar 02 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 02 Mar 2011 08:45:43 -0500, Jason E. Aten <j.e.aten gmail.com>  
wrote:

 I find this an interesting discussion.  Coming from writing alot of code  
 in
 language that makes extensive and
 highly effective use of named arguments (R), I can say that optional  
 named
 arguments
 (as in Lisp, and descendants like Python and R) do have big software
 engineering benefits,
 but also come with a substantial costs in terms of complexity of the
 function call sequence.

 That is, named arguments can be expensive in a typical interpreted
 implementation
 (probably one reason why R and Python are much slower to execute than the
 other
 interpreted languages), presumably because each function call has to
 invoke hash
 table lookups to determine the canonical formal position of each actual
 argument, and deal with variadic
 cases, to rearrange the order of the arguments to match expectations of  
 the
 callee.

 Someone familiar with lisp compilers could probably tell you if the heavy
 speed tax is intrinsic
 or just the price of interpretation.

 It would indeed be an interesting challenge to see if the compile-time
 metaprogramming
 features of D would allow one to include named arguments in an opt-in
 fashion without speed reduction.

Considering that calling a function with parameters by name directly translates at compile time to a function call by position, there should be zero speed impact. The interpretation of the parameter names, which is done at runtime for Python, would be done at compile time in D. -Steve
Mar 02 2011
prev sibling next sibling parent "Jason E. Aten" <j.e.aten gmail.com> writes:
--0016367b629a38e45a049d814188
Content-Type: text/plain; charset=ISO-8859-1

On Wed, Mar 2, 2011 at 8:45 AM, Jim <bitcirkel yahoo.com> wrote:
 In addition to that, named template arguments would allow you to create
 very customizable, yet lean types. It would be possible to parameterize all
 components. Basically, if you're not pleased with the default search
 algorithm or container type of a more complex object then you can specify
 your own.

Interesting, I hadn't considered the benefits of template arguments with names as far as leanness of types. The best part of naming arguments for functions and methods, in my experience, is that if you add additional arguments to a method, it is a cheap change. I don't have to go and find and change all the client calls that have already been written. I can leave all of the existing source with client code untouched, and only specify the new parameter in the new invocation that wants to use the new functionality. I only have to recompile. Low maintenance. Nice. --0016367b629a38e45a049d814188 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <div><div><div class=3D"gmail_quote">On Wed, Mar 2, 2011 at 8:45 AM, Jim <s= pan dir=3D"ltr">&lt;<a href=3D"mailto:bitcirkel yahoo.com">bitcirkel yahoo.= com</a>&gt;</span> wrote:<blockquote class=3D"gmail_quote" style=3D"margin:= 0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"> In addition to that, named template arguments would allow you to create ver= y customizable, yet lean types. It would be possible to parameterize all co= mponents. Basically, if you&#39;re not pleased with the default search algo= rithm or container type of a more complex object then you can specify your = own.<br> </blockquote></div><div><br></div>Interesting, I hadn&#39;t considered the = benefits of template arguments with names as far as leanness of types.</div=
<div><br>The best part of naming arguments for functions and methods, in m=

cheap change. I=A0don&#39;t have to go and find and change all the client c= alls that have already been written. I can leave all of the existing source= with client code untouched, and only specify the new parameter in the new = invocation that wants to use the new functionality. =A0I only have to recom= pile. =A0Low maintenance. =A0Nice. =A0<div> =A0</div><br> </div></div> --0016367b629a38e45a049d814188--
Mar 02 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 02 Mar 2011 10:06:17 -0500, Jason E. Aten <j.e.aten gmail.com>  
wrote:

 On Wed, Mar 2, 2011 at 8:45 AM, Jim <bitcirkel yahoo.com> wrote:
 In addition to that, named template arguments would allow you to create
 very customizable, yet lean types. It would be possible to parameterize  
 all
 components. Basically, if you're not pleased with the default search
 algorithm or container type of a more complex object then you can  
 specify
 your own.

Interesting, I hadn't considered the benefits of template arguments with names as far as leanness of types. The best part of naming arguments for functions and methods, in my experience, is that if you add additional arguments to a method, it is a cheap change. I don't have to go and find and change all the client calls that have already been written. I can leave all of the existing source with client code untouched, and only specify the new parameter in the new invocation that wants to use the new functionality. I only have to recompile. Low maintenance. Nice.

This isn't as dynamic as you think. If you change a function's argument types or count, the client must recompile. However, their code shouldn't have to change. -Steve
Mar 02 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 02 Mar 2011 13:38:05 -0500, Bekenn <leaveme alone.com> wrote:

 On 3/2/11 8:45 AM, spir wrote:
 I had never thought at that, but I'm surprised: what prevents Python's
 "compiler" (say, a semantic phase after parsing) to check number and
 names of arguments. (Number seems not to be checked before runtime
 neither.)
 All required information is in the AST. For named params, Python could
 translate to position params just like D. This would certainly remove a
 relevant amount of runtime "speed-down", I guess. (Only type-check of
 builtin func args must remain at runtime.)

 Denis

What follows is speculation; I'm not a Python programmer, but I am loosely familiar with the language. If I'm completely wrong, I'm sure someone will point it out: A Python "compiler" certainly can (and probably does) check function arguments, but the runtime is still heavily involved in argument passing. The complexity in Python is an artifact of how arguments are delivered at run-time: in a big (dynamically created, of course) dictionary. Essentially, The interpreter matches argument positions with parameter names -- at run time -- and then supplies those name/argument pairs as entries in the dictionary. (This is a logical view of the language, and may not precisely match implementations. For instance, I'd expect that "compiled" .pyc files throw out positional information ahead of time.) Looked at another way, *everything* is passed by name, not position; positional arguments are merely a shorthand notation. This is vastly different from how named arguments would be handled in D. D passes arguments by position -- end of story. Named arguments provide an alternative method of specifying the position of a given argument, which is determined by the compiler long before the linker or the runtime get involved.

Not a python expert either, but I think you are right. Most dynamic languages are this way -- because you need that flexibility since a "compiled" script might not be recompiled after you change the API. And also, many dynamic languages allow changing the API mid-program (not sure about python). There would just be no way to determine this at compile time. -Steve
Mar 02 2011
prev sibling next sibling parent Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
On 28/02/2011 21:38, Don wrote:
 But I still don't see the need for this feature. Aren't people using
 IDEs where the function signature (with parameter names) pops up when
 you're entering the function, and when you move the mouse over the
 function call?
 And if you really want to see them all the time, why not build that
 feature into the IDE?
 ("hit ctrl-f9 to show all parameter names, hit it again to hide them").

That's exactly the point I was going to make, as soon as I saw the question/challenge of " HRESULT hr = m_Device.Present(null, null, null, null); Quick: What behavior does that third argument specify?" For such a fine grained and common situation, looking that API up anywhere outside the IDE (such as in a webpage, or in a file in a filesystem) in any serious development just seems to me very archaic. But hey, maybe I'm just spoiled by Java... :P -- Bruno Medeiros - Software Engineer
Mar 08 2011
prev sibling next sibling parent reply Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
On 28/02/2011 22:13, Steven Schveighoffer wrote:


 Dunno, vim doesn't do that for me currently.

I feel tempted to say something very short and concise regarding vim and emacs, but it would require a large amount of justification to properly expose such point. I am planning to write a blog post about that, but I haven't gotten to it yet.
 Also, if reviewing code on github, there is no ide.

 -Steve

A) Should we give any significant weight to very minute and relatively infrequent code reading situations, like web-based code reviewing in github or whatever, or reading code in books? I doubt so. B) If the pull request is large, it should be near effortless to put those changes in the IDE and review them there. -- Bruno Medeiros - Software Engineer
Mar 08 2011
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Bruno Medeiros:

 A) Should we give any significant weight to very minute and relatively 
 infrequent code reading situations, like web-based code reviewing in 
 github or whatever, or reading code in books? I doubt so.

Named arguments allow to improve the reading of code everywhere, in editors too. Reading code in texts, emails, or online, is a common thing for me. I see every day pieces of code in this newsgroup. I suggest you to try to use for few months a language that allows named arguments.
The question that should be asked is if D should be optimized for IDE usage or
not...<

I think modern languages need to be designed to be aware of the existence of IDEs. So far the D design seems to ignore IDEs. On the other hand C# (and other languages) have or have added named arguments even if they are often used in IDEs. Bye, bearophile
Mar 08 2011
prev sibling next sibling parent reply Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
On 08/03/2011 21:37, Steven Schveighoffer wrote:
 On Tue, 08 Mar 2011 15:29:28 -0500, Bruno Medeiros
 <brunodomedeiros+spam com.gmail> wrote:

 On 28/02/2011 22:13, Steven Schveighoffer wrote:


 Dunno, vim doesn't do that for me currently.

I feel tempted to say something very short and concise regarding vim and emacs, but it would require a large amount of justification to properly expose such point. I am planning to write a blog post about that, but I haven't gotten to it yet.
 Also, if reviewing code on github, there is no ide.

 -Steve

A) Should we give any significant weight to very minute and relatively infrequent code reading situations, like web-based code reviewing in github or whatever, or reading code in books? I doubt so.

I contest that web based code reviewing is going to be infrequent, since all major phobos changes now must be reviewed by 2 peers before inclusion. Please look at a recent pull request review I participated in, without ever opening an editor/ide. GitHub provides very good collaborative review. If I have to install an IDE that I only use for reviewing, um... no. https://github.com/jmdavis/phobos/commit/aca1a2d7cfe7d5e934668e06028b78ffb6796245

Hum, looking at that GitHub pull request (first time I have done so), GitHub does look quite nice in terms of code reviewing functionality. So, hum, I do agree that web-based code reviewing might become significantly frequent (if it is not already). (Note that I am not talking about Phobos development only) Although in the particular cased of named arguments, I still don't feel it is worthwhile. Not unless it could be done in a very orthogonal way (both in semantics and syntax), and even so it should likely be very low priority (as in, not any time soon...).
 B) If the pull request is large, it should be near effortless to put
 those changes in the IDE and review them there.

Again, don't have one. -Steve

Just because you don't have or don't use an IDE, that is not an argument against doing B). What should be considered is whether it is worthwhile to review it in an IDE or do it the web application, for a given change request. At the moment, probably not (although I would say it depends a lot on the D code and the underlying project). But in the future things might change. It could even be that a web-based application like GitHub would grow some IDE features, like the one about parameters context information. -- Bruno Medeiros - Software Engineer
Mar 09 2011
parent reply Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
On 09/03/2011 17:20, Steven Schveighoffer wrote:
 On Wed, 09 Mar 2011 09:02:14 -0500, Bruno Medeiros
 <brunodomedeiros+spam com.gmail> wrote:

 Although in the particular cased of named arguments, I still don't
 feel it is worthwhile. Not unless it could be done in a very
 orthogonal way (both in semantics and syntax), and even so it should
 likely be very low priority (as in, not any time soon...).

It's one of those things where, in some cases, not having named arguments makes code unreadable. But having named arguments does not make *all* code more readable. In many many cases, code is readable just fine without using the named arguments. But those cases where it does help, it's essential. Like Don's CreateFont example (actually almost any GUI function). We might do something like require explicit comments for confusing functions like: foo( null, // paramA null, // paramB null, // paramC ); during the review process. It would at least document properly what is happening. I see not too much value in the "skip default parameter" prospect, most code can do fine without that via overloading. But the documentation and compiler verification of parameter names is what I see as the killer feature here.
 B) If the pull request is large, it should be near effortless to put
 those changes in the IDE and review them there.

Again, don't have one. -Steve

Just because you don't have or don't use an IDE, that is not an argument against doing B).

It absolutely is. I use NetBeans for doing php development. It took me hours and hours to set it up properly, install the right add-ons, etc. I'm not about to do that for something like descent or DDT so I can properly read code, I'm way more likely to just go look up the function signature myself for the few times I need it. Just having the named arguments idea makes so much more sense than having to load a specialized (and I might add, way overkill for just reviewing code in both size and complexity) tool.

Now that is an argument. Although I still don't agree: it really shouldn't take that long to setup an IDE (if Netbeans and/or its PHP plugin are crappy, don't use that to blame all IDEs :P ). But in any case this is kinda besides the point, because setting up an IDE is a one-time affair (reviewing code is many-times). For small changes, yeah, it might be overkill to fire up an IDE. However I think the ideal solution in this issue is to bring a bit more IDE functionality to the web. There are already some projects loosely related to this underway, for example Orion (http://adtmag.com/articles/2011/03/21/eclipse-orion-hub.aspx ) from the Eclipse Foundation, of which Github is one of the involved parties. But for bigger changes (in fact even for smaller ones as well) it might be worthwhile to use an IDE tool, because it can offer a lot of help in navigation and other stuff related to reviewing the code. I mean, the named arguments only address a very limited problem in reviewing code: it only tells you which parameter corresponds each argument. But what if you need to read the function's documentation to know or remind yourself what the function does, if the arguments have correct values, respect the contract, etc.? You'll likely need to open the function declaration in any case, in one way or another. -- Bruno Medeiros - Software Engineer
Mar 23 2011
next sibling parent Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
On 23/03/2011 16:12, Bruno Medeiros wrote:
 But for bigger changes (in fact even for smaller ones as well) it might
 be worthwhile to use an IDE tool, because it can offer a lot of help in
 navigation and other stuff related to reviewing the code. I mean, the
 named arguments only address a very limited problem in reviewing code:
 it only tells you which parameter corresponds each argument. But what if
 you need to read the function's documentation to know or remind yourself
 what the function does, if the arguments have correct values, respect
 the contract, etc.? You'll likely need to open the function declaration
 in any case, in one way or another.

Actually... what if you want to make sure it compiles? Or to run unit tests? Or just run and test it manually? You can't do any of those on the web. If you are just commenting on changes it might be fine, but if you are the one approving the code changes, I can hardly see how you can escape those tasks above (other than for very simple one-line changes), and thus the use of local tools. -- Bruno Medeiros - Software Engineer
Mar 23 2011
prev sibling parent reply Bekenn <leaveme alone.com> writes:
On 3/23/2011 9:12 AM, Bruno Medeiros wrote:
 Now that is an argument. Although I still don't agree: it really
 shouldn't take that long to setup an IDE (if Netbeans and/or its PHP
 plugin are crappy, don't use that to blame all IDEs :P ). But in any
 case this is kinda besides the point, because setting up an IDE is a
 one-time affair (reviewing code is many-times).

There is far more cost involved in using an IDE than the setup time. A typical IDE will: - Consume a relatively large chunk of space. Visual Studio on my system takes up 1.9 GB, with one of the platform SDKs taking up an additional 565 MB. XCode on my other system eats up a whopping 9.7 GB (!) with the iOS SDK (the download for XCode 4 with iOS SDK 4.3 is 4.2 GB for the .dmg file). Eclipse puts them both to shame at 268 MB for Eclipse Classic, with the JDK adding 179 MB on top of that. (I only use Eclipse for Android development, so I haven't installed anything beyond the base classic package.) For D development, I use Notepad++, which is just an editor -- 11.8 MB (plus 105 MB for dmd and associated tools). - Hijack file extensions. I have several versions of Visual Studio installed that all cooperate very nicely with each other, but if I were to install Eclipse for C/C++ development, I'd have to remember to tell it not to take over handling for .c/.cpp files. This isn't such a big deal if the IDE only handles one or two languages, but if it's a multi-language IDE, then there may be a list of twenty or more file types to scroll through, assuming that the installer is even nice enough to let you choose. - Have its own shortcuts, features, and quirks. In Visual Studio, I can hit tab to confirm intellisense suggestions. If I do the same thing in Eclipse, then I end up shifting focus over to the documentation popup window, which is just maddeningly stupid. XCode doesn't give me a list; it just inserts its suggestion inline, and then I have to either hit escape or keep typing if I want something else entirely. (XCode's suggestions also seem to be highly non-deterministic in nature; I think their algorithm would make for a great prng.) Build in Visual Studio is F7. In Eclipse, it's ctrl-b, which at least matches XCode's cmd-b. This can be mitigated in most cases by changing key bindings, but now you're looking at either a short list of commands that can be changed (which might not include the command you're looking for), or a very, *very* long list with hundreds of commands that you have to wade through. What's more, you have to figure out what name the IDE gives to the feature you're looking for, and it may not always be clear. Eclipse provides a search bar to make it easier; good thing, too, because typing "content assist" into that bar gives me back *21 different entries*! - Have its own unique, non-portable project format. Some IDEs can work with makefiles, but even most of those don't actually use a makefile as its preferred project format. This means that if you're looking at different projects from n different people/groups, you may need O(log(n)) different IDEs just to be able to open up their project. On the flip side, if you're the author of a project and you want people to be able to use their favorite IDE, then you have to provide several different sets of project configuration files. At least with makefiles, other people can build your project from the command-line without installing your favorite IDE. (Same goes for Visual Studio project files, actually; you can build those from the command line with MSBuild without having to install Visual Studio.) Lastly, at this point, D just doesn't have much in the line of support from major IDEs. There are neat projects like Descent and VisualD, but that's hardly the breadth or scope of support that you'd get with an established, highly-visible language. IDEs are simply not part of the language specification, and the language shouldn't be designed under the assumption that everyone's going to use an IDE, especially if you're thinking about a particular feature which many IDEs might not even have. Don't get me wrong -- I love IDEs. They can be very helpful, especially when it comes to dependency tracking and assisted editing. Right now, I use Notepad++ for D because I don't feel that the existing alternatives really offer that much useful functionality beyond what that editor provides. I'm working on some MSBuild tasks to make the process easier (yes, I develop primarily in Windows), and the IDE story will get better, but these things take a lot of time to fully materialize.
Mar 23 2011
next sibling parent Daniel Gibson <metalcaedes gmail.com> writes:
Am 24.03.2011 07:36, schrieb Bekenn:
 On 3/23/2011 9:12 AM, Bruno Medeiros wrote:
 Now that is an argument. Although I still don't agree: it really
 shouldn't take that long to setup an IDE (if Netbeans and/or its PHP
 plugin are crappy, don't use that to blame all IDEs :P ). But in any
 case this is kinda besides the point, because setting up an IDE is a
 one-time affair (reviewing code is many-times).

There is far more cost involved in using an IDE than the setup time. A typical IDE will: - Consume a relatively large chunk of space. Visual Studio on my system takes up 1.9 GB, with one of the platform SDKs taking up an additional 565 MB. XCode on my other system eats up a whopping 9.7 GB (!) with the iOS SDK (the download for XCode 4 with iOS SDK 4.3 is 4.2 GB for the .dmg file). Eclipse puts them both to shame at 268 MB for Eclipse Classic, with the JDK adding 179 MB on top of that. (I only use Eclipse for Android development, so I haven't installed anything beyond the base classic package.) For D development, I use Notepad++, which is just an editor -- 11.8 MB (plus 105 MB for dmd and associated tools).

9,7GB is pretty much.. but how much of that is iOS SDK stuff? However: Eclipse is pretty bloated and still only uses <300MB in your configuration.. And in times of multiple Terabyte Harddisks a few hundred MBs (or even a 2-3GBs) for an IDE is not really a problem.
 - Hijack file extensions. I have several versions of Visual Studio
 installed that all cooperate very nicely with each other, but if I were
 to install Eclipse for C/C++ development, I'd have to remember to tell
 it not to take over handling for .c/.cpp files. This isn't such a big
 deal if the IDE only handles one or two languages, but if it's a
 multi-language IDE, then there may be a list of twenty or more file
 types to scroll through, assuming that the installer is even nice enough
 to let you choose.

This can happen with normal text editors as well and is more an issue of crappy IDEs that do this stuff without asking you than with IDEs in general.
 - Have its own shortcuts, features, and quirks. In Visual Studio, I can
 hit tab to confirm intellisense suggestions. If I do the same thing in
 Eclipse, then I end up shifting focus over to the documentation popup
 window, which is just maddeningly stupid. XCode doesn't give me a list;
 it just inserts its suggestion inline, and then I have to either hit
 escape or keep typing if I want something else entirely. (XCode's
 suggestions also seem to be highly non-deterministic in nature; I think
 their algorithm would make for a great prng.) Build in Visual Studio is
 F7. In Eclipse, it's ctrl-b, which at least matches XCode's cmd-b. This
 can be mitigated in most cases by changing key bindings, but now you're
 looking at either a short list of commands that can be changed (which
 might not include the command you're looking for), or a very, *very*
 long list with hundreds of commands that you have to wade through.
 What's more, you have to figure out what name the IDE gives to the
 feature you're looking for, and it may not always be clear. Eclipse
 provides a search bar to make it easier; good thing, too, because typing
 "content assist" into that bar gives me back *21 different entries*!

The same happens with normal editors, vi and emacs have totally different shortcuts. Cheers, - Daniel
Mar 24 2011
prev sibling parent reply Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
On 24/03/2011 06:36, Bekenn wrote:
 On 3/23/2011 9:12 AM, Bruno Medeiros wrote:
 Now that is an argument. Although I still don't agree: it really
 shouldn't take that long to setup an IDE (if Netbeans and/or its PHP
 plugin are crappy, don't use that to blame all IDEs :P ). But in any
 case this is kinda besides the point, because setting up an IDE is a
 one-time affair (reviewing code is many-times).

There is far more cost involved in using an IDE than the setup time. A typical IDE will: - Consume a relatively large chunk of space. Visual Studio on my system takes up 1.9 GB, with one of the platform SDKs taking up an additional 565 MB. XCode on my other system eats up a whopping 9.7 GB (!) with the iOS SDK (the download for XCode 4 with iOS SDK 4.3 is 4.2 GB for the .dmg file). Eclipse puts them both to shame at 268 MB for Eclipse Classic, with the JDK adding 179 MB on top of that. (I only use Eclipse for Android development, so I haven't installed anything beyond the base classic package.) For D development, I use Notepad++, which is just an editor -- 11.8 MB (plus 105 MB for dmd and associated tools). - Hijack file extensions. I have several versions of Visual Studio installed that all cooperate very nicely with each other, but if I were to install Eclipse for C/C++ development, I'd have to remember to tell it not to take over handling for .c/.cpp files. This isn't such a big deal if the IDE only handles one or two languages, but if it's a multi-language IDE, then there may be a list of twenty or more file types to scroll through, assuming that the installer is even nice enough to let you choose. - Have its own shortcuts, features, and quirks. In Visual Studio, I can hit tab to confirm intellisense suggestions. If I do the same thing in Eclipse, then I end up shifting focus over to the documentation popup window, which is just maddeningly stupid. XCode doesn't give me a list; it just inserts its suggestion inline, and then I have to either hit escape or keep typing if I want something else entirely. (XCode's suggestions also seem to be highly non-deterministic in nature; I think their algorithm would make for a great prng.) Build in Visual Studio is F7. In Eclipse, it's ctrl-b, which at least matches XCode's cmd-b. This can be mitigated in most cases by changing key bindings, but now you're looking at either a short list of commands that can be changed (which might not include the command you're looking for), or a very, *very* long list with hundreds of commands that you have to wade through. What's more, you have to figure out what name the IDE gives to the feature you're looking for, and it may not always be clear. Eclipse provides a search bar to make it easier; good thing, too, because typing "content assist" into that bar gives me back *21 different entries*! - Have its own unique, non-portable project format. Some IDEs can work with makefiles, but even most of those don't actually use a makefile as its preferred project format. This means that if you're looking at different projects from n different people/groups, you may need O(log(n)) different IDEs just to be able to open up their project. On the flip side, if you're the author of a project and you want people to be able to use their favorite IDE, then you have to provide several different sets of project configuration files. At least with makefiles, other people can build your project from the command-line without installing your favorite IDE. (Same goes for Visual Studio project files, actually; you can build those from the command line with MSBuild without having to install Visual Studio.) Lastly, at this point, D just doesn't have much in the line of support from major IDEs. There are neat projects like Descent and VisualD, but that's hardly the breadth or scope of support that you'd get with an established, highly-visible language. IDEs are simply not part of the language specification, and the language shouldn't be designed under the assumption that everyone's going to use an IDE, especially if you're thinking about a particular feature which many IDEs might not even have. Don't get me wrong -- I love IDEs. They can be very helpful, especially when it comes to dependency tracking and assisted editing. Right now, I use Notepad++ for D because I don't feel that the existing alternatives really offer that much useful functionality beyond what that editor provides. I'm working on some MSBuild tasks to make the process easier (yes, I develop primarily in Windows), and the IDE story will get better, but these things take a lot of time to fully materialize.

Well, now we go back to discussion of the discussion of whether one thinks it's worthwhile to use and IDE or not (for general development, not just code reviews). I don't want to go into this discussion again, at least not now so soon. I think that what we all may take from the discussion I was having from Steven right now, and maybe everyone agree with, is that whether it's worthwhile to use an IDE for code reviews is reduced to the discussion of whether it's worthwhile to use an IDE generally or not. In other words, if you don't do the tasks I mentioned before (looking up documentation, compiling and running code, running tests. also, using the source control system) from inside the IDE when developing yourself, you will definitely won't want to use it when code reviewing, accepting patches, etc.. -- Bruno Medeiros - Software Engineer
Mar 24 2011
parent Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
On 24/03/2011 20:23, Steven Schveighoffer wrote:
 P.S. I've tried two D ides in the past for about 10 minutes (descent and
 code::blocks), could not get either of them to work right. And it was
 *not* trivial to set them up.

I must invite you try out DDT :D , even you don't stick to using it aferward. It should be no more than 5 minutes to setup (download times excluding): http://code.google.com/a/eclipselabs.org/p/ddt/wiki/UserGuide *fingers crossed* -- Bruno Medeiros - Software Engineer
Mar 29 2011
prev sibling parent Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
On 09/03/2011 06:10, Brad Roberts wrote:
 Personally, I spend_way_  more time reading code (mine or other peoples) than
I spend writing code.  Ignoring time, I
 also read far more lines/files/whatever code than I write.  I suspect these
things are going to vary highly from person
 to person and from job role to job role.  Those that primarily produce new
applications, tools, websites, etc and do
 little maintenance programming will be the polar opposite.

Me too, I also spend a lot of time reading and trying to understand code, especially when working with Eclipse, which is a huge code base. But I do it inside the IDE. I didn't mean reading in any kind of situation, but only minute ones when tools are not available. Like reading a book, reading a online guide/tutorial/snippet, etc.. -- Bruno Medeiros - Software Engineer
Mar 09 2011
prev sibling next sibling parent Brad Roberts <braddr puremagic.com> writes:
On 3/8/2011 12:29 PM, Bruno Medeiros wrote:
 On 28/02/2011 22:13, Steven Schveighoffer wrote:
 
 
 Dunno, vim doesn't do that for me currently.

I feel tempted to say something very short and concise regarding vim and emacs, but it would require a large amount of justification to properly expose such point. I am planning to write a blog post about that, but I haven't gotten to it yet.
 Also, if reviewing code on github, there is no ide.

 -Steve

A) Should we give any significant weight to very minute and relatively infrequent code reading situations, like web-based code reviewing in github or whatever, or reading code in books? I doubt so. B) If the pull request is large, it should be near effortless to put those changes in the IDE and review them there.

Personally, I spend _way_ more time reading code (mine or other peoples) than I spend writing code. Ignoring time, I also read far more lines/files/whatever code than I write. I suspect these things are going to vary highly from person to person and from job role to job role. Those that primarily produce new applications, tools, websites, etc and do little maintenance programming will be the polar opposite. Regarding B, if a pull/review request is large, I'll likely send it back with instructions to break it into small pull requests. Or at a minimum a series of small commits. Gigantic lumps of code (particularly many separable changes all done at once) are just a bad idea no matter how you arrange it. My 2 cents, Brad
Mar 08 2011
prev sibling next sibling parent reply Gareth Charnock <gareth.charnock gmail.com> writes:
Named arguments are useful when you have a function that takes a large 
number of parameters, the vast majority of which have default values. 
For example, have a look at this constructor in wxWidgets:

http://docs.wxwidgets.org/trunk/classwx_frame.html#01b53ac2d4a5e6b0773ecbcf7b5f6af8

wxFrame::wxFrame	(	wxWindow * 	parent,
wxWindowID 	id,
const wxString & 	title,
const wxPoint & 	pos = wxDefaultPosition,
const wxSize & 	size = wxDefaultSize,
long 	style = wxDEFAULT_FRAME_STYLE,
const wxString & 	name = wxFrameNameStr	
)

If you want to change the name argument you need to call

new wxFrame(a_parent,wxANY,"Hello 
world",wxDefaultPosition,wxDefaultSize,wxDEFAULT_FRAME_STYLE,"My Custom 
name str")

Which meant I had to look up what the default values of pos,size and 
style where even though I was happy with those default values. The more 
arguments the more of a pain this setup is without named arguments. 
Contrast to a hypothetical C++ syntax:

new wxFrame(a_parent,wxANY,"Hello world",name = "My Custom name str")

I haven't bothered with the arguments I don't care about and my function 
call has ended up less sensitive to changes in the wxFrame constructor.

On 28/02/11 21:50, Jonathan M Davis wrote:
 On Monday, February 28, 2011 13:38:34 Don wrote:
 spir wrote:
 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.


I agree. CreateFont() in the Windows API, I'm looking at you. (For Linux people, that function has about 12 parameters).
 ???

 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!

You don't have that option. At least, if you're a library developer, you don't. (I'm a bit sick of people saying "you don't have to use it if you don't want to" in language design. If it is in the language, you don't have a choice. You will encounter it). There are a couple of things that I really, really don't like about the names argument idea: 1. It makes parameter names part of the API. Providing no way for the function writer to control whether it is part of the API or not, and especially, doing it retrospectively, strikes me as extremely rude. 2. It introduces a different syntax for calling a function. foo(4, 5); foo(x: 4, y: 5); They look different, but they do exactly the same thing. I don't like that redundancy. Especially since, as far as I can tell, the named arguments are just comments (which the compiler can check). If so, a syntax like this would be possible, with no language change at all: pragma(namedarguments); // applies to whole module foo(/*x*/ 4, /*y*/ 5); ---> if a function parameter has a comment which forms a valid identifier, it's a named parameter. But I still don't see the need for this feature. Aren't people using IDEs where the function signature (with parameter names) pops up when you're entering the function, and when you move the mouse over the function call? And if you really want to see them all the time, why not build that feature into the IDE? ("hit ctrl-f9 to show all parameter names, hit it again to hide them").

I agree with pretty much everything said here. However, as I understand it, named parameters (at least as they work in Python) would allow for you to reorder parameters and give values for paramters which are normally default parameters without giving values for the default paramters before them, and those changes could not be dealt with by comments. However, I consider them to be a big _problem_, not a feature - _especially_ the ability to rearrange the function arguments. All of a sudden you could have foo(4, 5); foo(x : 4, y : 5); foo(y : 5, X : 4); all making _exactly_ the same function call. That seem _very_ bug-prone and confusing to me. foo(x : 4, y : 5) was bad enough, but allowing foo(y : 5, x : 4)? Not good. The amount of effort to understand the code becomes considerably higher. You could be very familiar with foo and know exactly what parameters it takes and totally mistake what it's really getting passed, because the arguments were flipped in comparison to the function parameters. I agree with Don. I think that named parameters would cause far more intellectual overhead and problems than they'd solve. - Jonathan M Davis - Jonathan M Davis

Mar 09 2011
parent Stewart Gordon <smjg_1998 yahoo.com> writes:
On 09/03/2011 12:22, Gareth Charnock wrote:
<snip>
 Which meant I had to look up what the default values of pos,size and style
where even
 though I was happy with those default values. The more arguments the more of a
pain this
 setup is without named arguments. Contrast to a hypothetical C++ syntax:

 new wxFrame(a_parent,wxANY,"Hello world",name = "My Custom name str")

This isn't hypothetical C++ syntax, it's perfectly legal C++ syntax. It is equivalent to name = "My Custom Name str", new wxFrame(a_parent, wxANY, "Hello world", name) Struct and array initialisers use a colon, not an equals sign, and if we add named arguments they would need to do the same to avoid changing the meaning of existing code. You may be just illustrating the concept and not proposing this as the actual syntax to add to C++ or D, but being careful now will help you to get used to the feature when/if it arrives. Stewart.
Mar 11 2011
prev sibling parent spir <denis.spir gmail.com> writes:
On 03/09/2011 06:20 PM, Steven Schveighoffer wrote:
 It's kind of like arrays in D.  Every time I have to use another language, I
 miss D's array syntax features.  All the same functionality is there, it just
 takes more effort to do the same thing.  That little effort is not terrible,
 but I much prefer not having to do it.

Agreed. This overall programmer-friendly design, is D's very big + for me. Denis -- _________________ vita es estrany spir.wikidot.com
Mar 09 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Another alternative is to introduce named arguments and get rid of
that extra housekeeping.
Feb 28 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
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
Feb 28 2011
prev sibling next sibling parent spir <denis.spir gmail.com> writes:
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
Feb 28 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
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).
Feb 28 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
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;
}
Feb 28 2011
prev sibling next sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
spir <denis.spir gmail.com> wrote:

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

:= is acceptable to me. It does not clash with anything, and clearly shows that something is being set to something. -- Simen
Feb 28 2011
prev sibling next sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
Adam Ruppe <destructionator gmail.com> wrote:

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

 struct Width { int width; alias width this; }

 foo(Width(10), Height(20));

Clearly this can be done better: struct _(string s) { int data; alias data this; } foo(_!"width"(10), _!"height"(20)); -- Simen
Feb 28 2011
prev sibling next sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
Bekenn <leaveme alone.com> wrote:

 On 2/28/11 11:53 AM, spir wrote:
 Agreed, and I'm not for adding non-obvious "signs". D is not Perl. Or
 else use ':=' ?

 Denis

I think we should stick with ':' due to its existing use in static struct initializers.

Seconded. -- Simen
Feb 28 2011
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, February 28, 2011 11:37:04 Steven Schveighoffer wrote:
 On Mon, 28 Feb 2011 14:33:55 -0500, Jonathan M Davis <jmdavisProg gmx.com>
 
 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.

foo(dimensions(123, 456)); // not helping

Like, I said if you're passing around the width and height much (as opposed to just once), then it definitely helps. But it doesn't necessarily help at the point of construction, so if you're just passing them to one function, then you don't really benefit. Still, I don't think that an example like this one makes the feature pulls its weight. Regardless, there are obviously a lot of people who like the idea, so if they can get Walter's support, it'll likely go in. I'd just as soon that it didn't, but it's not like it's my decision, and unless all the people who dislike it are silent or haven't read this thread, it definitely looks like the majority of folks around here are in favor of it. - Jonathan M Davis
Feb 28 2011
prev sibling next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, February 28, 2011 13:38:34 Don wrote:
 spir wrote:
 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.


I agree. CreateFont() in the Windows API, I'm looking at you. (For Linux people, that function has about 12 parameters).
 ???
 
 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!

You don't have that option. At least, if you're a library developer, you don't. (I'm a bit sick of people saying "you don't have to use it if you don't want to" in language design. If it is in the language, you don't have a choice. You will encounter it). There are a couple of things that I really, really don't like about the names argument idea: 1. It makes parameter names part of the API. Providing no way for the function writer to control whether it is part of the API or not, and especially, doing it retrospectively, strikes me as extremely rude. 2. It introduces a different syntax for calling a function. foo(4, 5); foo(x: 4, y: 5); They look different, but they do exactly the same thing. I don't like that redundancy. Especially since, as far as I can tell, the named arguments are just comments (which the compiler can check). If so, a syntax like this would be possible, with no language change at all: pragma(namedarguments); // applies to whole module foo(/*x*/ 4, /*y*/ 5); ---> if a function parameter has a comment which forms a valid identifier, it's a named parameter. But I still don't see the need for this feature. Aren't people using IDEs where the function signature (with parameter names) pops up when you're entering the function, and when you move the mouse over the function call? And if you really want to see them all the time, why not build that feature into the IDE? ("hit ctrl-f9 to show all parameter names, hit it again to hide them").

I agree with pretty much everything said here. However, as I understand it, named parameters (at least as they work in Python) would allow for you to reorder parameters and give values for paramters which are normally default parameters without giving values for the default paramters before them, and those changes could not be dealt with by comments. However, I consider them to be a big _problem_, not a feature - _especially_ the ability to rearrange the function arguments. All of a sudden you could have foo(4, 5); foo(x : 4, y : 5); foo(y : 5, X : 4); all making _exactly_ the same function call. That seem _very_ bug-prone and confusing to me. foo(x : 4, y : 5) was bad enough, but allowing foo(y : 5, x : 4)? Not good. The amount of effort to understand the code becomes considerably higher. You could be very familiar with foo and know exactly what parameters it takes and totally mistake what it's really getting passed, because the arguments were flipped in comparison to the function parameters. I agree with Don. I think that named parameters would cause far more intellectual overhead and problems than they'd solve. - Jonathan M Davis - Jonathan M Davis
Feb 28 2011
parent "Nick Sabalausky" <a a.a> writes:
"Jonathan M Davis" <jmdavisProg gmx.com> wrote in message 
news:mailman.2068.1298929852.4748.digitalmars-d puremagic.com...
 On Monday, February 28, 2011 13:38:34 Don wrote:
 There are a couple of things that I really, really don't like about the
 names argument idea:
 1. It makes parameter names part of the API.
 Providing no way for the function writer to control whether it is part
 of the API or not, and especially, doing it retrospectively, strikes me
 as extremely rude.

 2. It introduces a different syntax for calling a function.
 foo(4, 5);
 foo(x: 4, y: 5);
 They look different, but they do exactly the same thing. I don't like
 that redundancy.


a + b b + a a - (-b) b.opBinary!"+"(a); alias a poop; alias b butt; poop + butt (SomeType w, SomeType f) { return w - (-f); } (a, b) And yet, rightfully, no one gives half a shit that those redundancies are possible. (Oh my god, we shouldn't have unary minus, operator overloading, alias, or anonymous functions, because look at the possible redundancies they can create!!!)
 Especially since, as far as I can tell, the named arguments are just
 comments (which the compiler can check).
 If so, a syntax like this would be possible, with no language change at
 all:

 pragma(namedarguments); // applies to whole module

 foo(/*x*/ 4, /*y*/ 5);


Semantically-meaningful comments? Ultra-yuck! Plus that would seriously fuck up my habit of temporarily commenting out old arguments.
 ---> if a function parameter has a comment which forms a valid
 identifier, it's a named parameter.

 But I still don't see the need for this feature. Aren't people using
 IDEs where the function signature (with parameter names) pops up when
 you're entering the function, and when you move the mouse over the
 function call?


Wasn't your first objection "It makes parameter names part of the API"? Sounds like the same thing to me.
 However, I consider them to
 be a big _problem_, not a feature - _especially_ the ability to rearrange 
 the
 function arguments. All of a sudden you could have

 foo(4, 5);
 foo(x : 4, y : 5);
 foo(y : 5, X : 4);

 all making _exactly_ the same function call. That seem _very_ bug-prone 
 and
 confusing to me. foo(x : 4, y : 5) was bad enough, but allowing foo(y : 5, 
 x :
 4)? Not good. The amount of effort to understand the code becomes 
 considerably
 higher. You could be very familiar with foo and know exactly what 
 parameters it
 takes and totally mistake what it's really getting passed, because the 
 arguments
 were flipped in comparison to the function parameters.

1. I don't want to try to remember the "obvious" ordering of top, bottom, left and right. (Note that despite how I just happened to order them there, CSS considers it natural to go top, right, bottom, left instead. And I can't disagree that that's a perfectly intuitive ordering, too). 2. You've merely given an example of misuse. Everything can be misused. So that's a not a valid argument against it anyway.
Feb 28 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 28 Feb 2011 16:38:34 -0500, Don <nospam nospam.com> wrote:

 spir wrote:
  Just don't use them!

You don't have that option. At least, if you're a library developer, you don't. (I'm a bit sick of people saying "you don't have to use it if you don't want to" in language design. If it is in the language, you don't have a choice. You will encounter it).

encounter *reading* it or encounter *using it*? You shouldn't ever have to use named parameters if you don't want to. Just like you can specify all defaulted parameters, or specify all template args when calling templated functions. I could live without named parameters (obviously!), but I certainly think reading a call with named parameters can be much easier with the parameter names than without, and I don't think you could ever say the opposite (that name-less parameters would be clearer).
 There are a couple of things that I really, really don't like about the  
 names argument idea:
 1. It makes parameter names part of the API.
 Providing no way for the function writer to control whether it is part  
 of the API or not, and especially, doing it retrospectively, strikes me  
 as extremely rude.

 2. It introduces a different syntax for calling a function.
 foo(4, 5);
 foo(x: 4, y: 5);
 They look different, but they do exactly the same thing. I don't like  
 that redundancy.

I look at it similarly to IFTI: foo(T)(T t) {...} foo(1); foo!int(1); both mean the same, the int is optional. Note that the library developer of foo has no way to restrict you from using either form. One is simply a clearer way of saying the other. In essense, the parameter names are ALREADY an essential part of the API. If we didn't name the parameters (entirely possible with .di files!), how shitty would programming be?
 Especially since, as far as I can tell, the named arguments are just  
 comments (which the compiler can check).
 If so, a syntax like this would be possible, with no language change at  
 all:

 pragma(namedarguments); // applies to whole module

 foo(/*x*/ 4, /*y*/ 5);

 ---> if a function parameter has a comment which forms a valid  
 identifier, it's a named parameter.

There is a feature that isn't available via comments, parameter reordering: foo(y: 5, x: 4); Who in their right mind wants to do this, right? Well, consider you use two different libraries, and in one library the y is always the first parameter, and in another the x is always the first parameter (yes, I've seen shit like this). Calls to the separate libs might be a nightmare of continuous documentation referencing. But if you can just always say "x is first", then the calls are easy to read and write, and completely unambiguous.
 But I still don't see the need for this feature. Aren't people using  
 IDEs where the function signature (with parameter names) pops up when  
 you're entering the function, and when you move the mouse over the  
 function call?

Dunno, vim doesn't do that for me currently. Also, if reviewing code on github, there is no ide. -Steve
Feb 28 2011
prev sibling next sibling parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
On 28/02/2011 07:03, Bekenn wrote:
     HRESULT hr = m_Device.Present(pSourceRect: null, pDestRect: null,
hDestWindowOverride: null, pDirtyRegion: null);

One advantage is that it would encourage self-documenting code, partly because the meaning is clearer at the caller side, and partly because library programmers would be encouraged more to make parameter names meaningful. It also means that you don't have to remember which order the parameters of a function go in. Though this is only useful if you can remember what the parameters are called. For example, string search functions vary - needle/haystack, str/substr, search/seek, for/in. (OK, so some of these I've thought up on the spot, and for/in wouldn't work (nice as it may be) as they're keywords, but you get the idea.) Trouble is it would create fragility, as parameter names would become a new thing that can't be changed once decided without breaking existing code. So it would be important to get them right from the beginning, and there'll be a time when the feature has just been introduced during which library programmers are in the process of changing parameter names to something meaningful. But one way around that would be to support parameter aliases, which would also confer a few more benefits. Stewart.
Feb 28 2011
next sibling parent reply Bekenn <leaveme alone.com> writes:
On 2/28/11 4:50 PM, Stewart Gordon wrote:
 But one way around that would be to support
 parameter aliases, which would also confer a few more benefits.

Interesting idea. I think this might solve Jonathan Davis's main complaint; could you give an example of what syntax for that might look like?
Feb 28 2011
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
On 01/03/2011 01:29, Bekenn wrote:
 On 2/28/11 4:50 PM, Stewart Gordon wrote:
 But one way around that would be to support
 parameter aliases, which would also confer a few more benefits.

Interesting idea. I think this might solve Jonathan Davis's main complaint; could you give an example of what syntax for that might look like?

I don't know, but possibly void setColour(int colour alias color); and with a possibility of deprecating old names int find(string haystack deprecated alias s1, string needle deprecated alias s2); Stewart.
Feb 28 2011
next sibling parent Bekenn <leaveme alone.com> writes:
On 2/28/11 5:53 PM, Stewart Gordon wrote:
 I don't know, but possibly

 void setColour(int colour alias color);

 and with a possibility of deprecating old names

 int find(string haystack deprecated alias s1, string needle deprecated
 alias s2);

I think that could work; I don't mind the verbosity, given that the actual need for a parameter name alias should be exceedingly rare.
Feb 28 2011
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 2/28/11 7:53 PM, Stewart Gordon wrote:
 On 01/03/2011 01:29, Bekenn wrote:
 On 2/28/11 4:50 PM, Stewart Gordon wrote:
 But one way around that would be to support
 parameter aliases, which would also confer a few more benefits.

Interesting idea. I think this might solve Jonathan Davis's main complaint; could you give an example of what syntax for that might look like?

I don't know, but possibly void setColour(int colour alias color); and with a possibility of deprecating old names int find(string haystack deprecated alias s1, string needle deprecated alias s2); Stewart.

Don't know about others, but I think this is exactly the point where my "meh" detector goes off. Andrei
Feb 28 2011
next sibling parent Bekenn <leaveme alone.com> writes:
On 2/28/2011 8:43 PM, Andrei Alexandrescu wrote:
 Don't know about others, but I think this is exactly the point where my
 "meh" detector goes off.

It *might* be worthwhile if it does indeed address Jonathan's concern about library writers not being able to change parameter names. I'm not sold that that's really such a big deal; I expect that parameter name aliases would be so rarely used as to disappear into obscurity. But I could be wrong.
Feb 28 2011
prev sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message 
news:ikhtn9$2ea1$1 digitalmars.com...
 On 2/28/11 7:53 PM, Stewart Gordon wrote:
 On 01/03/2011 01:29, Bekenn wrote:
 On 2/28/11 4:50 PM, Stewart Gordon wrote:
 But one way around that would be to support
 parameter aliases, which would also confer a few more benefits.

Interesting idea. I think this might solve Jonathan Davis's main complaint; could you give an example of what syntax for that might look like?

I don't know, but possibly void setColour(int colour alias color); and with a possibility of deprecating old names int find(string haystack deprecated alias s1, string needle deprecated alias s2); Stewart.

Don't know about others, but I think this is exactly the point where my "meh" detector goes off.

std.algorithm has far worse signatures. The main problem I have with the above is that it only solves a barely-existent "problem".
Feb 28 2011
next sibling parent Bekenn <leaveme alone.com> writes:
On 2/28/2011 9:24 PM, Nick Sabalausky wrote:
 std.algorithm has far worse signatures. The main problem I have with the
 above is that it only solves a barely-existent "problem".

Right, exactly. Thinking about it some more, I don't really think the changing parameter name issue really justifies parameter name aliases.
Feb 28 2011
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 2/28/11 11:24 PM, Nick Sabalausky wrote:
 "Andrei Alexandrescu"<SeeWebsiteForEmail erdani.org>  wrote in message
 news:ikhtn9$2ea1$1 digitalmars.com...
 On 2/28/11 7:53 PM, Stewart Gordon wrote:
 On 01/03/2011 01:29, Bekenn wrote:
 On 2/28/11 4:50 PM, Stewart Gordon wrote:
 But one way around that would be to support
 parameter aliases, which would also confer a few more benefits.

Interesting idea. I think this might solve Jonathan Davis's main complaint; could you give an example of what syntax for that might look like?

I don't know, but possibly void setColour(int colour alias color); and with a possibility of deprecating old names int find(string haystack deprecated alias s1, string needle deprecated alias s2); Stewart.

Don't know about others, but I think this is exactly the point where my "meh" detector goes off.

std.algorithm has far worse signatures. The main problem I have with the above is that it only solves a barely-existent "problem".

It's not the signature I was mehing about. Andrei
Feb 28 2011
prev sibling next sibling parent spir <denis.spir gmail.com> writes:
On 03/01/2011 01:50 AM, Stewart Gordon wrote:
 Trouble is it would create fragility, as parameter names would become a new
 thing that can't be changed once decided without breaking existing code.  So it
 would be important to get them right from the beginning, and there'll be a time
 when the feature has just been introduced during which library programmers are
 in the process of changing parameter names to something meaningful.  But one
 way around that would be to support parameter aliases, which would also confer
 a few more benefits.

That is a real concern, indeed, and the only rational point until now possibly interpretable against named parameters: once a lib is adopted, the feature freezes param names --just like type names, funcs names, member names, constant names, alias names and so on and so forth. On the other hand, this will hopefully prevent lib authors using meaningless/helpless names from the start on ;-) It may even help & promote de facto or discussed conventions on param names (ideally, one would be able to guess half of them from the /meaning/ of parameters) Denis -- _________________ vita es estrany spir.wikidot.com
Mar 01 2011
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 28 Feb 2011 19:50:44 -0500, Stewart Gordon <smjg_1998 yahoo.com>  
wrote:

 On 28/02/2011 07:03, Bekenn wrote:
     HRESULT hr = m_Device.Present(pSourceRect: null, pDestRect: null,  
 hDestWindowOverride: null, pDirtyRegion: null);

One advantage is that it would encourage self-documenting code, partly because the meaning is clearer at the caller side, and partly because library programmers would be encouraged more to make parameter names meaningful. It also means that you don't have to remember which order the parameters of a function go in. Though this is only useful if you can remember what the parameters are called. For example, string search functions vary - needle/haystack, str/substr, search/seek, for/in. (OK, so some of these I've thought up on the spot, and for/in wouldn't work (nice as it may be) as they're keywords, but you get the idea.) Trouble is it would create fragility, as parameter names would become a new thing that can't be changed once decided without breaking existing code. So it would be important to get them right from the beginning, and there'll be a time when the feature has just been introduced during which library programmers are in the process of changing parameter names to something meaningful. But one way around that would be to support parameter aliases, which would also confer a few more benefits.

This is probably the worse concern, because right now, phobos has been created without the intention that parameter names will be used at the call site. Despite all the concern, I believe phobos has been naming parameters just fine. If there are any poorly named parameters, they either a) aren't worth worrying about or b) should be renamed anyways (even if named parameter calling is not introduced). I think the alias idea is too much... -Steve
Mar 01 2011
prev sibling next sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
Russel Winder <russel russel.org.uk> wrote:

 The Python mechanism relies on the fact that despatch is by name and not
 by signature.  Languages that dispatch by signature will have
 significantly greater problems!

Hardly. Just like with default arguments, the compiler would add in the missing stuff and use the simple signature. The parameter names would not be part of the signature. -- Simen
Feb 28 2011
prev sibling next sibling parent "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
On Mon, 28 Feb 2011 13:50:52 -0800, Jonathan M Davis wrote:

 On Monday, February 28, 2011 13:38:34 Don wrote:
 spir wrote:
 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.


I agree. CreateFont() in the Windows API, I'm looking at you. (For Linux people, that function has about 12 parameters).
 ???
 
 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!

You don't have that option. At least, if you're a library developer, you don't. (I'm a bit sick of people saying "you don't have to use it if you don't want to" in language design. If it is in the language, you don't have a choice. You will encounter it). There are a couple of things that I really, really don't like about the names argument idea: 1. It makes parameter names part of the API. Providing no way for the function writer to control whether it is part of the API or not, and especially, doing it retrospectively, strikes me as extremely rude. 2. It introduces a different syntax for calling a function. foo(4, 5); foo(x: 4, y: 5); They look different, but they do exactly the same thing. I don't like that redundancy. Especially since, as far as I can tell, the named arguments are just comments (which the compiler can check). If so, a syntax like this would be possible, with no language change at all: pragma(namedarguments); // applies to whole module foo(/*x*/ 4, /*y*/ 5); ---> if a function parameter has a comment which forms a valid identifier, it's a named parameter. But I still don't see the need for this feature. Aren't people using IDEs where the function signature (with parameter names) pops up when you're entering the function, and when you move the mouse over the function call? And if you really want to see them all the time, why not build that feature into the IDE? ("hit ctrl-f9 to show all parameter names, hit it again to hide them").

I agree with pretty much everything said here. However, as I understand it, named parameters (at least as they work in Python) would allow for you to reorder parameters and give values for paramters which are normally default parameters without giving values for the default paramters before them, and those changes could not be dealt with by comments. [...]

I think I agree with you and Don here. As for "skipping" default parameters, I suggest the following syntax: void foo(int i, bool b = true, real r = 3.14, string s = "") { ... } foo(1, , , "Hello World!"); This is a much smaller language change than named parameters. -Lars
Mar 01 2011
prev sibling next sibling parent spir <denis.spir gmail.com> writes:
On 03/01/2011 01:03 AM, Jonathan M Davis wrote:
  From the perspective
 of the library user, it does provide some benefit, but I honestly do not think
 that

 func(x : 4, y : 5);

 is easier to read than

 func(4, 5);

 Sure, you have to know what func's parameters are, but you have to know that
 anyway. Only now, with named arguments, you have to care about what their
 _names_ are in addition to what they're for. I do _not_ want to have to read
 code which uses named arguments. It's just more clutter and more intellectual
 overhead.

Sorry no, you don't *have* to. Nothing forces you to use them. And again named params are a help for /reading/. You & Don argue on a wrong basis, as if (1) they were forced on writing (2) they were supposed to be a feature at writing time. Even you who don't want it would benefit from them at times: on the opposite of what you say above, named params /remove/ intellectual/memory load from programmers' minds/brains. [It's like a fight against pocket calculators or the use of an encyclopedia to write a University thesis. (People should compute by hand and know all facts by heart.)] Denis -- _________________ vita es estrany spir.wikidot.com
Mar 01 2011
prev sibling next sibling parent reply "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
On Tue, 01 Mar 2011 12:20:22 +0100, spir wrote:

 On 02/28/2011 11:13 PM, Steven Schveighoffer wrote:
 But I still don't see the need for this feature. Aren't people using
 IDEs where the function signature (with parameter names) pops up when
 you're entering the function, and when you move the mouse over the
 function call?


You are wrong Don, this is not an argument. The feature is *not* for writing code, but for reading it (first your own code). Obviously, if you can write parameter names, this means you know them somehow, lol! The names provide highly valuable info at /reading/ time.
 Dunno, vim doesn't do that for me currently.  Also, if reviewing code
 on github, there is no ide.

Geany does it, but only for currently open files. Meaning, to have it work when programming in D, I should have the whole stdlib open in geany tabs... Anyway, as said above, this feature is 'orthogonal' to the question discussed in this thread. I'm fed up with people opposing to features very relevant for code clarity, which they are not forced to use, and can hardly bother when reading code themselves. Is the second statement below really that hard to read? p = new Point([1,2,3], [3,2,1]); p = new Point(color:[1,2,3], pos:[3,2,1]);

Are the following really that hard to read? p = new Point(/* color */ [1,2,3], /* pos */ [3,2,1]); p = new Point( [1, 2, 3], // color [3, 2, 1], // pos ); -Lars
Mar 01 2011
parent "Nick Sabalausky" <a a.a> writes:
"Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> wrote in message 
news:ikimed$2vba$5 digitalmars.com...
 On Tue, 01 Mar 2011 12:20:22 +0100, spir wrote:

 On 02/28/2011 11:13 PM, Steven Schveighoffer wrote:
 But I still don't see the need for this feature. Aren't people using
 IDEs where the function signature (with parameter names) pops up when
 you're entering the function, and when you move the mouse over the
 function call?


You are wrong Don, this is not an argument. The feature is *not* for writing code, but for reading it (first your own code). Obviously, if you can write parameter names, this means you know them somehow, lol! The names provide highly valuable info at /reading/ time.
 Dunno, vim doesn't do that for me currently.  Also, if reviewing code
 on github, there is no ide.

Geany does it, but only for currently open files. Meaning, to have it work when programming in D, I should have the whole stdlib open in geany tabs... Anyway, as said above, this feature is 'orthogonal' to the question discussed in this thread. I'm fed up with people opposing to features very relevant for code clarity, which they are not forced to use, and can hardly bother when reading code themselves. Is the second statement below really that hard to read? p = new Point([1,2,3], [3,2,1]); p = new Point(color:[1,2,3], pos:[3,2,1]);

Are the following really that hard to read? p = new Point(/* color */ [1,2,3], /* pos */ [3,2,1]); p = new Point( [1, 2, 3], // color [3, 2, 1], // pos ); -Lars

class Point { this(int[3] pos, int[3] color) {...} } p = new Point(/* color */ [1,2,3], /* pos */ [3,2,1]); Big Fail.
Mar 01 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 01 Mar 2011 04:10:12 -0500, Don <nospam nospam.com> wrote:

 Steven Schveighoffer wrote:
 On Mon, 28 Feb 2011 16:38:34 -0500, Don <nospam nospam.com> wrote:

 spir wrote:
  Just don't use them!

You don't have that option. At least, if you're a library developer, you don't. (I'm a bit sick of people saying "you don't have to use it if you don't want to" in language design. If it is in the language, you don't have a choice. You will encounter it).

have to use named parameters if you don't want to. Just like you can specify all defaulted parameters, or specify all template args when calling templated functions. I could live without named parameters (obviously!), but I certainly think reading a call with named parameters can be much easier with the parameter names than without, and I don't think you could ever say the opposite (that name-less parameters would be clearer).

For sure they can be clearer with nameless parameters! printf(formatstr: "Hello World!\n");

This is not less clear than printf("Hello World!\n"); It's as clear. More verbose, yes, but clear. Just like foo!int(1) is as clear as, but more verbose than, foo(1).
 In essense, the parameter names are ALREADY an essential part of the  
 API.  If we didn't name the parameters (entirely possible with .di  
 files!), how shitty would programming be?

The names are for humans to read. They are documentation. That's a big difference.

And they continue to be documentation, I'm documenting what my argument names are at the call site so I don't have to go back to the function definition to determine what each parameter is via position. Regarding your objection in another post, I see your point that you don't want to break existing code by changing a parameter name. A way to look at this is, you must choose good parameter names on the first try. Another way to look at it is, I'm documenting my function call -- I want to be notified by the compiler when the parameter names changed because I want to reassure myself that the call is still valid. My point is, the function author should choose good names, but if he must make a change, then fear of breaking calls should not dissuade him. We routinely change the names of functions or deprecate them, this is taken in stride by the users of the library, I don't see how changing parameter names is any different. -Steve
Mar 01 2011
prev sibling next sibling parent spir <denis.spir gmail.com> writes:
On 03/01/2011 05:52 AM, Bekenn wrote:
 On 2/28/2011 8:43 PM, Andrei Alexandrescu wrote:
 Don't know about others, but I think this is exactly the point where my
 "meh" detector goes off.

It *might* be worthwhile if it does indeed address Jonathan's concern about library writers not being able to change parameter names. I'm not sold that that's really such a big deal; I expect that parameter name aliases would be so rarely used as to disappear into obscurity. But I could be wrong.

Should we also have some mechanism to help lib writers and change type names, func names, member names...? Denis -- _________________ vita es estrany spir.wikidot.com
Mar 01 2011
prev sibling next sibling parent "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
On Tue, 01 Mar 2011 07:26:28 -0500, Nick Sabalausky wrote:

 "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> wrote in message
 news:ikimed$2vba$5 digitalmars.com...
 On Tue, 01 Mar 2011 12:20:22 +0100, spir wrote:

 On 02/28/2011 11:13 PM, Steven Schveighoffer wrote:
 But I still don't see the need for this feature. Aren't people using
 IDEs where the function signature (with parameter names) pops up
 when you're entering the function, and when you move the mouse over
 the function call?


You are wrong Don, this is not an argument. The feature is *not* for writing code, but for reading it (first your own code). Obviously, if you can write parameter names, this means you know them somehow, lol! The names provide highly valuable info at /reading/ time.
 Dunno, vim doesn't do that for me currently.  Also, if reviewing code
 on github, there is no ide.

Geany does it, but only for currently open files. Meaning, to have it work when programming in D, I should have the whole stdlib open in geany tabs... Anyway, as said above, this feature is 'orthogonal' to the question discussed in this thread. I'm fed up with people opposing to features very relevant for code clarity, which they are not forced to use, and can hardly bother when reading code themselves. Is the second statement below really that hard to read? p = new Point([1,2,3], [3,2,1]); p = new Point(color:[1,2,3], pos:[3,2,1]);

Are the following really that hard to read? p = new Point(/* color */ [1,2,3], /* pos */ [3,2,1]); p = new Point( [1, 2, 3], // color [3, 2, 1], // pos ); -Lars

class Point { this(int[3] pos, int[3] color) {...} } p = new Point(/* color */ [1,2,3], /* pos */ [3,2,1]); Big Fail.

Yeah, I'm aware of that. I was merely opposing the "code clarity" argument by saying that we already have a feature for clarifying code: comments. Note that I'm not against named parameters per se, and I understand their benefits. I just think that, at this late point in D2's development, the cost of adding them outweighs the benefits. I mean, have you looked at the spec for D2 lately? It's starting to look like the OOXML spec! -Lars
Mar 01 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 2/28/11, Steven Schveighoffer <schveiguy yahoo.com> wrote:
 Dunno, vim doesn't do that for me currently.

 -Steve

For C/C++, there's OmniCppComplete. It seems to do some parsing work and uses ctags. Now, I can use ctags and cscope in Vim with D, no problem there. But I haven't gotten around on getting autocompletion for D working. It might be possible to use the OmniCppComplete codebase and do a few edits here and there to make it work for D.
Mar 01 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 3/1/11, Bekenn <leaveme alone.com> wrote:
 When reading existing code, can you easily spot the difference between:
 	foo(1,,, "Hello World!");
 and
 	foo(1,,,, "Hello World!");
 ?

 Unlike named arguments, I'd argue this syntax makes things quite a bit
 /less/ readable.

This syntax is used by Autohotkey, an automation scripting language. It's not that bad for scripting (when you have an api reference on the side). But when you're reading code you have to keep count of those commas, and that's when things get ugly.
Mar 01 2011
prev sibling next sibling parent spir <denis.spir gmail.com> writes:
On 03/02/2011 02:59 PM, Steven Schveighoffer wrote:
 On Wed, 02 Mar 2011 08:45:43 -0500, Jason E. Aten <j.e.aten gmail.com> wrote:

 I find this an interesting discussion. Coming from writing alot of code in
 language that makes extensive and
 highly effective use of named arguments (R), I can say that optional named
 arguments
 (as in Lisp, and descendants like Python and R) do have big software
 engineering benefits,
 but also come with a substantial costs in terms of complexity of the
 function call sequence.

 That is, named arguments can be expensive in a typical interpreted
 implementation
 (probably one reason why R and Python are much slower to execute than the
 other
 interpreted languages), presumably because each function call has to
 invoke hash
 table lookups to determine the canonical formal position of each actual
 argument, and deal with variadic
 cases, to rearrange the order of the arguments to match expectations of the
 callee.

 Someone familiar with lisp compilers could probably tell you if the heavy
 speed tax is intrinsic
 or just the price of interpretation.

 It would indeed be an interesting challenge to see if the compile-time
 metaprogramming
 features of D would allow one to include named arguments in an opt-in
 fashion without speed reduction.

Considering that calling a function with parameters by name directly translates at compile time to a function call by position, there should be zero speed impact. The interpretation of the parameter names, which is done at runtime for Python, would be done at compile time in D. -Steve

I had never thought at that, but I'm surprised: what prevents Python's "compiler" (say, a semantic phase after parsing) to check number and names of arguments. (Number seems not to be checked before runtime neither.) All required information is in the AST. For named params, Python could translate to position params just like D. This would certainly remove a relevant amount of runtime "speed-down", I guess. (Only type-check of builtin func args must remain at runtime.) Denis -- _________________ vita es estrany spir.wikidot.com
Mar 02 2011
prev sibling next sibling parent reply "Joel C. Salomon" <joelcsalomon gmail.com> writes:
(De-lurking; I've been interested in D for a while, but my programming
is almost exclusively in C -- generally C99.)

Does D have the equivalent of C99's "designated initializers"?

Were I to attempt something like this in C, the code would go something
like this:

    int foo(int height, int width);
    struct _foo_args {
        int height; int width;
    };
    #define foo(...) \
        foo((struct _foo_args){__VA_ARGS__}.height, \
            (struct _foo_args){__VA_ARGS__}.width)

at which point each of these calls:

    foo(a, b);
    foo(.height = a, .width = b);
    foo(.width = b, .height = a);

have the same effect.

I'll readily admit this is *not* pretty, and likely more effort than
it's worth, but is will work.

Are D's compile-time operations not capable of something at *least* this
powerful?

--Joel
Mar 06 2011
next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Sunday 06 March 2011 16:57:17 Joel C. Salomon wrote:
 (De-lurking; I've been interested in D for a while, but my programming
 is almost exclusively in C -- generally C99.)
 
 Does D have the equivalent of C99's "designated initializers"?
 
 Were I to attempt something like this in C, the code would go something
 like this:
 
     int foo(int height, int width);
     struct _foo_args {
         int height; int width;
     };
     #define foo(...) \
         foo((struct _foo_args){__VA_ARGS__}.height, \
             (struct _foo_args){__VA_ARGS__}.width)
 
 at which point each of these calls:
 
     foo(a, b);
     foo(.height = a, .width = b);
     foo(.width = b, .height = a);
 
 have the same effect.
 
 I'll readily admit this is *not* pretty, and likely more effort than
 it's worth, but is will work.
 
 Are D's compile-time operations not capable of something at *least* this
 powerful?

D doesn't have macros. It has incredibly powerful templates as well as string mixins, but no macros. So, what D has tends to be very powerful, but there are times when it's more verbose to use than a C macro might be, and there are some things that you can do with C macros that you can't readily do in D (though there are a lot of things that yo ucan do with D templates that you could never do with C macros or even C++ templates - or if you can, it's a _lot_ harder in C++). It's a lot safer and less error-prone that way though. In this case, you could do something like this: int width; int height; func(width = 2, height = 7); That _is_ a bit wasteful though in that it's assigning to local variables which are likely never used after that. Regardless, I don't think that you can do something quite like what you're trying to do. If nothing else, I don't think that D has anything like C99's designated initializers. It has constructors. - Jonathan M Davis
Mar 06 2011
prev sibling parent bearophile <bearophileHUGS lycos.com> writes:
Joel C. Salomon:

 Does D have the equivalent of C99's "designated initializers"?

D2 currently allows code like this (but I don't know if this will be deprecated, for me sometimes is not easy to remember all things that will be deprecated): struct Foo { int x, y, z; } Foo f1 = { x:1, y:2 }; Foo f2 = { x:1, z:2 }; void main() {} Bye, bearophile
Mar 06 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 08 Mar 2011 15:29:28 -0500, Bruno Medeiros  
<brunodomedeiros+spam com.gmail> wrote:

 On 28/02/2011 22:13, Steven Schveighoffer wrote:


 Dunno, vim doesn't do that for me currently.

I feel tempted to say something very short and concise regarding vim and emacs, but it would require a large amount of justification to properly expose such point. I am planning to write a blog post about that, but I haven't gotten to it yet. > Also, if reviewing code on github, there is no ide. > > -Steve A) Should we give any significant weight to very minute and relatively infrequent code reading situations, like web-based code reviewing in github or whatever, or reading code in books? I doubt so.

I contest that web based code reviewing is going to be infrequent, since all major phobos changes now must be reviewed by 2 peers before inclusion. Please look at a recent pull request review I participated in, without ever opening an editor/ide. GitHub provides very good collaborative review. If I have to install an IDE that I only use for reviewing, um... no. https://github.com/jmdavis/phobos/commit/aca1a2d7cfe7d5e934668e06028b78ffb6796245
 B) If the pull request is large, it should be near effortless to put  
 those changes in the IDE and review them there.

Again, don't have one. -Steve
Mar 08 2011
prev sibling next sibling parent Emil Madsen <sovende gmail.com> writes:
--00235451e6683dc8ba049e0ea911
Content-Type: text/plain; charset=ISO-8859-1

On 9 March 2011 13:22, Gareth Charnock <gareth.charnock gmail.com> wrote:

 Named arguments are useful when you have a function that takes a large
 number of parameters, the vast majority of which have default values. For
 example, have a look at this constructor in wxWidgets:


 http://docs.wxwidgets.org/trunk/classwx_frame.html#01b53ac2d4a5e6b0773ecbcf7b5f6af8

 wxFrame::wxFrame        (       wxWindow *      parent,
 wxWindowID      id,
 const wxString &        title,
 const wxPoint &         pos = wxDefaultPosition,
 const wxSize &  size = wxDefaultSize,
 long    style = wxDEFAULT_FRAME_STYLE,
 const wxString &        name = wxFrameNameStr
 )

 If you want to change the name argument you need to call

 new wxFrame(a_parent,wxANY,"Hello
 world",wxDefaultPosition,wxDefaultSize,wxDEFAULT_FRAME_STYLE,"My Custom name
 str")

 Which meant I had to look up what the default values of pos,size and style
 where even though I was happy with those default values. The more arguments
 the more of a pain this setup is without named arguments. Contrast to a
 hypothetical C++ syntax:

 new wxFrame(a_parent,wxANY,"Hello world",name = "My Custom name str")

 I haven't bothered with the arguments I don't care about and my function
 call has ended up less sensitive to changes in the wxFrame constructor.


 On 28/02/11 21:50, Jonathan M Davis wrote:

 On Monday, February 28, 2011 13:38:34 Don wrote:

 spir wrote:

 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.


CreateFont() in the Windows API, I'm looking at you. (For Linux people, that function has about 12 parameters). ???
  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!

You don't have that option. At least, if you're a library developer, you don't. (I'm a bit sick of people saying "you don't have to use it if you don't want to" in language design. If it is in the language, you don't have a choice. You will encounter it). There are a couple of things that I really, really don't like about the names argument idea: 1. It makes parameter names part of the API. Providing no way for the function writer to control whether it is part of the API or not, and especially, doing it retrospectively, strikes me as extremely rude. 2. It introduces a different syntax for calling a function. foo(4, 5); foo(x: 4, y: 5); They look different, but they do exactly the same thing. I don't like that redundancy. Especially since, as far as I can tell, the named arguments are just comments (which the compiler can check). If so, a syntax like this would be possible, with no language change at all: pragma(namedarguments); // applies to whole module foo(/*x*/ 4, /*y*/ 5); ---> if a function parameter has a comment which forms a valid identifier, it's a named parameter. But I still don't see the need for this feature. Aren't people using IDEs where the function signature (with parameter names) pops up when you're entering the function, and when you move the mouse over the function call? And if you really want to see them all the time, why not build that feature into the IDE? ("hit ctrl-f9 to show all parameter names, hit it again to hide them").

I agree with pretty much everything said here. However, as I understand it, named parameters (at least as they work in Python) would allow for you to reorder parameters and give values for paramters which are normally default parameters without giving values for the default paramters before them, and those changes could not be dealt with by comments. However, I consider them to be a big _problem_, not a feature - _especially_ the ability to rearrange the function arguments. All of a sudden you could have foo(4, 5); foo(x : 4, y : 5); foo(y : 5, X : 4); all making _exactly_ the same function call. That seem _very_ bug-prone and confusing to me. foo(x : 4, y : 5) was bad enough, but allowing foo(y : 5, x : 4)? Not good. The amount of effort to understand the code becomes considerably higher. You could be very familiar with foo and know exactly what parameters it takes and totally mistake what it's really getting passed, because the arguments were flipped in comparison to the function parameters. I agree with Don. I think that named parameters would cause far more intellectual overhead and problems than they'd solve. - Jonathan M Davis - Jonathan M Davis


a lot of parameters, mostly because if the libary dev, chooses to change the default value of something, my old placeholder value, will end up being wrong without me knowing anything about it. Say: wxFrame::wxFrame ( wxWindow * parent, wxWindowID id, const wxString & title, const wxPoint & pos = wxDefaultPosition, const wxSize & size = wxDefaultSize, long style = wxDEFAULT_FRAME_STYLE, const wxString & name = wxFrameNameStr ) And I call it with the default args, because I have to, to change the name; however then the libary dev decides it would be better to have a default value of size = 800x600, now I'm not getting the default as I wanted to. -- // Yours sincerely // Emil 'Skeen' Madsen --00235451e6683dc8ba049e0ea911 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <div>On 9 March 2011 13:22, Gareth Charnock <span dir=3D"ltr">&lt;<a href= =3D"mailto:gareth.charnock gmail.com">gareth.charnock gmail.com</a>&gt;</sp= an> wrote:</div><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote= " style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"> Named arguments are useful when you have a function that takes a large numb= er of parameters, the vast majority of which have default values. For examp= le, have a look at this constructor in wxWidgets:<br> <br> <a href=3D"http://docs.wxwidgets.org/trunk/classwx_frame.html#01b53ac2d4a5e= 6b0773ecbcf7b5f6af8" target=3D"_blank">http://docs.wxwidgets.org/trunk/clas= swx_frame.html#01b53ac2d4a5e6b0773ecbcf7b5f6af8</a><br> <br> wxFrame::wxFrame =A0 =A0 =A0 =A0( =A0 =A0 =A0 wxWindow * =A0 =A0 =A0parent,= <br> wxWindowID =A0 =A0 =A0id,<br> const wxString &amp; =A0 =A0 =A0 =A0title,<br> const wxPoint &amp; =A0 =A0 =A0 =A0 pos =3D wxDefaultPosition,<br> const wxSize &amp; =A0size =3D wxDefaultSize,<br> long =A0 =A0style =3D wxDEFAULT_FRAME_STYLE,<br> const wxString &amp; =A0 =A0 =A0 =A0name =3D wxFrameNameStr =A0 <br> )<br> <br> If you want to change the name argument you need to call<br> <br> new wxFrame(a_parent,wxANY,&quot;Hello world&quot;,wxDefaultPosition,wxDefa= ultSize,wxDEFAULT_FRAME_STYLE,&quot;My Custom name str&quot;)<br> <br> Which meant I had to look up what the default values of pos,size and style = where even though I was happy with those default values. The more arguments= the more of a pain this setup is without named arguments. Contrast to a hy= pothetical C++ syntax:<br> <br> new wxFrame(a_parent,wxANY,&quot;Hello world&quot;,name =3D &quot;My Custom= name str&quot;)<br> <br> I haven&#39;t bothered with the arguments I don&#39;t care about and my fun= ction call has ended up less sensitive to changes in the wxFrame constructo= r.<div class=3D"im"><br> <br> On 28/02/11 21:50, Jonathan M Davis wrote:<br> </div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-l= eft:1px #ccc solid;padding-left:1ex"><div class=3D"im"> On Monday, February 28, 2011 13:38:34 Don wrote:<br> </div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-l= eft:1px #ccc solid;padding-left:1ex"><div class=3D"im"> spir wrote:<br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> On 02/28/2011 07:51 PM, Jonathan M Davis wrote:<br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> I&#39;m not entirely against named arguments being in D, however I do<br> think that any<br> functions that actually need them should be refactored anyway.<br> </blockquote></blockquote> <br> I agree.<br> CreateFont() in the Windows API, I&#39;m looking at you. (For Linux people,= <br> that function has about 12 parameters).<br> <br> </div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-l= eft:1px #ccc solid;padding-left:1ex"><div class=3D"im"> ???<br> <br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> In actuality, if I were to vote on whether named arguments should be<br> in the<br> language, I would definitely vote against it (I just plain don&#39;t want<b= r> the code<br> clutter, =A0[...]<br> </blockquote> <br></div><div class=3D"im"> Just don&#39;t use them!<br> </div></blockquote><div class=3D"im"> <br> You don&#39;t have that option. At least, if you&#39;re a library developer= , you<br> don&#39;t. (I&#39;m a bit sick of people saying &quot;you don&#39;t have to= use it if you<br> don&#39;t want to&quot; in language design. If it is in the language, you d= on&#39;t<br> have a choice. You will encounter it).<br> <br></div><div class=3D"im"> There are a couple of things that I really, really don&#39;t like about the= <br> names argument idea:<br></div><div class=3D"im"> 1. It makes parameter names part of the API.<br></div><div class=3D"im"> Providing no way for the function writer to control whether it is part<br> of the API or not, and especially, doing it retrospectively, strikes me<br> as extremely rude.<br> <br> 2. It introduces a different syntax for calling a function.<br> foo(4, 5);<br> foo(x: 4, y: 5);<br> They look different, but they do exactly the same thing. I don&#39;t like<b= r> that redundancy.<br> <br> <br> Especially since, as far as I can tell, the named arguments are just<br> comments (which the compiler can check).<br> If so, a syntax like this would be possible, with no language change at<br> all:<br> <br> pragma(namedarguments); // applies to whole module<br> <br> foo(/*x*/ 4, /*y*/ 5);<br> <br> ---&gt; =A0if a function parameter has a comment which forms a valid<br> identifier, it&#39;s a named parameter.<br> <br></div><div class=3D"im"> But I still don&#39;t see the need for this feature. Aren&#39;t people usin= g<br> IDEs where the function signature (with parameter names) pops up when<br> you&#39;re entering the function, and when you move the mouse over the<br> function call?<br></div><div class=3D"im"> And if you really want to see them all the time, why not build that<br> feature into the IDE?<br> (&quot;hit ctrl-f9 to show all parameter names, hit it again to hide them&q= uot;).<br> </div></blockquote> <br><div class=3D"im"> I agree with pretty much everything said here. However, as I understand it,= <br> named parameters (at least as they work in Python) would allow for you to<b= r> reorder parameters and give values for paramters which are normally default= <br> parameters without giving values for the default paramters before them, and= <br></div> those changes could not be dealt with by comments. However, I consider them= to<br> be a big _problem_, not a feature - _especially_ the ability to rearrange t= he<br> function arguments. All of a sudden you could have<div class=3D"im"><br> <br> foo(4, 5);<br> foo(x : 4, y : 5);<br></div> foo(y : 5, X : 4);<br> <br> all making _exactly_ the same function call. That seem _very_ bug-prone and= <br> confusing to me. foo(x : 4, y : 5) was bad enough, but allowing foo(y : 5, = x :<br> 4)? Not good. The amount of effort to understand the code becomes considera= bly<br> higher. You could be very familiar with foo and know exactly what parameter= s it<br> takes and totally mistake what it&#39;s really getting passed, because the = arguments<br> were flipped in comparison to the function parameters.<br> <br> I agree with Don. I think that named parameters would cause far more<br> intellectual overhead and problems than they&#39;d solve.<br> <br> - Jonathan M Davis<br> <br> - Jonathan M Davis<br> </blockquote> <br> </blockquote></div><br>I actually like the idea of named variables, for the= se funktions that takes a lot of parameters, mostly because if the libary d= ev, chooses to change the default value of something, my old placeholder va= lue, will end up being wrong without me knowing anything about it.<div> <br></div><div>Say:</div><div>wxFrame::wxFrame =A0 =A0 =A0 =A0( =A0 =A0 =A0= wxWindow * =A0 =A0 =A0parent,<br>wxWindowID =A0 =A0 =A0id,<br>const wxStri= ng &amp; =A0 =A0 =A0 =A0title,<br>const wxPoint &amp; =A0 =A0 =A0 =A0 pos = =3D wxDefaultPosition,<br>const wxSize &amp; =A0size =3D wxDefaultSize,<br> long =A0 =A0style =3D wxDEFAULT_FRAME_STYLE,<br>const wxString &amp; =A0 = =A0 =A0 =A0name =3D wxFrameNameStr =A0=A0<br>)<br></div><div><br></div><div=
And I call it with the default args, because I have to, to change the name=

value of size =3D 800x600, now I&#39;m not getting the default as I wanted = to.</div> <div><br><div><br>-- <br>// Yours sincerely<br>// Emil &#39;Skeen&#39; Mads= en<br> </div></div> --00235451e6683dc8ba049e0ea911--
Mar 09 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 09 Mar 2011 09:02:14 -0500, Bruno Medeiros  
<brunodomedeiros+spam com.gmail> wrote:

 Although in the particular cased of named arguments, I still don't feel  
 it is worthwhile. Not unless it could be done in a very orthogonal way  
 (both in semantics and syntax), and even so it should likely be very low  
 priority (as in, not any time soon...).

It's one of those things where, in some cases, not having named arguments makes code unreadable. But having named arguments does not make *all* code more readable. In many many cases, code is readable just fine without using the named arguments. But those cases where it does help, it's essential. Like Don's CreateFont example (actually almost any GUI function). We might do something like require explicit comments for confusing functions like: foo( null, // paramA null, // paramB null, // paramC ); during the review process. It would at least document properly what is happening. I see not too much value in the "skip default parameter" prospect, most code can do fine without that via overloading. But the documentation and compiler verification of parameter names is what I see as the killer feature here.
 B) If the pull request is large, it should be near effortless to put
 those changes in the IDE and review them there.

Again, don't have one. -Steve

Just because you don't have or don't use an IDE, that is not an argument against doing B).

It absolutely is. I use NetBeans for doing php development. It took me hours and hours to set it up properly, install the right add-ons, etc. I'm not about to do that for something like descent or DDT so I can properly read code, I'm way more likely to just go look up the function signature myself for the few times I need it. Just having the named arguments idea makes so much more sense than having to load a specialized (and I might add, way overkill for just reviewing code in both size and complexity) tool. It's not one of those "absolutely have to have it" features, it's a nice-to-have. I certainly can and have lived without it, and there are certainly ways to compensate for not having it. It's kind of like arrays in D. Every time I have to use another language, I miss D's array syntax features. All the same functionality is there, it just takes more effort to do the same thing. That little effort is not terrible, but I much prefer not having to do it. -Steve
Mar 09 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 24 Mar 2011 10:33:28 -0400, Bruno Medeiros  
<brunodomedeiros+spam com.gmail> wrote:

 Well, now we go back to discussion of the discussion of whether one  
 thinks it's worthwhile to use and IDE or not (for general development,  
 not just code reviews).
 I don't want to go into this discussion again, at least not now so soon.  
 I think that what we all may take from the discussion I was having from  
 Steven right now, and maybe everyone agree with, is that whether it's  
 worthwhile to use an IDE for code reviews is reduced to the discussion  
 of whether it's worthwhile to use an IDE generally or not. In other  
 words, if you don't do the tasks I mentioned before (looking up  
 documentation, compiling and running code, running tests. also, using  
 the source control system) from inside the IDE when developing yourself,  
 you will definitely won't want to use it when code reviewing, accepting  
 patches, etc..

Building on that, I'll actually put it another way: Without netbeans, I would be twice as slow with php development. Being a non-static language, with so many little quirks and annoyances that come with, I find netbeans' features essential (my most favorite is the recent ability to "type" object variables so you can look at the documented members). In fact, I'd be way more likely to install a D for netbeans plugin than I would to install another IDE specifically for D. But with D, I find the online documentation and included tools "good enough" for most development. I'm also way more familiar with D's library than I am with php's. I don't know if it's a good apples-to-apples comparison, but I simply feel no need to have an IDE to read D code. I don't feel the same way about php :) Having named arguments would add to that feeling of comfort, I believe. -Steve P.S. I've tried two D ides in the past for about 10 minutes (descent and code::blocks), could not get either of them to work right. And it was *not* trivial to set them up.
Mar 24 2011
prev sibling next sibling parent Andrew Wiley <debio264 gmail.com> writes:
On Thu, Mar 24, 2011 at 3:23 PM, Steven Schveighoffer
<schveiguy yahoo.com> wrote:
 On Thu, 24 Mar 2011 10:33:28 -0400, Bruno Medeiros
 <brunodomedeiros+spam com.gmail> wrote:

 Well, now we go back to discussion of the discussion of whether one thin=


 it's worthwhile to use and IDE or not (for general development, not just
 code reviews).
 I don't want to go into this discussion again, at least not now so soon.=


 think that what we all may take from the discussion I was having from St=


 right now, and maybe everyone agree with, is that whether it's worthwhil=


 use an IDE for code reviews is reduced to the discussion of whether it's
 worthwhile to use an IDE generally or not. In other words, if you don't =


 the tasks I mentioned before (looking up documentation, compiling and
 running code, running tests. also, using the source control system) from
 inside the IDE when developing yourself, you will definitely won't want =


 use it when code reviewing, accepting patches, etc..

Building on that, I'll actually put it another way: Without netbeans, I would be twice as slow with php development. =A0Being=

 non-static language, with so many little quirks and annoyances that come
 with, I find netbeans' features essential (my most favorite is the recent
 ability to "type" object variables so you can look at the documented
 members). =A0In fact, I'd be way more likely to install a D for netbeans
 plugin than I would to install another IDE specifically for D.

 But with D, I find the online documentation and included tools "good enou=

 for most development. =A0I'm also way more familiar with D's library than=

 with php's.

 I don't know if it's a good apples-to-apples comparison, but I simply fee=

 no need to have an IDE to read D code. =A0I don't feel the same way about=

 :) =A0Having named arguments would add to that feeling of comfort, I beli=

 -Steve

 P.S. I've tried two D ides in the past for about 10 minutes (descent and
 code::blocks), could not get either of them to work right. =A0And it was =

 trivial to set them up.

I would make the argument that once you started working with a D IDE with enough features, you'd probably find yourself addicted to it as you are with PHP and Netbeans. At least, that's been my experience across just about every language I've coded in.
Mar 24 2011
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 24 Mar 2011 23:39:30 -0400, Andrew Wiley <debio264 gmail.com>  
wrote:

 I would make the argument that once you started working with a D IDE
 with enough features, you'd probably find yourself addicted to it as
 you are with PHP and Netbeans. At least, that's been my experience
 across just about every language I've coded in.

/me likes my vi :) I know ides can mimic vi, or use vi directly to edit, but for most purposes, vi + online docs suits my style well. I don't dislike IDEs per se, I've used Visual Studio quite a bit and I like it, though it's not supported on my current OS (Linux). I also think NetBeans is pretty good, it certainly makes php coding more enjoyable. But I will never, ever install an IDE for the sole purpose of reviewing code. And I don't see the problem with making code more understandable without an IDE. The point that named parameters a "useless" feature because IDEs already take care of that is what I disagree with, not that IDEs are useful. -Steve
Mar 25 2011