On Fri, Oct 27, 2017 at 10:51 PM, Fleshgrinder <p...@fleshgrinder.com> wrote:

> Hey Internals!
>
> We currently have a couple of things that are broken about constants,
> and I wanted to gauge if people are interested in a) fixing it as well
> as b) to get to know the root causes of these things.
>
> # 1
>
> A constant defined in an interface cannot be overwritten in the class
> that implements the interface, however, further subclasses can overwrite
> the content of the constant at will.
>
> - https://3v4l.org/DFB37
> - https://3v4l.org/9LMci
>
> A constant defined in a class can be overwritten by any subclass at will.
>
> # 2
>
> Constants can reference themselves, and subclasses can define the actual
> value. Kind of like abstract constants. This works nicely while working
> with an actual instance of the object, however, it breaks in the moment
> that constant is accessed anywhere in the parent, or from any other
> constant.
>
> - https://3v4l.org/HUCTh
> - https://3v4l.org/5aYB5


PHP does not permit self-referencing constants.

However, this is only checked when the constant is first accessed. In your
first example the constant is never accessed, so no error is thrown. This
has nothing to do with subclasses defining the value -- you're using late
static binding, so you're accessing the constant of the child class
directly.

PHP cannot detect self-referencing constants during compilation, because
they may be formed through non-trivial cycles involving multiple constants,
across multiple files.

Nikita

# 3
>
> A constant that is defined with a visibility in a parent class, cannot
> be references between subclasses, like it is possible with methods.
> Instead we are presented with an access violation.
>
> - https://3v4l.org/2lU3i
>
> Note that this behavior is the same for static and instance properties
> that are being redefined in a child class. Hence, access is defined by
> location and not by modifier.
>
> # What I think
>
> I haven't thought very long about everything, but here are my initial
> thoughts:
>
> ## 1
>
> This issue could be resolved by changing the behavior to enable
> overwriting of parent constant in any sublcass. This gives us a
> consistent behavior.
>
> Afterwards we should add support for the final modifier, so that people
> can seal their constants and protect them from redefinition.
>
> > Why not seal by default?
>
> It would disallow some dynamic programming that is possible with the
> late static binding of PHP, and I honestly see no reason why we should
> disallow something that is already possible: BC!
>
> ## 2
>
> Disallow self-referencing constants in any context, and instead add
> support for the abstract keyword to constants. This raises the question
> on how to deal with constants in interfaces. I would allow the
> definition of both constants with and without a value there. Those
> without are abstract, those with a value are like they are right now.
> Directly referencing an abstract constant should result in an error.
>
> Abstract constants are a great thing in combination with late static
> binding, and the engine ensures that the value does not change over the
> course of the runtime of the program. An attribute that is impossible
> for methods. Dart for instance has support for the const keyword for
> many elements, including methods.
>
> ## 3
>
> This seems like a bigger construction site. I think that the behavior
> should be that the access is determined by the modifier, and not the
> location. Especially because doing anything else is to great of a BC.
> The current behavior of allowing access to protected members of other
> classes with the same parent also allows the creation of friend classes.
> Although without the control that real friend classes have.
>
> --
> Richard "Fleshgrinder" Fussenegger
>
>

Reply via email to