[DO NOT MERGE] POC: Add language-level tagged unions (enum union) and pattern matching (switch expressions) - #23744
[DO NOT MERGE] POC: Add language-level tagged unions (enum union) and pattern matching (switch expressions)#23744MetaLang wants to merge 1 commit into
Conversation
DMD perf check
Breakdown — compile hello.d
Breakdown — compile Phobos+43.5 M instructions: frontend +43.7 M (+1.20%), codegen -0.3 M (-0.02%)
All measurements
e174f31 vs merge-base 7e0b115 · about these metrics |
| from.isFunction_Delegate_PtrToFunction() | ||
| ? MATCH.convert : MATCH.exact; | ||
| const isNullUnitVariant = from.toBasetype().ty == Tnull && | ||
| variant.payload.length == 0 && variant.ident == Identifier.idPool("None"); |
There was a problem hiding this comment.
Try to avoid comparing identifiers by string, chuck None into the table and do a pointer comparison instead.
| alias Parameters = Array!(Parameter); | ||
| alias Statements = Array!(Statement); | ||
| alias Catches = Array!(Catch); | ||
| inout(SwitchExp) isSwitchExp() { return op == EXP.switchExpression ? cast(typeof(return))this : null; } |
There was a problem hiding this comment.
That doesn't look like the right place for it.
|
Some of the implementation is certainly cleaner. It doesn't handle integer confusion, which is why I banned that. No handling of alias sequences and expansion into variants. Kinda important use case both in literature and in D code. You did not solve for the overlapped error. You support multiple values per variant, I assume that tuples will exist to define that into existance. It does not support by-ref, vs by-value this is a killer feature over library. It does not support chaining like it would via UFCS, this is a downgrade over library. It requires a lot of redundent tokens, you don't need case inside of the declaration, nor in switch expression. The extra combination of enum and union I very much dislike it. As we've learned from DIP1000 that is not a good thing. |
It's just vibe-coded LLM slop I banged out to show my vision for how such a feature would work.
I'm not completely sure what you're referring to. It will reject cases like: enum union Num
{
int,
long,
}
Num n = 0;Unless you disambiguate with a cast or literal syntax.
Ya, too complicated to implement for a POC, but it should be supported through .tupleof or something similar.
What's that?
The variants are "tuple-like", but currently don't have any relation to tuples. I don't think that's a necessity, but may be nice to have. The struct variants are really useful though.
Ya I'm not sure what to do about that because of the safety issues. Maybe with your fast DFA it'd be safe to support.
That feature is maybe a nice to have, but it's very easy to emulate with a switch expression inside a UFCS function and IMO doesn't add a whole lot.
Those are for readability/comprehensibility more than anything. It makes it more clear to the people reading and writing the code what's going on semantically, and I think that the case token before each variant might be necessary for disambiguation if you also wanna have member functions inside the body, but I may be misremembering. The case tokens in switch expressions are to match how you declare cases in the enum union body, and to make it more familiar for programmers who are used to the regular switch. But yeah they're unnecessary in terms of parsing.
I think it's good for signalling to the programmer what this construct does and how it works. It's like a union, but with an enumerated list of cases (and enums are traditionally used for the tag in a tagged union). Also note that Rust, Swift, C#, Zig and Odin all use the keywords enum and/or union (in Zig it's literally You could just as easily use |
Its an error for
I've got to go do that on my PR.
Booo functions, not analyzable! Not clean chaining of input ranges.
|
This PR adds language-level support for Rust/Swift-style tagged unions (called
enum union), and dedicated syntax for matching on their variants in the form of switch expressions.I wasn't satisfied with @rikkimax's approach in #23540, which is more in line with the structural approach taken by ML/Haskell, so I decided to implement it myself. And by myself, I mean an LLM - I wrote the spec, but it wrote all of the code and tests, and it was pretty quick and dirty. Consequently and unsurprisingly, most of the test runners are failing.
See enum_union_guide.md for an explanation of how the features work.
Included
@xoxorwr @limepoutine @Herringway