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