On Fri, Sep 6, 2024, at 7:46 PM, Davey Shafik wrote: > My main struggle with this is readability. As much as I want custom > types (and type aliases is a good chunk of the way there), the main > issue I have is understanding what the valid inputs are: > > function foo(Status $string): void { } > > How do I know that Status is a) not a class, b) that I can fulfill the > requirement with a string, and/or maybe any object with __toString(), > or maybe it’s ints? Or objects or enums? > > Even with file-local aliases (which I would definitely prefer to avoid) > we will most likely rely on developer tooling (e.g. IDEs and static > analyzers) to inform the developer what the right input types are. > > I would very much prefer to either go all in with an Enum-like (which > means that we can hang methods on to the value) or we need to > distinguish between type hints for class-likes and type hints for > not-class-likes (*Bar anyone?). > > Expanding on type-class-likes: within the type methods, $this->value > would refer to the original value, any operators would follow the > _same_ rules as either the original values type (e.g. $int = 4; $string > = “foo”; $int . $string == “4foo", or call __toString() in all the > normal places for strings if defined). > > > type Stringable: string|int { > public function __toString(): string > { > return (string) $this->value; // original value > } > > // Add Stringable methods here > }.
Methods on typedefs was the sort of "other stuff classes do" that I was trying to avoid getting into right now. :-) Mainly because I can totally see how it's tempting, but also have no idea what it would mean from a type-theoretic perspective. It would only make sense if we're talking type DEFs, not type ALIASes. I'm not against that, and it could be fun to try and think through the type theoretical implications, but I don't think that's what Rob was going for so I didn't want to take that side quest just yet. (Though if he's OK with it, I'm OK with it.) > So, with that in mind… I’d also like to open up the ability for Enums > to be fulfilled by the backed value, that is: This is 1. Off topic for type aliases. 2. Has been discussed numerous times before. Enums are not equivalent to their backing value. The backing value is a standardized-serialization value. Nothing more. A string-backed enum is not a string, and a string is not a string-backed enum. Trying to use an enum as transparently equivalent to its backing value is a categorical error and belies a misunderstanding of what Enums are. cf: https://peakd.com/hive-168588/@crell/on-the-use-of-enums --Larry Garfield