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<bobw...@hotmail.com> 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