Jump to page: 1 217  
Page
Thread overview
Pretty please: Named arguments
Feb 28, 2011
Bekenn
Feb 28, 2011
Russel Winder
Feb 28, 2011
Bekenn
Feb 28, 2011
Jonathan M Davis
Feb 28, 2011
Vladimir Panteleev
Feb 28, 2011
Bekenn
Feb 28, 2011
Bekenn
Feb 28, 2011
Jim
Mar 01, 2011
spir
Mar 02, 2011
Stewart Gordon
Feb 28, 2011
bearophile
Feb 28, 2011
Russel Winder
Mar 01, 2011
Simen kjaeraas
Feb 28, 2011
spir
Feb 28, 2011
spir
Feb 28, 2011
Michel Fortin
Feb 28, 2011
bearophile
Feb 28, 2011
Bekenn
Feb 28, 2011
spir
Feb 28, 2011
Bekenn
Feb 28, 2011
spir
Feb 28, 2011
Bekenn
Feb 28, 2011
Andrej Mitrovic
Feb 28, 2011
Andrej Mitrovic
Feb 28, 2011
Andrej Mitrovic
Feb 28, 2011
Andrej Mitrovic
Feb 28, 2011
spir
Feb 28, 2011
Michel Fortin
Feb 28, 2011
Michel Fortin
Feb 28, 2011
spir
Feb 28, 2011
spir
Feb 28, 2011
bearophile
Feb 28, 2011
spir
Feb 28, 2011
Simen kjaeraas
Feb 28, 2011
Bekenn
Feb 28, 2011
Simen kjaeraas
Feb 28, 2011
Andrej Mitrovic
Feb 28, 2011
spir
Mar 01, 2011
Jacob Carlborg
Feb 28, 2011
Andrej Mitrovic
Feb 28, 2011
Bekenn
Feb 28, 2011
Andrej Mitrovic
Feb 28, 2011
Jacob Carlborg
Feb 28, 2011
Bekenn
Mar 01, 2011
Nick Sabalausky
Feb 28, 2011
Jonathan M Davis
Feb 28, 2011
Jonathan M Davis
Feb 28, 2011
Jonathan M Davis
Feb 28, 2011
Tomek Sowiński
Feb 28, 2011
Andrej Mitrovic
Feb 28, 2011
Adam Ruppe
Feb 28, 2011
Andrej Mitrovic
Feb 28, 2011
Adam Ruppe
Mar 01, 2011
Jacob Carlborg
Feb 28, 2011
Andrej Mitrovic
Feb 28, 2011
bearophile
Feb 28, 2011
Andrej Mitrovic
Feb 28, 2011
Simen kjaeraas
Feb 28, 2011
KennyTM~
Feb 28, 2011
Adam Ruppe
Feb 28, 2011
spir
Feb 28, 2011
bearophile
Feb 28, 2011
bearophile
Feb 28, 2011
Bekenn
Feb 28, 2011
spir
Feb 28, 2011
Don
Feb 28, 2011
Jonathan M Davis
Feb 28, 2011
bearophile
Feb 28, 2011
Bekenn
Mar 01, 2011
Nick Sabalausky
Mar 01, 2011
Bekenn
Mar 01, 2011
Andrej Mitrovic
Mar 09, 2011
Gareth Charnock
Mar 09, 2011
Emil Madsen
Mar 11, 2011
Stewart Gordon
Feb 28, 2011
bearophile
Mar 01, 2011
Don
Mar 08, 2011
Bruno Medeiros
Mar 01, 2011
Don
Mar 01, 2011
spir
Mar 01, 2011
spir
Mar 01, 2011
Nick Sabalausky
Mar 01, 2011
Bekenn
Mar 01, 2011
Max Samukha
Mar 01, 2011
Dmitry Olshansky
Mar 01, 2011
Bekenn
Mar 02, 2011
Max Samukha
Mar 02, 2011
Bekenn
Mar 01, 2011
Andrej Mitrovic
Mar 08, 2011
Bruno Medeiros
Mar 08, 2011
bearophile
Mar 09, 2011
Bruno Medeiros
Mar 09, 2011
spir
Mar 23, 2011
Bruno Medeiros
Mar 23, 2011
Bruno Medeiros
Mar 24, 2011
Bekenn
Mar 24, 2011
Daniel Gibson
Mar 24, 2011
Bruno Medeiros
Mar 25, 2011
Andrew Wiley
Mar 29, 2011
Bruno Medeiros
Mar 09, 2011
Brad Roberts
Mar 09, 2011
Bruno Medeiros
Feb 28, 2011
Bekenn
Mar 01, 2011
Jonathan M Davis
Mar 01, 2011
Jim
Mar 01, 2011
dsimcha
Mar 01, 2011
spir
Mar 01, 2011
Nick Sabalausky
Mar 01, 2011
Bekenn
Mar 01, 2011
spir
Mar 01, 2011
Steven Wawryk
Mar 01, 2011
Jonathan M Davis
Mar 01, 2011
Steven Wawryk
Mar 01, 2011
Jacob Carlborg
Mar 01, 2011
Jonathan M Davis
Re: Tooling [ was Re: Pretty please: Named arguments ]
Mar 01, 2011
Russel Winder
Mar 01, 2011
Jacek Nowak
Mar 01, 2011
spir
Mar 01, 2011
Bekenn
Mar 01, 2011
Jonathan M Davis
Mar 02, 2011
Jim
Mar 02, 2011
Don
Mar 02, 2011
Jason E. Aten
Mar 02, 2011
Jim
Mar 02, 2011
Jason E. Aten
Mar 02, 2011
spir
Mar 02, 2011
Bekenn
Mar 08, 2011
Bruno Medeiros
Mar 01, 2011
Stewart Gordon
Mar 01, 2011
Bekenn
Mar 01, 2011
Stewart Gordon
Mar 01, 2011
Bekenn
Mar 01, 2011
Bekenn
Mar 01, 2011
spir
Mar 01, 2011
Nick Sabalausky
Mar 01, 2011
Bekenn
Mar 01, 2011
spir
Mar 07, 2011
Joel C. Salomon
Mar 07, 2011
Jonathan M Davis
Mar 07, 2011
bearophile
February 28, 2011
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?
February 28, 2011
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: 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:

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).

[ . . . ]

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

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

-- 
Russel. ============================================================================= Dr Russel Winder      t: +44 20 7585 2200   voip: sip:russel.winder@ekiga.net 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


February 28, 2011
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?
February 28, 2011
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
February 28, 2011
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  
>> 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.

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
February 28, 2011
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?
February 28, 2011
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

February 28, 2011
On 02/28/2011 08:32 AM, Russel Winder wrote:
>> 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!

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

February 28, 2011
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 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?

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.

-- 
Russel. ============================================================================= Dr Russel Winder      t: +44 20 7585 2200   voip: sip:russel.winder@ekiga.net 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


February 28, 2011
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/

« First   ‹ Prev
1 2 3 4 5 6 7 8 9 10 11