On Wed, Dec 3, 2025, at 16:51, Larry Garfield wrote:
> Thanks, Rob!  This does seem like a good low-hanging fruit piece to attack.  
> Most importantly, I don't see anything here that would preclude more formal 
> TypeDef structures in the future.
> 
> A few other notes:
> 
> - Should `mixed` be allowed as in an alias definition?  Since `mixed` matches 
> anything, it would render the entire alias redundant as it's then equivalent 
> to `mixed`.

This is already a compiler error: "Type mixed can only be used as a standalone 
type." That being said, I guess this could be used to rename "mixed" to 
something else, but I don't know why you'd want to do that. I'd be open to 
throwing it in with "never" and "void", but "mixed" is an actual type that can 
be returned, which is why it wasn't.

> - What if any conflict resolution is there if you include two different type 
> files that declare the same alias?

It works the same as use in other ways:
"Cannot use type DateTimeImmutable as DT because the name is already in use"

> - Because it's all compile time, I assume two aliases with the same source 
> but different names become compatible?  
> Eg:
> 
> use type string|Stringable as Stringy;
> use type string|Stringable as Stringish;
> 
> Those are mutually compatible in practice, yes?

That's correct. You'd need typedefs to be able to enforce a difference there.

> 
> - Are aliases case sensitive?  You're using Capitalized names in the RFC, but 
> I don't know if that means anything...  (Please state in the RFC.)

Good catch; will do. For the record, it's as type-sensitive as any other type 
in PHP (as in not case-sensitive at all).

> - The "include type" syntax implies that it would not be possible to pre-load 
> aliases via Composer autoload or opcache preloading.  (Well, maybe the 
> latter.)  That feels like an unnecessary limitation, and is my main issue 
> with the current design.  Some way to have project-wide or package-wide 
> definitions would be very helpful, without needing a manual include statement 
> in every file.

Currently, we don't have packages or even "real" namespaces, so as much as I'd 
want this, there'd need to be some settling on what authority a namespace 
really has. The amount of pushback that I got on the namespace-private RFC 
indicates to me that people don't want namespaces to have any authority, but 
they want "packages" but nobody knows what a package is ... but clearly, 
namespaces aren't anything.

I digress. Sadly, no, this isn't possible with the current design. That doesn't 
mean it can't be possible in the future, though, with some autoloading overhaul 
or changes (see: Gina's Core Autoloading RFC under Drafts). But currently, it 
has to pull off some shenanigans to compile the file in the file (instead of 
during runtime like require and include). Hence why type-files may only contain 
types and no other code.

Basically, we just have to have some way to tell the compiler "also include 
these type aliases when compiling this file" -- that could be "every file from 
here on out gets the aliases" (ie, a `use global type float|int as Number` -- 
or something like that), or "include this type file" into this source file.

The former would work best with today's current autoloader, but it would be 
"trapped" in that paradigm and would make it harder to eventually create a 
"type autoloader". I could be wrong, though, and I'm open to other people's 
ideas and opinions. I don't like the current implementation very much, and 
while the former is much simpler to implement, I'm reasonably confident the 
current implementation can be improved.

> - Does it matter where the `include type` statement goes?  Must it be at the 
> top under the `use` statements, or could it be anywhere?

It's basically a "copy this file right here", so it doesn't need to necessarily 
be at the top, but trying to include it in a function would create a syntax 
issue. I should clarify this in the RFC.

> - Not allowing `use` statements in type include files: This feels like a very 
> unfortunate limitation.  Is there any way to obviate that?  It's all compile 
> time, as you said...

I had to go make sure I didn't have a typo in there. I assume you mean 
namespaces? Namespaces in type files have a very weird problem once they get 
included. For instance, namespaces are also compile-time prefixes, and using 
statements are per namespace, not per file. By eliminating the namespace, it 
becomes unambiguous that it’s per-file. That prevents shenanigans like:

// my-types.php
namespace Hello {
  use int|float as Number; // at the end of the namespace, the "use" is lost
}

namespace World {
  use Number as Foo; // Number isn't a thing, neither is Hello\Number
}

Even just declaring a namespace for resolving types would create interesting 
effects:

// my-types.php
namespace Foo;

use int|float as Number; 
// alias actually becomes Foo\Number and gets cleared at the end of the file

In all reality, I generally expect tooling to make this easier. Like 
right-click the alias in your IDE and select: "move to type file" or something 
like that and have it automatically appended to your project's type file. Same 
with typing a type in a type file and having it automatically include it, just 
like it will automatically "use" a type outside of the current namespace for 
you.

> Overall, I am tentatively in favor.
> 
> --Larry Garfield

Thanks!

— Rob

Reply via email to