Re: RFC: short and inner classes

From: Date: Fri, 14 Mar 2025 17:45:29 +0000
Subject: Re: RFC: short and inner classes
References: 1 2 3 4  Groups: php.internals 
Request: Send a blank email to [email protected] to get a copy of this message
Hey Ilija,

On 14.3.2025 17:09:40, Ilija Tovilo wrote:
Hi Bob On Thu, Mar 13, 2025 at 11:36 PM Bob Weinand<[email protected]> wrote:
On 6.3.2025 23:20:37, Ilija Tovilo wrote:
I would also like to echo what has been said about the :: operator, which feels out of place. I understand that \ comes with additional autoloading challenges, namely requiring a fallback autoloading strategy that currently does not conform to PSR-4.
Could you please elaborate on why the :: operator feels out of place? \ is a namespace separator. :: is a class scoping separator. You, yourself did decide to use nested :: for property hook scoping, like parent::$x::set() - a property scoped within a class, having methods. The same applies here - it's a class scoped within a class, having methods. Breaking from these patterns seems very surprising to me.
:: is an operation performed on the class. E.g. fetch a static property, fetch a constant, call a static method, while \ is part of the class name. The way I see it, the outer class can simply add an additional namespace component to the inner class.
I'd consider this a very internals perspective. Yes, internally it will include its separator and the reported name includes the separator. From a user perspective, the class is fetched (an operation!) from its defining class. Similarly, static::Foo (if it is going to be re-introduced) and parent::Foo, are definitely *fetches* of the class. And as such, it should also have the :: operator.
class Foo {
     class Bar {} // Called Foo\Bar
     public Bar $bar;
} This is dead simple, it doesn't change any assumptions about class names by embedding new symbols, it doesn't need a new operator, you can refer to the class with its short name from inside the outer class without self:>, which is shorter and more straight forward, `use Foo\Bar;` will just work in other classes, etc.
use Foo\Bar; to reference to an inner-class sounds very much like a bad idea to me. Inner classes are supposed to be intrinsically tied to their containing class, and making it work like a namespace reduces the association a lot. I desire explicitness, which a different symbol can give you. Using namespace-syntax makes the autoloading and human resolution more complex for no gain. Removing the self:: seems enticing, but it breaks at the moment you add inheritance. Then you'll have to either make it a binding-time decision whether it's a namespace access or a parent inner class access. class Foo { class Bar {} } class Baz extends Foo { public Bar $bar; // ??? parent::Bar would be obvious. } Certainly you could opt for only removing self:: in classes they are declared in, but what's then the syntax when referring to an inner class up the inheritance chain? parent\Foo? That's plain weird. Or explicitly requiring the concrete class name the inner class is implemented on? Then this becomes the only weird case which cannot be accessed through the scope resolution. Why would one want that?
One thing this approach breaks is that it doesn't allow for polymorphic inner class resolution, i.e. static:>Bar. But given this was removed anyway, that point no longer applies. This can also easily be replicated by a simple method: class Foo {
     class Bar {}
     public function createBar(): Bar {
         return new Bar();
     }
} Except this is actually type-safe, because the return value of createBar() must stay compatible with Foo\Bar.
I don't care much about static resolution for this, but self:: and parent:: are relevant. Bob

Thread (102 messages)

« previous php.internals (#126759) next »