Hey Rob,
On 17.3.2025 17:53:26, Rob Landers wrote:
On Mon, Mar 17, 2025, at 16:30, fennic log wrote:
2. As with any syntax change and new operator there needs to be very
careful consideration, do we need a new operation, or could `::` if
the parent is static or `->` if the class is initialized?
There's quite a long thread already about this very topic. That being
said, the inner class has no bearing on whether the outer class is
instantiated or not. Originally, I used `::` as the separator, but it
seems there are some good arguments for `\`, so we will see.
I have not grasped any single argument in favour of \, except "other
languages are doing it too", "existing tooling splitting on backslash
would continue to work" and "we could use the existing use statement as is".
The problems are numerous though:
1. Unlike other languages (e.g. C# and java), namespaces and classes may
share a name in PHP. E.g. class "Y" in a namespace "X" and class "X" may
not exist both. In PHP that's allowed. Inner classes compete with
namespaced classes for their fully qualified name.
2. Autoloading will have to become aware of inner classes.
3. Autoloading will have to do a non-cacheable check for existence on
the inner class, before iteratively testing whether any parent has a
respective .php file. Currently autoloading takes a class name,
transforms it to a single canonical path, and includes it. Always
succeeding.
4. Humans, navigating to a path, will not be able to navigate to a file
directly but have to search for it.
5. Tooling splitting on backslash might assume the 1:1 mapping to the
filesystem and break. It's really not a catch all. Some things may be
broken and some not, but all need to be probably revisited anyway.
6. It makes accessing via parent, self or static weird. These keywords
have always been followed by a double colon. (Even if this particular
RFC does not end up adding them) And it will conflict with a namespace
named "parent" for example.
7. At least right now, every backslash identified symbol is trivially
universally public. With \ as an inner class separator, this would no
longer be the case. Maybe that will eventually change, but today this
can be relied upon.
Also, just because other languages are doing a mistake, it does not mean
we have to repeat it. They are generally doing it because their
identifier separator is universal and it's consistent. It does not mean
that it's without its own problems.
Using the double colon is a very minor BC break (accessing a class by a
class constant value?! That's also quite inconsistent that it works at
all, as you can't do that with normal constants, only class constants.).
Using another sigil would also be possible (like :>). But for the
backslash I only see drawbacks.
Also, nothing precludes us from allowing "use Foo\Bar::Inner;".
3. 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.
On 15.3.2025 00:37:08, Rob Landers wrote:
Classes don't actually know their inner classes -- they aren't like
properties. In essence, an inner class is just a regular class with a
funny name and access to scopes it wouldn't normally have access to.
We could probably add `getOuterClass(): string` if that is useful. It
is possible to keep track of a class's inner classes, but then that
introduces a paradox chicken/egg type problem during construction,
which may or may not be a problem.
I don't see the chicken-and-egg problem here. You can simply collect all
the inner class names at compilation. You don't even need to actually
store the zend_class_entry - just collect the names and fetch from the
class table at runtime (and ignore missing ones, e.g. if there was an
error during linking).