On 19.3.2025 16:04:06, Rob Landers wrote:
On Tue, Mar 18, 2025, at 03:37, Bob Weinand wrote:

Okay, I see the point with LSP. I'm not sure whether we need to preserve LSP for that specific scenario, but neither can I say that we should ignore it.

(Effectively implementing LSP would mean that there's an implicit interface matching all public method signatures of the parent class, for child classes - which is doable, but possibly too much for the initial RFC.)

I would however ask, should we not implement LSP compatible inner classes, to enforce that no child class may name a class the same than any non-private inner class declared by any of its parents, until we resolve this question (in possibly a future version of PHP).
I do not think we should bar ourselves from allowing this in the future.

I'm not sure I understand what you are asking. But I think you are saying the following should be illegal?

class ParentOuter {
  class ParentInner {}
}

class ChildOuter extends ParentOuter {
  class ParentInner {} // not allowed
}

Precisely.

And not pretending starts with using a different symbol than a backslash.

I have been thinking about this for a couple of days now... When thinking through the ramifications of my decision to use :> over ::, this will also affect generics, most likely -- whenever that happens. This is because if this RFC passes, generics will want to be consistent with whatever exists currently.

If we were to use :>, then generics would probably look something like this to be consistent:

class Box<T> {
  public function add(self:>T $item) {}
}

The same thing would also probably apply to ::

class Box<T> {
  public function add(self::T $item) {}
}

With `\`, it nearly follows exactly what you would expect-ish:

use \Box\T as T;

class Box<T> {
  public function add(T $item) {}

// or without use
  public function add(Box\T $item) {}
}

With `\`, we can also just automatically check the current class as part of namespace resolution when compiling:

class Box<T> {
  public function add(T $item) {}
}

This would also make it easier to user inner classes:

class Outer {
  public class Inner {}
  public function foo(Inner $bar) {}
}

The other syntax options do not allow this; at least, I don't think so. I'm very heavily leaning towards `\` as the separator.

— Rob

I'm failing to understand why you'd think this would be related at all?

If we get generics,

class Box<T> {
  public function add(T $item) {}
}

would just work, without any use or such. There will not be a symbol Box::T or Box\T, just all mentions of T within the Box class will be taken as "this is the generic placeholder" and the compiler takes care. It's not like that T will be directly accessible from outside of the class or actually a proper type, unlike inner classes.

A generic is not an inner class nor will it look like it. Also, there's no accessing of a parents generic - you write class Child<T> extends ParentClass<T> - or something along these lines, getting the T available for your class.

Bob

Reply via email to