I have heard some people claiming that boolean state variables are generally bad and should be avoided when possible. Apparently in many cases it is possible to put state into lambda functions, instead of using booleans. An example to this approach is a conceptual implementation of C#'s Lazy. Lazy<T>
gets a function-like object that constructs T
the first time Get()
is called. Subsequent calls to Get()
return the same T
object over and over again.
For example, a trivial implementation of Lazy, which uses bool can be found at this SO answer. Here is a simplified (thread unsafe) version:
class Lazy<T> { private readonly Func<T> createValue; private bool isValueCreated; private T value; T Get() { if (!isValueCreated) { value = createValue(); isValueCreated = true; } return value; } public Lazy(Func<T> createValue) { this.createValue = createValue; } }
An alternative is to get rid of bool and use lambda functions as a way to store state:
class Lazy<T> { private Func<T> valueGetter; public Lazy(Func<T> createValue) { valueGetter = () => { T value = createValue(); valueGetter = () => value; return value; }; } public T Get() { return valueGetter(); } }
I find both variants similarly readable, but the second variant can be too surprising to some programmers, even though the second is shorter. Due to the surprise factor I like the second variant less. The same can also be done with C++:
template <class T> class Lazy { public: template <class U> Lazy(U createValue) { valueGetter = [this, createValue]() { T value = createValue(); valueGetter = [value] { return value; } ; return value; }; } T get() { return valueGetter(); } private: std::function<T()> valueGetter; };
I have never seen anybody suggest the above, so I assume that it is less fashionable to use this construct in C++.
I find the above lambdas more appealing in a "neat trick" sort of way, but not in a "work with other people" mentality. Should booleans be avoided when lambdas can be used like that? Is using lambdas, like that, considered a good design? Have I been programming C and C++98 for too long, and have become tainted by the mentality of those languages for preferring the boolean?
getValue
? Not defined nor called anywhere.