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