On Monday, 17 August 2015 at 18:12:02 UTC, Andrei Alexandrescu
wrote:
On 8/14/15 7:40 AM, Andrei Alexandrescu wrote:
On 8/12/15 5:43 AM, Sönke Ludwig wrote:
Anyway, I've just started to work on a generic variant of an
enum based
algebraic type that exploits as much static type information
as
possible. If that works out (compiler bugs?), it would be a
great thing
to have in Phobos, so maybe it's worth to delay the JSON
module for that
if necessary.
First proof of concept:
https://gist.github.com/s-ludwig/7a8a60150f510239f071#file-taggedalgebraic-d-L148
It probably still has issues with const/immutable and ref in
some
places, but the basics seem to work as expected.
struct TaggedAlgebraic(U) if (is(U == union)) { ... }
Interesting. I think it would be best to rename it to
TaggedUnion
(instantly recognizable; also TaggedAlgebraic is an oxymoron
as there's
no untagged algebraic type). A good place for it is straight in
std.variant.
What are the relative advantages of using an integral over a
pointer to
function? In other words, what's a side by side comparison of
TaggedAlgebraic!U and Algebraic!(types inside U)?
Thanks,
Andrei
Ping on this. My working hypothesis:
- If there's a way to make a tag smaller than one word, e.g. by
using various packing tricks, then the integral tag has an
advantage over the pointer tag.
- If there's some ordering among types (e.g. all types below 16
have some property etc), then the integral tag again has an
advantage over the pointer tag.
- Other than that the pointer tag is superior to the integral
tag at everything. Where it really wins is there is one unique
tag for each type, present or future, so the universe of types
representable is the total set. The pointer may be used for
dispatching but also as a simple integral tag, so the pointer
tag is a superset of the integral tag.
I've noticed many people are surprised by std.variant's use of
a pointer instead of an integral for tagging. I'd like to
either figure whether there's an advantage to integral tags, or
if not settle for good a misconception.
Andrei
From the compiler perspective, the tag is much nicer. Compiler
can use jump table for instance.
It is not a good solution for Variant (which needs to be able to
represent arbitrary types) but if the amount of types is finite,
tag is almost always a win.
In the case of JSON, using a tag and packing trick, it is
possible to pack everything in a 2 pointers sized struct without
much trouble.