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