You need the Option class

Having studied a lot of Scala, and now moving back to C++, there are many things that you find in code “in the wild” that I used to find acceptable, but today I find a real eye sore. Many of those are things that experienced C++ programmers can easily agree to, such as avoiding functions that just modify object state, and try otherwise to write mostly functions that take all information it needs explicitly as parameters, and puts all its outputs in the actual return value. This is greatly praised in functional programming. But another eye-opener to me was to learn about monads, and specifically about the Option class.

Monad theory is very interesting, but you don’t really need any of that to get the Option class. This class can be understood as a container that can hold a single value. It is either empty, or it has a value that you can read.

It becomes extremely handy as a way to dead with computations that can fail. Lazy or inexperienced programmers, or even yourself, can deal with that sometimes by just returning a “Null” or “None” instead of a value in your program. This is specially common in dynamic languages. Or even worse, you might decide to raise and exception, what is something awful… Or return “-1” also instead of a natural. Ideally what you should do is to return an Option<int> containing either a value, or the actual object from the class that represents the absence of a “valid” value.

C++ programmers do that a lot using pointers. You set a pointer to NULL if the object doesn’t exist, otherwise you can work with it… Here is one example of actual code with anonymized variables that does that:

bool bX = true;
if(pbY)
  if(*pbY)
    bX = false;
if(bX) {...}

It is an interesting example because it deals with a pointer to Boolean, that we would like to see changed to an Option<bool>, probably. The code is weird because apart from the disguised Option logic, it is hard to imagine why to have this pointer to bool instead of just taking bool parameters. And then there is a new bool declared to store the result of the expression

pbY && *pbY

or explicityly

pbY != NULL && *pbY == true

Why didn’t that turn into a bool earlier on? We can’t really say, we are thinking too locally maybe. But if this extra information about the Boolean being “valid” or not is really necessary here, then there is no other way: either you have two Booleans, one to mark “valid” and the other with the value, or you have something like this based on pointers, or finally you explicitly use an Option<bool> object.

One interesting aspect from Option class is that you can chain these computations that can fail. You don’t think too much about this kind of stuff when you are working with pointers like this, but it becomes more clear when you move into a proper class… Here is another example of a situation that happens sometimes in code, that doesn’t actually have to do with “failure”, but that might be improved with an Option modeling. Original code is:

bool wasOK;
if (testA() && testB()) {
  wasOK = processA();
} else {
  wasOK = processB();
  if (!wasOK)
    wasOK = processA();
}

The program is returning a single boolean to indicate whether the “process” was successful. The order of execution does not reveal something important, though. processB actually happens more frequently than processA. My nomenclature also didn’t help… It is easier to understand the code if I write in plain english:

“If we can run process B, do it. If we can’t run it, or if we can but it failed, then run processA.”

A clearer code would be something like:

wasOK = !(testA() && testB()) && processB() || processA()

Here we exploit the “short-circuit” feature from logic operators, by the way, so processA doesn’t run if processB is successful, and processB doesn’t run if not possible.

But really, what would be even nicer was if we had

Option<bool> processBopt() {
  return (testA() && testB()) ? None : Option<int>(processB());
}

Option<bool> processAopt() {
  return Option<int>(processA());
}

And now we can do, in Scala lingo:

processBopt() orElse processAopt()

And much better yet would be to return the actual result from the process, and not just a signal about whether it was successful and the results are sitting somewhere “you should know where”…

I have no idea how the “orElse” operator is implemented in existing C++ classes. But in Scala it looks great, and it is one of the main reasons I love to use Scala today. It is just much better to deal with this kind of slightly-more-complicated logic that you find in real life. Actually working with the Option class in C++ will probably never be as good as it is in Scala – apparently Boost has it, but I’m not sure how to use it. But I do believe I would still find a way to avoid this kind of pointer-based code I have shown here if I had written this program, and would have stick to some of the alternatives. Once a programmer finally learns about this Option “design pattern”, everything becomes easier if you stick to it when the situation requires it.

Advertisements

2 thoughts on “You need the Option class

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s