On 6 September 2025 01:47:35 BST, Rob Landers <rob@bottled.codes> wrote: > >Interesting... but we don’t really have a way to say that a parameter or >return value must satisfy *any* constraints except that it be of a certain >type. Hmmm, I guess we have "true" and "false" as values that can be >returned/accepted by functions — but I think they’re the only ones.
Declaring an enum already declares a type. I wasn't thinking about constraining on lists of values, just saying that something should be a "set of T" where T is the enum type. Relying on integer ops, the result ends up as an int: enum FooOption: flag { ... } class Foo { ... function setOption(FooOption $opt): void { ... } function getCurrentOptions(): int { ... } } With general-purpose generics, you can make that strongly typed: enum FooOption { ... } class Foo { ... function setOption(FooOption $opt): void { ... } function getCurrentOptions(): Set<FooOption> { ... } } A specific EnumBitSet<T> could implement the integer serialisation: class EnumBitSet<T> extends Set<T> { function asBitMask(): int { ... } } enum FooOption: int { ... } class Foo { ... function setOption(FooOption $opt): void { ... } function getCurrentOptions(): EnumBitSet<FooOption> { ... } } $foo = new Foo; ... $foo->getCurrentOptions()->asBitMask(); With the recently proposed declare-time generics, you'd just need an extra declaration alongside your enum: class EnumBitSet<T> extends Set<T> { function asBitMask(): int { ... } } enum FooOption: int { ... } class FooOptionSet extends EnumSet<FooOption> { // Can add additional methods here, but don't need to } class Foo { ... function setOption(FooOption $opt): void { ... } function getCurrentOptions(): FooOptionSet { ... } } $foo = new Foo; ... $foo->getCurrentOptions()->asBitMask(); All the operator overloads or methods for things like intersect, union, contains, etc could be on the top-level Set<T>, since they don't intrinsically have anything to do with enums. That's the joy of our enum implementation being object-based: any algorithm that works on object identity automatically works on enum cases. Rowan Tommins [IMSoP]