On Fri, Sep 6, 2024, at 22:45, Larry Garfield wrote:
> Hi Rob.
> 
> First of all, I'm very much in favor of type aliases generally, so thank you 
> for taking a swing at this.
> 
> Second, it looks like you've run into the main design issue that has always 
> prevented them in the past: Should aliases be file-local and thus not 
> reusable, or global and thus we need to figure out autoloading for them?  It 
> looks like your answer to that question at the moment is "yes". :-)  While I 
> can see the appeal, I don't think that's the best approach.  Or rather, if we 
> go that route, they shouldn't be quite so similar syntactically.
> 
> There seems to be two different implementations living in the same RFC, 
> uncomfortably.  In one, it's a compiler-time replacement.  In the other, it's 
> a special class-like.  But the RFC seems to go back and forth on what happens 
> in which case, and I'm not sure which is which.
> 
> However, you have demonstrated a working class-like for it, which is frankly 
> the biggest hurdle.  So I think the direction has promise, but should be 
> adjusted to go all-in on that approach.
> 
> To wit:
> 
> typealias Stringy: string|Stringable;
> typealias UserID: Int;
> typealias TIme: Hour|Minute|Second;
> typealias FilterCallback: callable(mixed $a): bool;  (eventually...)
> 
> (etc.)
> 
> Each of those produces a class-like, which can therefore be autoloaded like a 
> class.  The syntax is also a bit closer to a class (or an Enum, I suppose), 
> so it's much more self-evident that they are defining a reusable thing 
> (whereas "use" does not do that currently).  And the syntax is not stringy, 
> like the proposed type_alias(), so it's easier to write.  I wouldn't even 
> include type_alias() at that point.  It exists at runtime, so reflection is 
> meaningful.
> 
> Aliases can then be used only in parameter, return, property, and instanceof 
> types.  Extends and implements are out of scope entirely.
> 
> (Whether the keyword is typealias or typedef, uses : or =, or whatever, is 
> its own bikeshed I won't dive into at the moment.)
> 
> Then, as a separate, entirely optional, maybe even separate RFC (or second 
> vote, or whatever), we have a `use string|Stringable as Stringy` syntax.  
> Like all other `use` declarations, these are compile-time only, single-file 
> only, and do not exist at runtime, so no reflection.  They compile away just 
> like all other use-statements now.
> 
> I'm not personally convinced the second is really necessary if we do a good 
> enough job on the first, but I'd probably not stand in the way of having both.

That's a really good point and would clear up quite a bit of confusion and 
complexity.

> 
> Having typealias/typedef as a class-like also opens up some interesting 
> potential in the future, because classes have all sorts of other things they 
> do, but that is probably too complex scope creepy to get into here so I will 
> not go further than that mention.
> 
> I suspect there's also other edge case bits to worry about, particularly if 
> trying to combine a complex alias with a complex type, which could lead to 
> violating the DNF rule.  For example:

Oh, DNF is the bane of my existence with this RFC—I don't want to mess this up. 
I'll see you at the end of the example, though.

> 
> typealias Foo: (Bar&Baz)|Beep;
> 
> use (Bar&Baz)|Beep as Foo;
> 
> function narf(Foo&Stringable $s) {}
> 
> With the compile time approach, that would expand to 
> `(Bar&Baz)|Beep&Stringable`, which is not a valid type def.

I can see how you arrived at this, but I think you may have missed a step, 
since the entirety of Foo will be &'d with Stringable.

Foo = (Bar & Baz) | Beep

want: (Foo) & Stringable

expand Foo: ((Bar & Baz) | Beep) & Stringable

Which can be reduced to the following in proper DNF (at least, it 
compiles—https://3v4l.org/0bMlP):

(Beep & Stringable) | (Bar & Baz & Stringable)

It's probably a good idea to update the RFC explaining how expansion works.

> 
> With the runtime approach, I don't know if that could be handled gracefully 
> or if it would still cause an error.
> 
> I'm not sure what the right solution is on this one, just pointing it out as 
> a thing to resolve.
> 
> --Larry Garfield
> 

— Rob

Reply via email to