Re: [PHP-DEV] [RFC] [Discussion] Typed class constants
Dan, On Sat, Feb 4, 2023 at 8:34 AM Dan Ackroyd wrote: > Hi Mark, > > On Sat, 4 Feb 2023 at 00:22, Mark Niebergall > wrote: > > > > This is also a bigger policy question for other seemingly-abandoned > > RFCs. If it is agreed that a new RFC should be created in this scenario, > > I've added some notes on the page https://wiki.php.net/rfc/howto > > I had some words already prepared from something I will post > separately, but may as well post here also: > > Mailing list etiquette - > https://github.com/Danack/RfcCodex/blob/master/etiquette/mailing_list.md > > Mailing list etiquette for young'uns - > > https://github.com/Danack/RfcCodex/blob/master/etiquette/mailing_list_for_younguns.md > > RFC attitudes - > https://github.com/Danack/RfcCodex/blob/master/etiquette/rfc_attitudes.md > > RFC etiquette - > https://github.com/Danack/RfcCodex/blob/master/etiquette/rfc_etiquette.md > > Most of the stuff in there is just etiquette rather than rules, so > probably isn't appropriate for the wiki. > > Thanks, these are actually very helpful and insightful. > > > I did leave Benas as an author to give him credit for the work he did. > > Although well intentioned, that's probably quite a no-no. Putting > someone's name on something they don't necessarily agree with is > likely to cause drama. I've added a note on that also. > > > With the reverting, valuable community input was dismissed. An effort > should > > be made to address applicable previous community input instead of just > > reverting it out. > > Probably not. > > It's up to other people to persuade RFC authors why something should > be included, rather than RFC authors having to take time and energy to > justify why they are reverting unapproved edits to their RFC. > > But yep, if you want to do it as part of a separate RFC, go for it. > I'll be doing that as a separate RFC, after the typed constants RFC settles. > > cheers > Dan > Ack >
Re: [PHP-DEV] [RFC] [Discussion] Typed class constants
Benas, On Sun, Feb 5, 2023 at 9:29 AM Benas IML wrote: > [copy of the email that I have accidentally sent to Mark individually] > > Hey, > > As much as I appreciate your enthusiasm and ideas, adding your name on > my original RFC and editing its contents without my approval is not > acceptable. Especially considering that contents of the RFCs are a > direct representation of my stance and views on a particular feature. > As such, I would not like to have my name put on proposals that I have > never discussed nor proposed myself. In this case, I explicitly have > given Máté permission to continue working on this RFC and in taking it > under his wing. > My apologies. Good luck on the RFC. > > That being said, feel free to open a new RFC yourself and copy the > contents of your previous proposal from the wiki's history tab. > I will be doing that. I'll give the typed constants RFC time to settle first. > > Best regards, > Benas > > P.S.: Next time, try also contacting me over Room 11 or GitHub, given > that I rarely check this email. > > Thanks for the updated contact information. > On Sat, 4 Feb 2023 at 02:22, Mark Niebergall > wrote: > > > > Máté, Benas, Internals, > > > > On Fri, Feb 3, 2023 at 7:34 AM Máté Kocsis > wrote: > > > > > Hi Alexandru, Mark, > > > > > > > > > > 1. Why is object type not supported? I can't see a real reason and > also > > > > there is no explanation why. > > > > > > > > > > Sorry for this, mentioning object as unsupported was an artifact from > the > > > original version of the RFC which > > > was created back then when constants couldn't be objects. After your > > > comments, I removed the object type > > > from the list. Thank you for catching this issue! > > > > > > > > > > 2. In the examples for illegal values, it would be good to explain > why > > > > they are not legal. > > > > I don't understand why "public const ?Foo M = null;" wouldn't be > legal. > > > > I think "?Foo" should work the same as "Foo|null" that would be > legal. > > > > > > > > It was there due to the same reason as above. I removed this example > now. > > > > > > I had updated the RFC page, but it looks like the changes were > reverted in > > > > December 2022. The updated version I was working on was: > > > > https://wiki.php.net/rfc/typed_class_constants?rev=1648644637 > > > > > > > > > Yeah, the original author of the RFC was surprised to find your > changes in > > > his RFC ( > https://github.com/php/php-src/pull/5815#issuecomment-1356049048 > > > ), > > > so he restored his original version. > > > Next time, please either consult with the author of an RFC if you > intend to > > > modify the wording, or you can simply create a brand new RFC - even if > it's > > > very similar to the original one (just don't > > > forget to add proper references). > > > > > > > See https://externals.io/message/117406#117460 about contact attempts > that > > were made (with no response), and other discussions about why I used the > > existing RFC instead of creating a new one. Next time I will just start a > > new RFC if an author is non-responsive. This is also a bigger policy > > question for other seemingly-abandoned RFCs. If it is agreed that a new > RFC > > should be created in this scenario, I will update > > https://wiki.php.net/rfc/howto since that scenario is not specifically > > covered. > > > > That being said, the RFC was discussed publicly actively last year, and > the > > RFC was revised based on the public input. With the reverting, valuable > > community input was dismissed. An effort should be made to address > > applicable previous community input instead of just reverting it out. > > > > I will work on a new RFC to follow this implementation to introduce > > inheritance. > > > > > > > > > > The updated RFC looks good, thanks for working on it. You may want to > > > > review the revised version I had worked on for implementation ideas, > and > > > > review the previous conversations. > > > > > > > > > > I also saw your proposal, but to be honest, I'm not that fond of the > idea. > > > This doesn't mean though that you shouldn't create a new RFC or an > > > implementation, as others may find it useful. If you kick off > > > the project, I'll surely try to review your work. > > > > > > > That is fine to break it apart as a future RFC. I have seen too many real > > world use cases where inheritance with typed constants would solve > > problems. See https://externals.io/message/117406#117408 for an > > explanation. Adding typed constants independently adds value, so it > should > > progress. > > > > > > > > > > Regards, > > > Máté Kocsis > > > > > > > Overall, I'm happy to see that this is progressing again, thanks for > > working on it. > > > > - Mark Niebergall >
Re: [PHP-DEV] [RFC] [Discussion] Typed class constants
Máté, Benas, Internals, On Fri, Feb 3, 2023 at 7:34 AM Máté Kocsis wrote: > Hi Alexandru, Mark, > > > > 1. Why is object type not supported? I can't see a real reason and also > > there is no explanation why. > > > > Sorry for this, mentioning object as unsupported was an artifact from the > original version of the RFC which > was created back then when constants couldn't be objects. After your > comments, I removed the object type > from the list. Thank you for catching this issue! > > > > 2. In the examples for illegal values, it would be good to explain why > > they are not legal. > > I don't understand why "public const ?Foo M = null;" wouldn't be legal. > > I think "?Foo" should work the same as "Foo|null" that would be legal. > > > > It was there due to the same reason as above. I removed this example now. > > I had updated the RFC page, but it looks like the changes were reverted in > > December 2022. The updated version I was working on was: > > https://wiki.php.net/rfc/typed_class_constants?rev=1648644637 > > > Yeah, the original author of the RFC was surprised to find your changes in > his RFC (https://github.com/php/php-src/pull/5815#issuecomment-1356049048 > ), > so he restored his original version. > Next time, please either consult with the author of an RFC if you intend to > modify the wording, or you can simply create a brand new RFC - even if it's > very similar to the original one (just don't > forget to add proper references). > See https://externals.io/message/117406#117460 about contact attempts that were made (with no response), and other discussions about why I used the existing RFC instead of creating a new one. Next time I will just start a new RFC if an author is non-responsive. This is also a bigger policy question for other seemingly-abandoned RFCs. If it is agreed that a new RFC should be created in this scenario, I will update https://wiki.php.net/rfc/howto since that scenario is not specifically covered. That being said, the RFC was discussed publicly actively last year, and the RFC was revised based on the public input. With the reverting, valuable community input was dismissed. An effort should be made to address applicable previous community input instead of just reverting it out. I will work on a new RFC to follow this implementation to introduce inheritance. > > The updated RFC looks good, thanks for working on it. You may want to > > review the revised version I had worked on for implementation ideas, and > > review the previous conversations. > > > > I also saw your proposal, but to be honest, I'm not that fond of the idea. > This doesn't mean though that you shouldn't create a new RFC or an > implementation, as others may find it useful. If you kick off > the project, I'll surely try to review your work. > That is fine to break it apart as a future RFC. I have seen too many real world use cases where inheritance with typed constants would solve problems. See https://externals.io/message/117406#117408 for an explanation. Adding typed constants independently adds value, so it should progress. > > Regards, > Máté Kocsis > Overall, I'm happy to see that this is progressing again, thanks for working on it. - Mark Niebergall
Re: [PHP-DEV] [RFC] [Discussion] Typed class constants
I initiated a conversation about the typed constants RFC back in March 2022: https://externals.io/message/117406 I had updated the RFC page, but it looks like the changes were reverted in December 2022. The updated version I was working on was: https://wiki.php.net/rfc/typed_class_constants?rev=1648644637 The updated RFC looks good, thanks for working on it. You may want to review the revised version I had worked on for implementation ideas, and review the previous conversations. The primary concept missing is declared but unassigned class constants, which must then be assigned a value in the concrete class. See the section on my revised version "Inheritance and variance". That'll be a question of if that can or should be included in this RFC or not. It provides the most value, allowing for inheritance from a parent class to ensure the value is set and typed in the concrete class. - Mark Niebergall On Tue, Jan 31, 2023 at 5:55 PM Ondřej Mirtes wrote: > I fully support this RFC. PHPStan added support for PHPDoc types in class > constants some time ago - it’s useful to rely on the same constant type > even in subclasses when accessing them via static:: or $object::. > > On Tue 31. 1. 2023 at 22:01, Máté Kocsis wrote: > > > Hi Everyone, > > > > A few years ago, Benas Seliuginas announced the "Typed constants" RFC ( > > https://externals.io/message/110755) which apparently had a > > positive reception overall. > > Unfortunately, there were some issues with the implementation (namely, > with > > the parser) > > so the RFC was stuck. > > > > A few weeks ago, I reached out to Benas whether he intended to resurrect > > the proposal, but > > due to time constraints, he couldn't, and was OK with me continuing it. > > With some help from > > Bob Weinand, I managed to overcome the implementation difficulties, and > > adapted it > > to the newly added type-related features. > > > > Please find the updated RFC here: > > https://wiki.php.net/rfc/typed_class_constants. > > > > Regards, > > Máté > > > -- > > Ondřej Mirtes >
Re: [PHP-DEV] Typed constants revisited
Guilliam, On Wed, Mar 30, 2022 at 7:50 AM Guilliam Xavier wrote: > Hi Mark, > > I have updated the RFC https://wiki.php.net/rfc/typed_class_constants with more details and examples from this thread, and updated the RFC status to Under Discussion. Hopefully the updated RFC helps answer questions and clarifies what the proposal includes. >>> > Thanks (I assume that you talked with the original author) -- not sure if > you should have started a new thread with the "[RFC]" tag in the subject? > I will address the issues from you and Alex in the RFC page, then start a new thread with "[RFC]" since you are correct this has moved past initial testing-the-waters and is now into the discussion phase about the RFC. I reached out multiple times to the original author but have not received a response. I did leave Benas as an author to give him credit for the work he did. > > >> I think you should also update the "Supported types" section. >>> Starting with enums, constants can also be objects. Once a good >>> technical solution is found, any object would be supported probably >>> https://wiki.php.net/rfc/new_in_initializers#future_scope >>> I think that only void, never and callable types should not be >>> supported, just like on properties. >>> >> >> I have updated the "Supported types" to list out all types that are >> supported and which types are not supported. >> > > A few comments, by subsection: > > - **Supported types**: This corresponds to the types currently allowed > for const values (as well as unions thereof) except it [still] doesn't > mention enums (which internally are classes implementing the `UnitEnum` > interface, and whose values are ultimately of `object` type) although > currently allowed. It also doesn't mention `mixed` (used later in examples). > - **Strict and coercive typing modes**: I didn't understand it on first > read; I had to read the later "Constant values" section and compare both > with > https://wiki.php.net/rfc/typed_properties_v2#strict_and_coercive_typing_modes > and https://wiki.php.net/rfc/typed_properties_v2#default_values > - **Inheritance and variance**: Several occurrences of "Class constants" > should probably be "*Typed* class constants". Also, I still think that > `protected bool $isExtinct` is *not* a good parallel to `public const bool > CAN_FLY` (see my previous message). > - **Constant values**: You should probably remove the `iterable` example > now [and maybe add an `enum` one]. > Thanks for the input, I'll work on addressing those. > > >> Constants cannot be objects since objects are mutable, so typed constants >> will not be allowed to be an enum (which is technically an object). A typed >> constant _may_ be an enum value though, so the following example will be >> valid: >> >> ``` >> enum Fruit >> { >> case Apple; >> case Banana; >> } >> >> class Colors >> { >> protected const string RED = Fruit::Apple; >> protected const string YELLOW = Fruit::Banana; >> } >> ``` >> > > This is incorrect, `Fruit::Apple` is of type `Fruit` (ultimately > `object`), not `string`. But it is *not* mutable, and *is* allowed as a > const value currently. > Yes, Alex also identified this issue in my examples, I will correct that and include enum examples in an updated RFC. I will do that before starting an "[RFC]" thread. > > Besides, I realized that the RFC is [only] for *class* constants; what > about *namespaced (and global)* constants? > Ah yes, I hadn't considered expanding this RFC to namespaced and global constants. Let me mull over implementation syntax for those and include them in the RFC. My initial reaction is to not include those in this RFC, keeping the scope to just class constants. If there is value in typing namespaced and global constants, then another RFC could add those. Once I have all these new issues figured out and the RFC updated, I'll start that new thread. > > Regards, > > -- > Guilliam Xavier >
Re: [PHP-DEV] Typed constants revisited
Alex, On Wed, Mar 30, 2022 at 7:47 AM Alexandru Pătrănescu wrote: > Hey Mark, > > On Wed, Mar 30, 2022 at 4:01 PM Mark Niebergall > wrote: > >> Alex, >> >> On Tue, Mar 29, 2022 at 10:35 PM Alexandru Pătrănescu >> wrote: >> >>> Hey Mark, >>> >>> >>> On Wed, Mar 30, 2022 at 6:03 AM Mark Niebergall >>> wrote: >>> >>>> >>>> I have updated the RFC https://wiki.php.net/rfc/typed_class_constants >>>> with >>>> more details and examples from this thread, and updated the RFC status >>>> to >>>> Under Discussion. Hopefully the updated RFC helps answer questions and >>>> clarifies what the proposal includes. >>>> >>> >>> Thanks for the RFC and the drive here. >>> I personally see the benefit and I think it would be a nice addition. >>> >>> I think you should also update the "Supported types" section. >>> Starting with enums, constants can also be objects. Once a good >>> technical solution is found, any object would be supported probably >>> https://wiki.php.net/rfc/new_in_initializers#future_scope >>> I think that only void, never and callable types should not be >>> supported, just like on properties. >>> >>> >> I have updated the "Supported types" to list out all types that are >> supported and which types are not supported. >> >> Constants cannot be objects since objects are mutable, so typed constants >> will not be allowed to be an enum (which is technically an object). A typed >> constant _may_ be an enum value though, so the following example will be >> valid: >> >> ``` >> enum Fruit >> { >> case Apple; >> case Banana; >> } >> >> class Colors >> { >> protected const string RED = Fruit::Apple; >> protected const string YELLOW = Fruit::Banana; >> } >> ``` >> > > Actually, Fruit::Apple is an enum instance and that is an object that is > of Fruit enum type (Fruit class). > You can check this as it's already possible in PHP 8.1, even if it's not > yet possible to have them with type: https://3v4l.org/f4WIC > > What you are referring to as enum value is actually a backed value for an > enum instance. > If you would define the enum as > ``` > enum Fruit: string > { > case Apple = 'apple'; > case Banana = 'banana'; > } > ``` > You could obtain the value with Fruit::Apple->value. But I'm not > referring to this. > > So going back to the topic I mentioned, a constant can right now be an > object. > It can be only an enum instance for now but I believe that in the near > future we will be able to have any object there. > Ah yes, you are correct, my mistake. I will need to make some more updates to the RFC page to address that. > > Also, self and parent would make sense for valid typed constants, just > like they do work on properties. > I'll add examples and an item about this as well. > > Regards, > Alex > > >> >>> >>>> Of note is the "Inheritance and variance" section, which details uses >>>> with >>>> abstracts and interfaces, plus the "Constant values" section which >>>> includes >>>> details about errors. >>>> >>>> >>>> > >>>> > -- >>>> > Guilliam Xavier >>>> > >>>> >>> >>> Thanks, >>> Alex >>> >>
Re: [PHP-DEV] Typed constants revisited
Alex, On Tue, Mar 29, 2022 at 10:35 PM Alexandru Pătrănescu wrote: > Hey Mark, > > > On Wed, Mar 30, 2022 at 6:03 AM Mark Niebergall > wrote: > >> >> I have updated the RFC https://wiki.php.net/rfc/typed_class_constants >> with >> more details and examples from this thread, and updated the RFC status to >> Under Discussion. Hopefully the updated RFC helps answer questions and >> clarifies what the proposal includes. >> > > Thanks for the RFC and the drive here. > I personally see the benefit and I think it would be a nice addition. > > I think you should also update the "Supported types" section. > Starting with enums, constants can also be objects. Once a good technical > solution is found, any object would be supported probably > https://wiki.php.net/rfc/new_in_initializers#future_scope > I think that only void, never and callable types should not be supported, > just like on properties. > > I have updated the "Supported types" to list out all types that are supported and which types are not supported. Constants cannot be objects since objects are mutable, so typed constants will not be allowed to be an enum (which is technically an object). A typed constant _may_ be an enum value though, so the following example will be valid: ``` enum Fruit { case Apple; case Banana; } class Colors { protected const string RED = Fruit::Apple; protected const string YELLOW = Fruit::Banana; } ``` > >> Of note is the "Inheritance and variance" section, which details uses with >> abstracts and interfaces, plus the "Constant values" section which >> includes >> details about errors. >> >> >> > >> > -- >> > Guilliam Xavier >> > >> > > Thanks, > Alex >
Re: [PHP-DEV] Typed constants revisited
On Mon, Mar 28, 2022 at 6:54 AM Guilliam Xavier wrote: > Constants are not abstract in an interface - they must be assigned a >> value. Only classes and methods can be abstract. Within an abstract class >> it is not valid to have an abstract property. Properties can be defined >> `protected int $id;` and optionally assigned a value `protected int $id = >> 5;`, but cannot be `abstract protected int $id;`. >> > > That's the *current* state of the language indeed, but to me, [part of] > your proposal looks like introducing "abstract constants"... Maybe I'm > misunderstanding? > > >> So to me it makes more sense to have constants follow the same syntax as >> properties `public const bool CAN_FLY;` without the `abstract` keyword. >> >> An example: >> >> ``` >> abstract class Bird >> { >> public const bool CAN_FLY; >> protected bool $isExtinct; >> ``` >> >> This allows for similar behavior, similar requirements, and similar >> syntax - consistency ftw! >> > > For similarity/consistency, the `$isExtinct` property should probably be > [`public` and] `static` (actually `readonly` too, but cannot be both). > > But, again, we can also see some similarity with `static` *methods*, e.g.: > > ``` > abstract class Bird > { > abstract public const bool CAN_FLY; > abstract public static function isExtinct(): bool; > } > class Dove extends Bird > { > // NOTE: the following two lines are required (in the class definition) > public const bool CAN_FLY = true; > public function static isExtinct(): bool { return false; } > } > // var_dump(Dove::CAN_FLY); > // var_dump(Dove::isExtinct()); > ``` > > Besides, an uninitialized property must be initialized before first read, > but is *not* required to be overridden/redefined (with a value) in a child > class; so in this example (still hypothetical): > > ``` > abstract class Bird > { > public const bool CAN_FLY; > public static bool $isExtinct; > } > class Dodo extends Bird > { > // NOTE: the following two lines are commented out > // public const bool CAN_FLY = false; > // public static bool $isExtinct = true; > } > var_dump(Dodo::CAN_FLY); > var_dump(Dodo::$isExtinct); > ``` > > where would the [missing value for constant] error be: on the definition > of class Dodo (like for an unimplemented abstract method), or only when > trying to access Dodo::CAN_FLY (like for an uninitialized property)? > > >> >> There seems to be interest and good use cases (thanks Sara for the good >> practical example!). At this point I'm going to work on a new RFC with all >> the details and feedback from this discussion. >> >> > > Thanks & good luck! =) > I have updated the RFC https://wiki.php.net/rfc/typed_class_constants with more details and examples from this thread, and updated the RFC status to Under Discussion. Hopefully the updated RFC helps answer questions and clarifies what the proposal includes. Of note is the "Inheritance and variance" section, which details uses with abstracts and interfaces, plus the "Constant values" section which includes details about errors. > > -- > Guilliam Xavier >
Re: [PHP-DEV] Typed constants revisited
On Fri, Mar 25, 2022 at 10:55 AM Guilliam Xavier wrote: > I intentionally left `abstract` out of `public const bool CAN_FLY;` in the >> `abstract class` for consistency with the implementation with `interface`, >> which would also have to be `public const bool CAN_FLY;`. Currently >> `abstract` is only used in front of methods `abstract function doThing(): >> bool;`. Open to discussion - which way is ideal or preferred? That could be >> included as a subset of an RFC vote if a consensus during discussion isn't >> reached. >> > > I understand, but note that methods are implicitly abstract in an > interface, but it must be explicit in an abstract class; and since I see > the proposed feature mainly as a "replacement" for abstract static methods > [whose all implementations just return a literal value]... (anyway, not > super important) > Constants are not abstract in an interface - they must be assigned a value. Only classes and methods can be abstract. Within an abstract class it is not valid to have an abstract property. Properties can be defined `protected int $id;` and optionally assigned a value `protected int $id = 5;`, but cannot be `abstract protected int $id;`. So to me it makes more sense to have constants follow the same syntax as properties `public const bool CAN_FLY;` without the `abstract` keyword. An example: ``` abstract class Bird { public const bool CAN_FLY; protected bool $isExtinct; ``` This allows for similar behavior, similar requirements, and similar syntax - consistency ftw! There seems to be interest and good use cases (thanks Sara for the good practical example!). At this point I'm going to work on a new RFC with all the details and feedback from this discussion.
[PHP-DEV] Requesting wiki, RFC karma
Hello All, I would like to request wiki edit privileges and RFC karma. Quick intro - I co-organize the Utah PHP Usergoup, speak at PHP and tech conferences, volunteer for cyber security exam certification development, work on a vulnerability management platform with PHP, and have been developing in PHP for ~17 years. Plans - I'm picking up the typed constants RFC where it was left off, planning to create a new RFC for this go around. I have a few other future ideas I've also been tinkering with and plan to create several other RFCs in the future. Username: mbniebergall Thanks, Mark Niebergall
Re: [PHP-DEV] Typed constants revisited
Guilliam, On Fri, Mar 25, 2022 at 6:35 AM Guilliam Xavier wrote: > Hi Mark, > > On Wed, Mar 23, 2022 at 11:55 PM Mark Niebergall > wrote: > >> (...) >> >> Another example I often see in my projects could be used with a similar >> example: >> >> ``` >> abstract class Bird >> { >> public const bool CAN_FLY; >> public const string FAMILY; >> public function canFly(): bool >> { >> return self::CAN_FLY; >> } >> } >> final class EmperorPenguin extends Bird >> { >> public const bool CAN_FLY = false; >> public const string FAMILY = 'penguin'; >> } >> ``` >> > > I had this "need" too (and used abstract static methods where the > implementations just return a literal value...). > > Just 2 remarks: in abstract class Bird, shouldn't it be: > - "*abstract* public const bool CAN_FLY;" (and same for FAMILY) > - "return *static*::CAN_FLY;" > ? > I intentionally left `abstract` out of `public const bool CAN_FLY;` in the `abstract class` for consistency with the implementation with `interface`, which would also have to be `public const bool CAN_FLY;`. Currently `abstract` is only used in front of methods `abstract function doThing(): bool;`. Open to discussion - which way is ideal or preferred? That could be included as a subset of an RFC vote if a consensus during discussion isn't reached. Good correction, yes, `return static::CAN_FLY;` in that example in the concrete child class. > > Regards, > > -- > Guilliam Xavier >
Re: [PHP-DEV] Typed constants revisited
On Thu, Mar 24, 2022 at 1:00 PM Rowan Tommins wrote: > On 23/03/2022 18:54, Mark Niebergall wrote: > > The next phase of work with different RFC would take > > this further with const inheritance, where const type must match. > > > I'm not sure it makes much sense to split this into two RFCs, and as far > as I can see, the previous RFC included both features: > > > Class constants are covariant. This means that the type of a class > constant is not allowed to be widen during inheritance. > > > Or is there something more you mean by "const inheritance", which isn't > covered by the RFC's examples? > Agreed, the more discussion that is going on, the more I'm leaning towards to see this implemented in a single RFC. The true value comes with the full feature set. Correct the original RFC discusses some inheritance, but didn't expand it out the way I'm thinking. It only details ensuring the concrete class has a matching type. I'm proposing additionally allowing blank values to be set by the concrete class. Existing draft RFC (https://wiki.php.net/rfc/typed_class_constants): ``` class Test { private const int A = 1; public const mixed B = 1; public const int C = 1; } class Test2 extends Test { // this is legal (because Test::A is private) public const string A = 'a'; // this is legal public const int B = 0; // this is illegal public const mixed C = 0; } ``` What I'm proposing would further allow const without values in abstracts and interfaces, which require concrete classes to have a value: ``` abstract class Test { private const int A = 1; public const mixed B = 1; public const int C = 1; // no value set, this is legal, concrete classes must set value public const int D; } interface TestInterface { // no value set, this is legal public const string NAME; } class Test2 extends Test implements TestInterface { // this is legal (because Test::A is private) public const string A = 'a'; // this is legal public const int B = 0; // these are required due to inheritance public const int D = 5; public const string NAME = 'EmperorPenguin'; // this is illegal public const mixed C = 0; } ``` > > > Regards, > > -- > Rowan Tommins > [IMSoP] > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > >
Re: [PHP-DEV] Typed constants revisited
Pierre, On Thu, Mar 24, 2022 at 9:20 AM Pierre wrote: > Le 24/03/2022 à 16:06, Mark Niebergall a écrit : > > So you are correct, the const value does have a value that has a type, > but > > there is no way to enforce which type the value is or to use const with > > inheritance, which is part of the bigger picture here. > > That was exactly my point: the type could simply implicitely be the one > of the original value. > > Then the engine just has to use the existing covariance/contravariance > rules for type checks based upon the guessed value type. This would fix > the type safety issue you are referring to. > I'd rather not use the "guessed value type" in code, that tends to lead to bugs: guessing = bugs. Explicitly declaring the type avoids the pitfalls of guessing and ensures code predictability. It also comes with added benefits, including self-documenting code, defined inheritance requirements (the way you describe would have BC breakage), and (for some IDEs) type hinting. Of note, many other languages already have typed constants. Yes this is the "everyone else is doing it" argument, but they had their valid reasons. Some are strong typed languages, others are not. See: - Go: https://go.dev/blog/constants - HVVM: https://docs.hhvm.com/hack/classes/type-constants - C: https://fresh2refresh.com/c-programming/c-constants/ - C++: https://en.cppreference.com/w/c/language/const - C#: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/const > > -- > > Regards > >
Re: [PHP-DEV] Typed constants revisited
Pierre, On Thu, Mar 24, 2022 at 1:04 AM Pierre wrote: > Le 23/03/2022 à 23:10, Larry Garfield a écrit : > > Is there a benefit to it other than "well everything else has types now, > so..."? Even if it's esoteric, like in reflection-based meta programming? > (I've been dabbling too much in that lately. :-) ) "Everything else does" > isn't a compelling argument for me, but there may be others I'm not > thinking of. > > > > --Larry Garfield > > > Hello, > > Well I was thinking myself that const being well... constant, and so > always defined, type could be determined at compile time without the > need to express it in a verbose way. > > PHP doesn't do any static type inference, but in this case, it could be > done almost for free, am I wrong ? If it was determined at compile time, > then the type checking on overrides would only be trivial, using the > parent occurrence value inferred type. My point is that there's no need > to express the type of a value, the value has already has a type. > As a developer, I don't *always* trust other developers implementing my code. Referring back to the Bird and EmperorPenguin example, the expected type for `public const bool CAN_FLY;` example MUST be a bool. If it isn't typed, another developer _could_ incorrectly set `CAN_FLY = 1;` or `CAN_FLY = 'true';` or even `CAN_FLY = 'Y';`. With class constants typed, they would get an error if setting it to anything other than a bool `CAN_FLY = true;` or `CAN_FLY = false;`. This further proliferates into sending the value of `CAN_FLY` into a typed argument like `protected function determineModeOfTransport(bool $canFly)` - if the constant is set incorrectly as a string or integer then more errors can occur. Typing class constants could also help static code analyzers more easily determine if there are bugs with unexpected value types being used in code. Instead of determining the value of the constant, the type of the constant could be used instead, providing a cleaner tokenized parsing. So you are correct, the const value does have a value that has a type, but there is no way to enforce which type the value is or to use const with inheritance, which is part of the bigger picture here. > > Regards, > > -- > > Pierre > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > >
Re: [PHP-DEV] Typed constants revisited
On Wed, Mar 23, 2022 at 4:10 PM Larry Garfield wrote: > On Wed, Mar 23, 2022, at 1:54 PM, Mark Niebergall wrote: > > Hello All, > > > > In June 2020, Benas Seliuginas emailed this list ( > > https://externals.io/message/110755#110755) to gauge interest in typed > > constants. An RFC (https://wiki.php.net/rfc/typed_class_constants) was > > started and had an accompanying PR ( > https://github.com/php/php-src/pull/5815). > > At the time, Nikita Popov supported it for overall language consistency, > > and Sebastian Bergmann +1'd it for overall language consistency as well. > > The PR has since been closed without being merged, and the idea hasn't > > progressed since. > > > > I'd like to revisit the concept, gauge current interest, and pick the > > concept and work back up. Any more discussion items for or against the > idea? > > > > I'm willing to do the work to pick it up where it was left off and get an > > RFC proposed through the normal process, and a working PR. This is my > first > > foray into the PHP RFC process, and C code is not my forte, but I'll take > > it on. If anyone would be willing to pair/mentor/co-author with me, > please > > let me know. Either way, I'll plan to work on it. > > > > This is the first of several concepts I have been tinkering with and > seeing > > practical uses for. The next phase of work with different RFC would take > > this further with const inheritance, where const type must match. > > > > - Mark > > Is there a benefit to it other than "well everything else has types now, > so..."? Even if it's esoteric, like in reflection-based meta programming? > (I've been dabbling too much in that lately. :-) ) "Everything else does" > isn't a compelling argument for me, but there may be others I'm not > thinking of. > > --Larry Garfield > Larry and Internals, To the benefits! On its own, typing class constants does help align them with other things like typed class properties, typed arguments, and method return types. There will come additional benefits though, and this would be phase 1. Phase 2 would be to introduce typed constants to be set by extending or implementing classes. Combining the two features would lead to better defined and usable class constants. For example, an interface could be: ``` interface DbTable { public const string TABLE_NAME; } ``` Which would then be implemented as: ``` class UserTable implements DbTable { public const string TABLE_NAME = 'user'; } ``` Thus ensuring `TABLE_NAME` is always set, and always returns a `string` type. See https://docs.laminas.dev/laminas-db/table-gateway/ for a real-world framework example where this feature _could_ be used. Another example I often see in my projects could be used with a similar example: ``` abstract class Bird { public const bool CAN_FLY; public const string FAMILY; public function canFly(): bool { return self::CAN_FLY; } } final class EmperorPenguin extends Bird { public const bool CAN_FLY = false; public const string FAMILY = 'penguin'; } ``` In this case, one could instead use typed class properties, but it feels improper since the values are static and unchanging. Immutability is a work around to this when implemented properly. This would simplify the solution while ensuring values remain unchanged. - Mark > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > >
[PHP-DEV] Typed constants revisited
Hello All, In June 2020, Benas Seliuginas emailed this list ( https://externals.io/message/110755#110755) to gauge interest in typed constants. An RFC (https://wiki.php.net/rfc/typed_class_constants) was started and had an accompanying PR (https://github.com/php/php-src/pull/5815). At the time, Nikita Popov supported it for overall language consistency, and Sebastian Bergmann +1'd it for overall language consistency as well. The PR has since been closed without being merged, and the idea hasn't progressed since. I'd like to revisit the concept, gauge current interest, and pick the concept and work back up. Any more discussion items for or against the idea? I'm willing to do the work to pick it up where it was left off and get an RFC proposed through the normal process, and a working PR. This is my first foray into the PHP RFC process, and C code is not my forte, but I'll take it on. If anyone would be willing to pair/mentor/co-author with me, please let me know. Either way, I'll plan to work on it. This is the first of several concepts I have been tinkering with and seeing practical uses for. The next phase of work with different RFC would take this further with const inheritance, where const type must match. - Mark