I only noticed a very tiny description of union types in the language specification, which makes me think Chapel unions are more like C unions than Rust enumerations. Is this right? Is there a good/canonical way to emulate ADTs in Chapel? Any advice will be appreciated. Thanks..
Yes, Chapel unions are very much like C unions. There are thoughts about making them more like a proper variant type/tagged union, but this is not a part of the language that has seen much work.
As far as something like Rust enumerations in Chapel, you can do quite a bit with just Chapel generics. I recommend checking out @daniel.fedorin's talk about type-level programming in Chapel from ChapelCon 2025: https://chapel-lang.org/chapelcon25/#typelevel
I wouldn’t say that emulating ADTs via types as I have done in my talk is a “good” way; it’s nice enough for type-level programming, but it’s probably not what you want in day-to-day programming.
I think the ways to “emulate” Rust ADTs is the same as the way you’d use in C/C++:
a union field and an explicit tag (e.g., an enum outside the union)
a class hierarchy
These have their various drawbacks (one is technically unsafe, and requires some manual effort to keep the union and tag in sync; the other requires heap allocations and probably dynamic dispatch).
Tagging onto the previous responses: It would also be very reasonable to request improved union support by commenting on one of the existing union issues or opening a new one. I'd say that lack of perceived need from the user community is one of the main reasons these haven't gotten more attention to date.
I suspect there is some low-hanging fruit here, depending on what's needed. For example, Chapel unions do store which field is active, so could potentially support a query to get at that hidden field with low effort. Doing something that was higher-level or that required more specialized language support would obviously require more effort (but could still be undertaken).
Thanks @jabraham@daniel.fedorin for your replies. I did come to the same conclusion. @bradcray I did wish that I could just check which field in the union was set as Chapel would throw a runtime error anyway. I will comment in existing union issues. For now I will see if I can just write my code another way.
Thanks to all.
–shiv–
I did wish that I could just check which field in the union was set
It seems possible that this would not be terribly hard to expose in a low-level way—for example, a query that returns an integer indicating which field, by declaration order, was active. That value is stored in the C-level type, so it would just be a matter of exposing it at the Chapel level. I suspect that the only reason we didn't do this earlier was a combination of (a) naivete and (b) wishing for a higher-level more language-integrated solution. But I don't think (b) should stop us from doing something low-level in the meantime to improve the ability to make such a query at all.
For anyone who finds their way to this thread, the conversation migrated to this issue where we found both a workaround for Chapel as it stands today, and Jade has put together a draft PR that exposes it using a user-facing method.