Monday, 16 August 2010

Named function arguments for C++

For me a high quality code is a readable one. Consider a hypothetical method like this:
  class XXX:
{
public:
void func(int aaa, string bbb, bool optionX = true);
...
};
now try to call it:
  func(1, "test", true);
What irritates me here is, that I don't know what exactly does true mean at the first glance! Thus I found myself quite often writting code like this:
  bool useOptionX = true;
func(1, "test", useOptionX);
Well, that's better, but what about this:
  bool useOptionX = false;
func(1, "test", useOptionX); // should I use it or not?
a little bit misleading, isn't it? Not that this would be a big problem, but it's nevertheless a small hitch obstructing us from reading the code effortlesly. OK, next try:
  bool dontUseOptionX = false;
func(1, "test", dontUseOptionX ); // don't use is false, so I should use it?
A total mess! And what about constructors?
  class XXX:
{
public:
XXXX(bool optionY);
...
};
  class YYY: public XXX
{
public:
YYY() : XXX(true) {}; // true what???
...
};
Call me pedantic, but I don't like that at all! What we really need here are Python's named arguments:
  sameFuncInPython(aaa=1, bbb="pythonistas", optionX=True)
Simple, effective, readable! Is there a way to emulate this in C++? Recently, as I was especially annoyed with the constructor example from above, I devised a following solution:
  class XXX:
{
public:
XXXX(bool optionY);
...
typedef useOptionY bool;
};
  class YYY: public XXX
{
public:
YYY() : XXX(useOptionY(true)) {};
...
};
and now the other code can be wtritten totally plausibly too:
  typedef bool useOptionX; // local namespace!
  func(1, "test", useOptionX(false));
func(1, "test", useOptionX(false));
and what would you say to the following?
  waitOnSocket(sec(1), usec(20));

Small thing, but it improves my source code. I like it!

---
PS: After I wrote this, I remembered reading something in this vein about Java. And really, this post http://codemonkeyism.com/never-never-never-use-string-in-java-or-at-least-less-often/ by Codemokeyism proposes generally the same solution:

  new Customer(firstName("Stephan"), name("Schmidt")); 
Alas, instead of a benign typedef, you have to write a whole new class named name and firstName etc. Without doubt it's and improvement, but the costs and the clutter... But on the other side Java tends to be verbose nonetheless, so maybe it's OK.