On Fri, Mar 14, 2025, at 17:09, 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.
>
> 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.
>
> 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.
>
> Ilija
>
Hi Ilija,
What about a hybrid approach? Maybe something like \\
that Tim suggested? But hear me
out. Instead of it being between all inner parts, it is only between the outermost and inner parts
of the class, otherwise just use \
. This also solves a problem where:
- we don't need to change anything with autoloading
- we can differentiate between different types with the same name
So
namespace Foo;
class Outer {
class Middle {
class Inner {}
}
}
namespace Foo\Outer;
class Middle {
}
can be differentiated from each other (Foo\Outer\Middle vs. Foo\Outer\\Middle\Inner).
I also like the idea of just using the name instead of having Foo:>Bar.... I think that is
possible now that I have all the machinery in place for visibility. I may have the implementation
ready today/tomorrow (as per the currently written RFC). 🤞
— Rob