On 2/28/19 5:13 AM, Andrzej Krzemienski via Boost wrote:
Hi Peter, Thank you for writing and sharing this implementation of variant.
I am sorry if I am bringing back an issue that has been already discussed and solved before, but I do not understand the rationale behind doing compromises in order to provide the never-empty guarantee.
At the risk of inserting something totally irrelevant, I'd offer my own experience with variant types. In my case this comes up as the result of an integer operation which might produce an integer or some error condition such as positive_overflow. I've characterized this as "extended integer type" as opposed to "integer" which has infinite range. These types can take on a value from 0 to some N or one value of and enum. Arithmetic operations are defined so that if i and j are both extended integer types, i + j is defined for all types. For example if i & j both hold values "positive_overflow" then i + j would result a value of "positive_overflow". (For those who are interested - the set of values representable by this type and the addition operator constitute a non-associative, commutative group. So the concept is well defined.) Also, of late, I'm been influenced by the discussions about "monad" and it's value in provably correct programs generally. Of course "variant" comes to mind immediately when a C++ programmer starts thinking about this. I looked into it and was dissatisfied with the complexity and ambiguity of the current offerings. I started to think about writing my own. This is always a red flag that something's very wrong somewhere. I eventually concluded that the source of my difficulties was the assignment operation. This of course is derived from the idea that a C++ type should be in general mutable. But the idea that an instance of s set "extended integer" can change to a different member of the same set is mathematically weird. This is why assignability conflicts on fundamental level with the ideas behind functional programming - an idea which has influenced me. So I implemented "extended integer" in the simplest way possible - and deleting the assignment operator. Seems to me that this resolved all my issues. In the few occasions I've been inclined to use assignment, I've found that code was either flawed or could easily be refactored to avoid the need for assignment. I didn't need any "library" type solution as my the implentation of my ad hoc solution is/was trivially obvious. For those interested you can see in the safe numerics library as the type "checked_integer". C++ starts from the idea that every instance should be mutable and hence gives you an assignment operator by default. The design discussions around variant (expected, outcome, ...) presume that this operation must be implemented. I question this. Not only for variant, but for many other C++ data types. Robert Ramey