Hey,
On 17.3.2025 19:58:39, Rob Landers wrote:
On Mon, Mar 17, 2025, at 19:05, Bob Weinand wrote:
. The idea that extending the parent class doesnt no inherit the
child classes doesnt make sense to me.
As then if you extend a parent class and call a function of that
class which could rely on the existence of an inner class, I can
see a lot of headaches caused by this exact scenario.
As a developer, if I extend a class, I expect the entire dependance
of that class to be inherited, otherwise the extending class won't
work.
I'm not sure what you mean. When you inherit a class, you do not
necessarily inherit everything from its superclass. You are free to
override it however you want. Since we are defining "types" in the
sense of PHP, we cannot merely inherit a "type", otherwise we would
cause all kinds of issues with LSP. This is specifically why
inheritance works the way it does in this RFC and why `static::` is
forbidden.
I don't understand the problem here.
for each nested class in parent class:
class_alias(substitute parent class with child class in class
name, class name)
Very simple. There's no magic needed, it can be simply class aliases.
This will also make static, self and parent trivially work.
PHP doesn't go out of its way to prevent the developer from violating
LSP -- but where it can, it does. If a type were inherited, then the
subclasses wouldn't be able to guarantee that an inner/nested class
implemented the parent inner/nested class. Or, if it did, it would
require that all subclasses using a class of the same name MUST
inherit from the parent class as well.
This is non-trivial to implement as the parent class may or may not
have been compiled yet when we are compiling the subclass. So, we have
no idea what the parent class actually looks like until runtime.
Further, it is much simpler to reason about each class as a distinct
type vs. maybe inheriting a type from a supertype.
Thus, if you want to inherit from the super-class's inner classes, you
can, but this RFC won't force you to do so. In my mind, this is the
biggest argument for a `\`, because the enclosing class acts more like
a namespace than a type, from the perspective of the inner class.
If we were to embrace `\`, then it could be argued that a namespace is
technically a class in itself, (but a partial class, to borrow from C#
terminology) and every class in a namespace is essentially just a
public class in that super-class/namespace.
Nobody has argued that perspective, but I believe it may be
interesting (and would lay a foundation for namespace private/public
class behavior/visibility). That being said, it truly does cause
issues with autoloading -- at least, PSR-4 autoloading -- and I'm not
sure whether we should solve that problem here; however, it is
something to be cognizant of, for sure. There are other types of
autoloading supported by tools, such as composer, that do not have any
issues with using `\` as a separator.
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.
However nice grand unified naming schemes may seem, I don't think it's a
good idea to pursue. Clarity and explicitness shall reign supreme here.
I also don't think that the proposed visibilities are applicable to
namespaced classes. In particular and in practice shared internal
classes are not necessarily directly organized in a way it makes sense
to organize inner classes. Also visibilities like protected propagate
along the inheritance chain, something which is not given with (outer)
namespaced classes.
The less we mix these slightly different concepts, the better.
"It's similar, except in these and those cases" is the death of all
consistent experiences. Thus, let's not even attempt to pretend it is.
And not pretending starts with using a different symbol than a backslash.
Bob