Pretty please: Named arguments

Jacob Carlborg doob at me.com
Mon Feb 28 05:05:38 PST 2011


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


More information about the Digitalmars-d mailing list