Eigenpoll : D wish list : Named keyword arguments 

Functions and templates can sometimes grow a lot of arguments. Currently you can specify an argument list with defaults like:

void aFunction(
t1 arg1,
t2 arg2,
t3 arg3 = a3_default,
t4 arg4 = a4_default
)

You can then call aFunction leaving out arg3 or arg4.
But you can't just supply arg4 without also supplying arg3.

If you could call using keywords or named arguments like in some other programming languages (Python, Lisp come to mind) then the problem would be solved:

aFunction(a, b, arg4=17)

This would be very handy for GUI toolkits, whose widget constructors tend to have very long lists of parameters, most with defaults.

Here's a typical example of a constructor from wxWidgets:

wxStatusBar(
wxWindow *parent,
wxWindowID winid,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = wxFULL_REPAINT_ON_RESIZE,
const wxString& name = wxPanelNameStr);

To specify the name, for instance, you have to supply 3 additional unrelated arguments: pos,size, and style.

So you have to do:
new wxStatusBar(parent, id, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE, "the name");

Instead of the much clearer and more maintainable:
new wxStatusBar(parent, id, name="the name");

Boolean arguments is another area.
Since it's so easy to do, people often make methods like:

void manipulate(Size scale, bool lock_x=false, bool lock_y=false);

Then at the point of call you have something like:

manipulate(scale, false, true);

and then you have to go back to the definition of the method to see what false and true mean there.

Of course you can define some enums like
LOCK_ON=true
LOCK_OFF=false
but that's extra work, and also it introduces more symbols into the namespace. Usually to prevent clashes such enums get names like:
QB_MANIP_WIDGET_LOCK_ON=true
QB_MANIP_WIDGET_LOCK_OFF=false

So the call looks like:
manipulate(scale, QB_MANIP_WIDGET_LOCK_OFF, QB_MANIP_WIDGET_LOCK_ON)

And even then its STILL not clear looking at it what's being locked. So you could introduce even more enums like LOCK_X_ON LOCK_X_OFF, and use those. But that's not going to be enforced by the compiler. Hmm so let's define actual distinct compiler checkable enum types for LOCK_X and LOCK_Y. Wow that's getting complicated, and we've introduce 2 public enum types with 2 public values each just to be able to call this silly function.

On the other hand, if you have named keyword arguments then you can just call it like:

manipulate(scale, lock_y = true)

It's perfectly clear to read, and no silly enums. And now we can even introduce more keyword arguments before lock_x, and lock_y without messing this up. Say manipulate is changed to be:

void manipulate(Size scale, Observer obs=None, lock_x=false, lock_y=false)

Then our manipulate(scale, lock_y=true) call is still valid.

All of the above also goes for specifying template parameters.


The downside to this is that matching overloaded versions of functions becomes more complicated to implement.




Report this item for cleanup