On 11/05/12 00:33, Robert Jacques wrote: > On Sunday, 4 November 2012 at 22:33:46 UTC, Alex Rønne Petersen > wrote: >> On 05-11-2012 00:31, evansl wrote: >>> http://dlang.org/phobos/std_variant.html >>> >>> says: >>> >>> This module implements a discriminated union type (a.k.a. tagged union, >>> algebraic type). >>> >>> Yet, the wiki page: >>> >>> http://en.wikipedia.org/wiki/Tagged_union >>> >>> says: >>> >>> a tag field explicitly indicates which one is in use. >>> >>> and I don't see any indication of a tag field in the std_variant.html >>> page. Another wiki reference: >>> >>> http://en.wikipedia.org/wiki/Disjoint_union >>> >>> is more explicit because it pairs the tag with the value: >>> >>> (x,i) >>> >>> where x is the value and i is the tag. >>> >>> One reason for an explicit tag is that the bounded types may contain >>> the same type twice. This has lead to problems in boost::variant as >>> evidenced by the post: >>> >>> http://article.gmane.org/gmane.comp.parsers.spirit.general/17118 >>> >>> In addition, both variant and tuple have a common part, a metafunction >>> mapping from a tag to a type; hence, this same common part could be used >>> to implement both tuple and a tagged variant. >>> >>> A variant which actually contained a tag field I think would be more >>> general in that it would allow duplicate types among the bounded types >>> just as a tuple's bounded types can contain duplicate types. >>> >>> -regards, >>> Larry >>> >> >> Yes, this is a big problem with the current std.variant implementation >> (among other problems such as no recursive variants....). The best >> std.variant can offer right now is the 'type' property to identify >> what's stored in it. >> >> std.variant is, unfortunately, not very useful if you want the >> semantics of variants in ML-style languages. > > I've been working on an update to std.variant whose formal > submission has been held up by a PhD thesis and some health > issues, although I'm currently (slowly) doing a code > review/cleanup of it in the hope of finally submitting it. ( Old > code: https://jshare.johnshopkins.edu/rjacque2/public_html/ ) > Anyways, my implementation has an internal 'tag' as does the > current implementation, IIRC. However, as the tag is a > meaningless random number, instead .type is provide access to the > meaningful typeinfo object of that class. And .type provides most > (all?) of the functionality of an int id: > > auto var = Variant(5); > if(var.type == typeid(int)) { > // Do something... > } else if(var.type == typeid(string)) { > // Do something else... > }
Robert, I see no bounded types in the above Variant. Looking back at: http://dlang.org/phobos/std_variant.html I see now that std.Variant doesn't require the set of types to be bounded. It's only Algebraic: http://dlang.org/phobos/std_variant.html#Algebraic that has a bounded set of types. I should have read closer. I mistakenly thought std.variant served the same purpose as Boost.variant, but now I see that Boost.variant and std.Algebraic serve similar purposes in that they require a set of bounded types, but that Boost.any and std.variant are similar in that the types are unbounded (IOW, any type can be stored in std.variant or Boost.any). Sorry for not carefully reading. So my question then is why doesn't ALgebraic have a tag. This would allow: Algebraic!(int,int) > > But I am missing something as I found that the linked post wasn't > clear what the exact issue was, only that there was an issue. If > someone would like to clarify the problem (or any other with > Variant) it would be appreciated. > If std.Algebraic is like Boost.Variant, then duplicate bounded types are not allowed and leads to the problem mentioned in the post on the spirit mailing list which I linked to in my OP. OOPS, now I see why reading that post was not clear enough. Maybe this earlier post in same spirit thread would be clearer. http://article.gmane.org/gmane.comp.parsers.spirit.general/17113 In particular, note the phrase: neither can you use variant<string,string,int> because variant can't take duplicate types. This can lead to problems in the spirit parser because the attributes of parsing: a | b where: phrase a has an attribute of type A phrase b has an attribute of type B is: variant<A,B> as noted near the bottom of: http://www.boost.org/doc/libs/1_51_0/libs/spirit/doc/html/spirit/abstracts/attributes/compound_attributes.html and if A and B are the same, then there's a problem because Boost.variant can't handle duplicates. Hope that's clearer. -regards, Larry BTW, recently there was a review of another Boost library that has some similarity to Boost.any. It's called type_erasure: http://steven_watanabe.users.sourceforge.net/type_erasure/libs/type_erasure/doc/html/index.html Since std.Variant is similar to Boost.any (as noted above), and since Boost.any is, in some ways, like Boost.type_erasure, and since you're working on a revised std.Variant, you might be interested in looking at type_erasure.
