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

Reply via email to