On Fri, Apr 21, 2023 at 4:10 AM Robert Landers <landers.rob...@gmail.com>

> 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

Sorry if it sounds stupid or obviously broken, I really am just looking to
understand where my rationale flaw is.

Marco Deleu

Reply via email to