On Fri, Apr 21, 2023 at 4:10 AM Robert Landers <landers.rob...@gmail.com> wrote:
> Hey Deleu, > > I ended up on this list in the first place because I wanted to figure > out how to implement type aliases. I can confidently say why no one > wants to touch it with a ten-foot pole: implementing this will require > refactoring the entire type system. There currently isn't a 'type > table'; supporting type aliases will probably require one. Hey Rob, thanks for this info! I just have some small follow-up for me to make some sense of it. What is fundamentally different about Type Alias as opposed to something like Enums that was recently introduced? ``` enum Options{} class Options{} // Fatal error: Cannot declare class Options, because the name is already in use ``` What I would expect here is ``` type Number = int|float; class Number {} // Fatal error: Cannot declare class Number, because the name is already in use ``` When the engine needs to know about a type alias and it's not in the symbols table, trigger autoload. When the type alias is registered, check if it's value matches what was sent (Type checking). I can kind of imagine the implementation of this could be somewhat awkward because it would involve `instanceof`, `is_int()`, `is_float()`, `is_string()`, etc - meaning we don't have a unified verification system/syntax that encapsulate types and scalar types all at once, but it's not like we have infinite scalar types so it's still doable? > I was able > to hack something together that used the import statements as a way to > work without that much changes (I never got autoloading to work, but I > suspect that was my unfamiliarity with the code, not that it was > impossible): > > use int|float as Number; > > at the top and it would work with fairly minimal changes to the > engine. Anything more complex or different required a huge > refactoring. However, from previous discussions, when that syntax was > brought up, it was shot down. It appears that people want code-wide > aliases, which goes back to refactoring (to the point of > re-implementing an entire type system) and people can't agree that > it's a good idea in the first place (i.e., what if you think int|float > is Number, but some other library has only float aliased to Number?) > and then that can be solved via imports ... but how does that work? > What if you think `\Marco\Deleu\Stringable` is something that works like PHP strings, but it turns out it's actually a math interface that only works with numbers? I know I'm exaggerating, but it's only to make it more obvious that namespaces have solved that problem a long time ago. A library can use `\Lib1\Number = int|float` and make use of it internally and I can also import that. If I want to import `\Lib1\Number` and `Lib2\Number` simultaneously, we have ``` use \Lib1\Number as Lib1_Number; use \Lib2\Number as Lib2_Number; ``` They can be different things and mean different things and be used differently. PHP has "solved" this problem ages ago. If users want a standard meaning for Numbers, PSR can do that. If there is consensus on what `Number` should be, perhaps we will have a `psr/type-aliases` package that defines common type aliases and everyone that wants it can use it for interoperability. Sorry if it sounds stupid or obviously broken, I really am just looking to understand where my rationale flaw is. -- Marco Deleu