The Observable C++ library has a new feature: observable expressions.

You can create an expression out of observable values and properties, and its result will also be an observable value. The result will stay updated when the expression’s operands change.

#### A simple example

1 2 3 4 5 6 |
auto x = value<double> { 5.0 }; auto y = observe( 2200 / log10(40 + x / 3), ); x = 17; // Will also recompute y. |

#### Some more details

Observable expressions are just like regular C++ expressions, except that instead of being evaluated only once, they are evaluated each time one of their operands changes.

Take the following code:

1 2 3 |
double a = 5; double b = 15; double avg = (a + b) / 2; |

This is just some regular C++ code; it will compute the average of two numbers. We’ve all seen this kind of code before and we all know how it works.

It works, but what if your operands change? Well, obviously, we’ll need to recompute the average!

1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
double compute_avg(double x, double y) { return (x + y) / 2; } double a = 5; double b = 15; double avg = compute_avg(a, b); // One of our numbers changes for some reason. b = 25; // We need to recompute the average. avg = compute_avg(a, b); |

See, easy! We just need to create a function that computes an average, and each time we change one number we call that function and update the average.

Let’s try it with the Observable library, using observable values:

1 2 3 4 5 6 7 |
using namespace observable; value<double> a = 5; value<double> b = 15; value<double> avg = observe((a + b) / 2); b = 25; // The average is automatically updated. |

The new code is much simpler, right?

You can also subscribe to changes and get notified when the avg changes.

1 |
avg.subscribe([](auto new_avg) { cout << new_avg << endl; }; |

The library supports much more complex expressions than our simple average. You can use mathematical functions, select between two values and even create your own functions (called filters).

Check out the expression documentation for more examples and a more detailed explanation.

#### How this works, from 10k feet

The quick and simple explanation is this: the library provides overloaded operators for value<T>s.

When you use observable values, the overloaded operators return intermediate *expression nodes* (which also overload the operators).

These expression nodes form an *expression tree* that can be used to evaluate an arbitrary expression.

The root of this tree is passed to another class, an *expression* class, which knows how and when to evaluate the expression tree.

The observe() function takes an expression tree and returns an observable value that is linked to an expression. This observable value is updated each time the expression is evaluated.

#### When you should use observable expressions

If you can tolerate a bit of template machinery behind the scenes, and you want to use a reactive approach to your code, then this is for you.

Observable expressions can simplify your code and they can make it more readable than the equivalent code.

Check out the Capture The Dot Game and see how observable expressions are used with Qt.

Check out the Observable library on GitHub: https://github.com/ddinu/observable.