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

Reply via email to