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

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to