-
Notifications
You must be signed in to change notification settings - Fork 19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Change underlying storage to an actual union #72
Comments
Do you have specific semantics in mind or lifetime management that could be simplified? Not having GC-scanned But it would probably make the code a bit easier to read in any case. There had been issues with unused union parts not getting overwritten that produced false pointers, but those appeared to have gone, judging by vibe.d's |
Instead of using memory tricks, and having to remember to call things that the compiler does naturally, we can let the compiler just do its thing. I have a suspicion that there are some shortcuts that might not be correct, but I haven't proven it yet. I found it odd that when I just added the full union to the Dummy union, it started complaining about how e.g. opAssign couldn't be It also paves the way for CT usage. |
But all the lifetime management (construction, destruction, copy construction/postblit) still needs to be done manually. And (Anyway, I don't really argue against this, we should definitely do it) |
Looking at std.sumtype, @pbackus is destroying the current value, and then assigning the union by constructing a new one (which I assume blits the proper .init value first). I don't think he's calling any postblit/etc manually: The ctors look better too: In general, the machinery just looks much more straightforward and simple. I'd like to see a similar approach here. Let the compiler do the work it knows how to do. It also gives the compiler more info about what is going on. When the compiler sees |
I don't know, maybe its because I know the code, but I really think the main difference comes down to certain simplifications, such as always doing destroy+blit assign instead of using the copy constructor/postblit of the target type, and not so much to how the storage is defined. I don't see much in terms of actual simplification or compiler assistance (struct alignment definitely is, though). BTW, I just discovered that I started a WIP branch for this already: https://github.com/s-ludwig/taggedalgebraic/tree/union_storage |
Simplification should be a goal. If TU is storing a union and not void[N], it should utilize the compiler's in-built abilities to ensure lifetime is done correctly. It may not be automatic, it's still a union, but it should be utilized. I have no objection to using postblit/copy vs. destroy+blit, so long as it's not a manual process. I'm reminded of my newaa project where I reimplemented the built in associative arrays as a library type. I don't do any special mechanisms for the I'm not saying this is a requirement, nor that I have a specific vision in mind. But I'd like to have that kind of "aha, I get how this works" feeling when looking at the code, instead of "I have no idea how this works... this looks like black magic... this looks like a compiler workaround".
Nice! I'll take a look when I have some time. |
But it is manual in both cases. I feel like I'm obviously missing something here, but unless I'm terribly mistaken, |
It has to be done via direct member access. But e.g. this kind of stuff is hard to comprehend why it's needed: taggedalgebraic/source/taggedalgebraic/taggedunion.d Lines 793 to 817 in c40e23c
This is where I started trying to fix #63 and where it started complaining about Maybe I'm misunderstanding the complexity. The whole thing is somewhat confusing to me. Why in some cases it's a void[N], and in others it's a union between the first member and void[N]? This makes weird problems happen when your first member is of a certain type (but I suspect there are similar issues with SumType). It would be nice if the storage is |
Okay, but using edit: CTFE is another valid point though! |
But that's not what happens, these are the paths for all construction and opAssign:
|
SumType does this and I think because of this, it has more accurate semantics than TaggedUnion, and also needs less machinery around the lifetime issues.
I'm putting this issue report here, because I think it's a good goal to have that I think unlocks some other issues that need fixing, specifically #63 and #44.
The text was updated successfully, but these errors were encountered: