Trait constants

  110741
June 27, 2020 13:52 php-lists@koalephant.com (Stephen Reay)
Hi,

It’s always struck me as slightly odd that traits don’t support constants the way classes and interfaces do.
I tried to find an explanation of the lack of support in the original RFC, and came up empty.

A consequent discussion in R11 has led me here.
Can anyone working on internals explain why traits don’t allow constants (either technically or philosophically)?
Moreover, what’s the opinion(s) of the list, on adding support for this? Would an RFC be needed? 


Cheers 



Stephen
  110745
June 27, 2020 15:59 mike@newclarity.net (Mike Schinkel)
> On Jun 27, 2020, at 9:52 AM, Stephen Reay <php-lists@koalephant.com> wrote: > > Hi, > > It’s always struck me as slightly odd that traits don’t support constants the way classes and interfaces do. > I tried to find an explanation of the lack of support in the original RFC, and came up empty. > > A consequent discussion in R11 has led me here. > Can anyone working on internals explain why traits don’t allow constants (either technically or philosophically)? > Moreover, what’s the opinion(s) of the list, on adding support for this?
Yes. Please. -Mike
  110750
June 27, 2020 19:09 tysonandre775@hotmail.com (tyson andre)
> It’s always struck me as slightly odd that traits don’t support constants the way classes and interfaces do. > I tried to find an explanation of the lack of support in the original RFC, and came up empty. > > A consequent discussion in R11 has led me here. > Can anyone working on internals explain why traits don’t allow constants (either technically or philosophically)? > Moreover, what’s the opinion(s) of the list, on adding support for this? Would an RFC be needed?
I'm in favor of adding it. I doubt there's any insurmountable technical obstacles. (I work on a static analyzer for php (https://github.com/phan/phan) and don't expect technical issues with that proposal) I personally find it inconvenient to put constants used by traits in different classes/interfaces or in properties. Other languages allow adding constants to traits: - Java allows defining constants on interfaces, which allow defining default method implementations like PHP traits - https://doc.rust-lang.org/edition-guide/rust-2018/trait-system/associated-constants.html allows defining constants with values on traits (it also does various other things that impractical for php) One thing to document/add tests for would be the resolution of `self::MY_CONST`. In a trait, `self::method()` may be overridden by the method of the class that's using the trait. I'd expect `self::MY_CONST` to be the same. ```php https://www.php.net/manual/en/language.oop5.traits.php#language.oop5.traits.conflict (e.g. `use A, B { const A::MY_CONST insteadof B; }`) - We already check if there are conflicting values when inheriting constants from an interface and another interface/trait. Cheers, - Tyson
  110751
June 27, 2020 19:32 tysonandre775@hotmail.com (tyson andre)
> Can anyone working on internals explain why traits don’t allow constants (either technically or philosophically)? > Moreover, what’s the opinion(s) of the list, on adding support for this? Would an RFC be needed?
I don't think there's any insurmountable obstacles, but it would be useful to add a lot of tests because of potential edge cases (resolution, opcache, reference counting) involved in traits and adding new places where constants can go. (I'd also worked on a declined RFC and implementation for changing what could be used in a constant expression) ``` getMessage() . "\n"; } D::main(); /* Output: from c Undefined class constant 'self::OTHER_CONST' From D */ ``` - Tyson
  110756
June 28, 2020 12:33 nikita.ppv@gmail.com (Nikita Popov)
On Sat, Jun 27, 2020 at 3:53 PM Stephen Reay <php-lists@koalephant.com>
wrote:

> Hi, > > It’s always struck me as slightly odd that traits don’t support constants > the way classes and interfaces do. > I tried to find an explanation of the lack of support in the original RFC, > and came up empty. > > A consequent discussion in R11 has led me here. > Can anyone working on internals explain why traits don’t allow constants > (either technically or philosophically)? > Moreover, what’s the opinion(s) of the list, on adding support for this? > Would an RFC be needed? >
Sounds like a reasonable addition. An RFC will be needed to specify the details, which tend to be tricky whenever traits are involved. Some suggestions: * Constants mustn't be accessible directly on the trait, i.e. TraitName::FOOBAR throws. self::FOOBAR within the trait is legal in that "self" is remapped to the using class, as usual. * The same constants important from multiple traits should follow the rules of properties, i.e. require that values match. Conflict resolution for constants should very much *not* be supported. Regards, Nikita