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 # 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
signature.asc
Description: OpenPGP digital signature