Re: [PHP-DEV] Constants and Access Modifiers
On 11/12/2017 7:25 PM, Rowan Collins wrote: > On 12/11/2017 09:49, Fleshgrinder wrote: >> Other languages allow you to have a contract on fields. >> >> class A { const FOO: int = 42; } >> class A { final static $foo: int = 42; } >> >> These are basically the same, as you already said. However, I added a >> contract to both of them. > > Yes, I wondered whether to mention type constraints; certainly the > previous, stalled, proposal would have added them directly on what I was > calling "fields". The more I think about it, though, the more I think a > separate notion of "properties" like C# would be a great way to add new > constraints in a clear way. > > Consider "int $foo { public get; private set; }" as defining the following: > > - a field which like any other variable could theoretically have any > value, but which will never be accessed except via the property definition > - a getter method with the signature "function(): int" > - a setter method with the signature "function(int $foo): void" > > It immediately makes sense why you can't assign by reference (the setter > method doesn't take a reference, only a value). It also makes sense to > have this present in an interface (the implementing class is obliged to > have such a property, but may define explicit getter and setter methods > rather than defaults). > > You could then also have syntax for a property with a compile-time value > and no setter, but I'm not sure whether this meets your requirements. > Having this functionality would be more than awesome. Especially because it would allow upgrade paths for anemic code bases where all properties are public. On 11/12/2017 7:25 PM, Rowan Collins wrote:>> There is one thing that differs for the const >> and the field: a const value must be known at compile time, whereas a >> field value does not. An important difference! >> >> class A { abstract public const FOO: int; } >> class A { abstract public function foo(): int; } >> >> These also look basically the same. The return value of the method, >> however, may also be determined at runtime (just like with fields) and >> on top of that might change with every invocation. > > What I'm not really clear on is *why* the value being known at > compile-time is important to you. Is there some architectural decision > you would make differently based on this guarantee? Are you expecting > the language itself to have some optimisation or different behaviour > based on that guarantee? > I expect certain optimizations, and as my fellow Austrian countryman Harald already said, there is enough room for them. I also expect the ability to perform calculations at compile time, instead of at runtime. The values would stay the same forever with proper caching. abstract class A { abstract const X; abstract const Y; final const Z = self::X + self::Y; } final class B extends A { const X = 1; const Y = 1; } On 11/12/2017 7:25 PM, Rowan Collins wrote: > Would the ability to mark a function as "pure" (always returning the > same output for the same input) serve the same purpose, since a pure > function with no arguments can be substituted for its return value at > compile time? > > abstract class A { abstract static pure function getFoo(): int; } > class B extends A { static pure function getFoo(): int { return 42; } } > class C extends A { static pure function getFoo(): int { return 999; } } > > Regards, > Pure functions in general would be an awesome thing in PHP, as they also allow for many optimizations. -- Richard "Fleshgrinder" Fussenegger signature.asc Description: OpenPGP digital signature
Re: [PHP-DEV] Constants and Access Modifiers
Am 12.11.2017 um 19:25 schrieb Rowan Collins: On 12/11/2017 09:49, Fleshgrinder wrote: There is one thing that differs for the const and the field: a const value must be known at compile time, whereas a field value does not. An important difference! class A { abstract public const FOO: int; } class A { abstract public function foo(): int; } These also look basically the same. The return value of the method, however, may also be determined at runtime (just like with fields) and on top of that might change with every invocation. What I'm not really clear on is *why* the value being known at compile-time is important to you. Is there some architectural decision you would make differently based on this guarantee? Are you expecting the language itself to have some optimisation or different behaviour based on that guarantee? compile time at least leaves space for optimization and looking what opcache only since PHP7.0 got and looking forward to a JIT implementation this can make a difference in the future -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Constants and Access Modifiers
On 12/11/2017 09:49, Fleshgrinder wrote: Other languages allow you to have a contract on fields. class A { const FOO: int = 42; } class A { final static $foo: int = 42; } These are basically the same, as you already said. However, I added a contract to both of them. Yes, I wondered whether to mention type constraints; certainly the previous, stalled, proposal would have added them directly on what I was calling "fields". The more I think about it, though, the more I think a separate notion of "properties" like C# would be a great way to add new constraints in a clear way. Consider "int $foo { public get; private set; }" as defining the following: - a field which like any other variable could theoretically have any value, but which will never be accessed except via the property definition - a getter method with the signature "function(): int" - a setter method with the signature "function(int $foo): void" It immediately makes sense why you can't assign by reference (the setter method doesn't take a reference, only a value). It also makes sense to have this present in an interface (the implementing class is obliged to have such a property, but may define explicit getter and setter methods rather than defaults). You could then also have syntax for a property with a compile-time value and no setter, but I'm not sure whether this meets your requirements. There is one thing that differs for the const and the field: a const value must be known at compile time, whereas a field value does not. An important difference! class A { abstract public const FOO: int; } class A { abstract public function foo(): int; } These also look basically the same. The return value of the method, however, may also be determined at runtime (just like with fields) and on top of that might change with every invocation. What I'm not really clear on is *why* the value being known at compile-time is important to you. Is there some architectural decision you would make differently based on this guarantee? Are you expecting the language itself to have some optimisation or different behaviour based on that guarantee? Would the ability to mark a function as "pure" (always returning the same output for the same input) serve the same purpose, since a pure function with no arguments can be substituted for its return value at compile time? abstract class A { abstract static pure function getFoo(): int; } class B extends A { static pure function getFoo(): int { return 42; } } class C extends A { static pure function getFoo(): int { return 999; } } Regards, -- Rowan Collins [IMSoP] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Constants and Access Modifiers
Am 12.11.2017 um 10:50 schrieb Alice Wonder: On 11/12/2017 01:38 AM, Tony Marston wrote: Just because some languages use a corrupt definition of "constant" is no reason for PHP to do the same. A constant has a value which, once defined, cannot be changed. It is not logical to define a constant name in one place and its value in another. Plus plus on this. A constant does not change. If it changes it is a variable. I do not know anything about Dart but if they are changing the meaning of well-defined terms like constant, I worry that there will be programs with security holes simply because some developers will not understand what they mean by the terms they define. what about both of you read the initial post of that thread as well as the manual at http://php.net/manual/en/language.oop5.interfaces.php ___- that's the topic and not arbitary change constants! 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 -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Constants and Access Modifiers
On 11/12/2017 01:38 AM, Tony Marston wrote: wrote in message news:549c4634-ac38-41d3-ab43-f816a9f2b...@fleshgrinder.com... On 11/12/2017 12:44 AM, Stanislav Malyshev wrote: Hi! Yes, Dart has a different understanding of const, which is exactly why I posted it for you guys. In the hope that it helps to get more different views on the topic. Currently you are too concentrated on how it is implemented in PHP at this time, and argue that it is impossible to diverge from that path. Which is simply not true, we only have to ensure backwards compatibility. I am not arguing it's impossible, I am arguing it is not a good idea. We have the concept of constants in this language, and bolting on it a completely different concept from different language, which by coincidence was named with the same term, would only be a source of confusion. If we wanted immutable objects in language - which I am not convinced at all we do, but assuming for a minute we did - there's no reason to conflate them with constants as we have them now. These are different things. I did not mean to say that we have to have everything exactly as Dart has it. I just wanted to show, that the meaning of const as we have is not universally the same. Abstract constants would also only be truly useful if we could define the type as well on them. Which is currently not possible. Also, I am not saying that the requested feature MUST be done with const. However, it should behave like one, which is impossible with methods. Just because some languages use a corrupt definition of "constant" is no reason for PHP to do the same. A constant has a value which, once defined, cannot be changed. It is not logical to define a constant name in one place and its value in another. Plus plus on this. A constant does not change. If it changes it is a variable. I do not know anything about Dart but if they are changing the meaning of well-defined terms like constant, I worry that there will be programs with security holes simply because some developers will not understand what they mean by the terms they define. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Constants and Access Modifiers
On 11/11/2017 9:51 PM, Rowan Collins wrote: > On 11/11/2017 18:39, Fleshgrinder wrote: >> On 11/6/2017 1:44 AM, Stanislav Malyshev wrote: >> >>> From this link, it looks like const in Dart has pretty much nothing in >>> common with const in PHP, besides name, so in the interest of avoiding >>> confusion, I would not discuss it in the same topic. >>> >> Yes, Dart has a different understanding of const, which is exactly why I >> posted it for you guys. In the hope that it helps to get more different >> views on the topic. Currently you are too concentrated on how it is >> implemented in PHP at this time, and argue that it is impossible to >> diverge from that path. Which is simply not true, we only have to ensure >> backwards compatibility. > > I think the point is that adding "single-assignment variables" (which > Dart calls "final") or "deeply immutable values" (which Dart calls > "const") would be a completely different feature which could be added > side-by-side with what we have now, under a different name. What PHP > calls "const" (in the context of classes) is neither of those features. > I know and I repeat, I posted the link just to show that const can be more than the const we currently have, and to fuel the discussion. I never said that we have to have the same implementation they have. ;) On 11/11/2017 9:51 PM, Rowan Collins wrote: > The debate seems to be whether you view class constants as more like > static properties, or static methods. Given this: > > class A { public const Foo = 42; } > echo A::Foo; > > Is it equivalent to this (using an imaginary "readonly" modifier)... > > class A { public static readonly $foo = 42; } > echo A::$foo; > > ...or is it equivalent to this (particularly if you imagine an > optimising compiler that caches / inlines the result)? > > class A { public static function foo(): int { return 42; } } > echo A::foo(); > > > The difference is that a field is never "abstract" - it either has a > value, or it is undefined; you can't add a contract to an interface > saying "you must have this field" either. A method, on the other hand, > is assumed to encapsulate something - it's a black box with a contract, > so defining the contract without any implementation makes sense. (Note > that I've called $foo a "field" to distinguish it from a "property", as > C# does: a property with a contract like "$foo { public get; private > set; }" could indeed be abstract.) > > The interesting thing about the above examples is that the static method > with a fixed return *already works right now*, whereas the readonly > field doesn't exist; so it makes some sense to say that "const FOO" is > PHP's way of saying "static readonly $FOO", and have it subject to > similar semantics. > > Regards, > Other languages allow you to have a contract on fields. class A { const FOO: int = 42; } class A { final static $foo: int = 42; } These are basically the same, as you already said. However, I added a contract to both of them. There is one thing that differs for the const and the field: a const value must be known at compile time, whereas a field value does not. An important difference! class A { abstract public const FOO: int; } class A { abstract public function foo(): int; } These also look basically the same. The return value of the method, however, may also be determined at runtime (just like with fields) and on top of that might change with every invocation. As I said, the idea is to have a constant value that is known at compile time. This is the definition of const in PHP. The only thing I was asking for is to split definition and initialization by reusing the abstract keyword. -- Richard "Fleshgrinder" Fussenegger signature.asc Description: OpenPGP digital signature
Re: [PHP-DEV] Constants and Access Modifiers
On 11/12/2017 12:44 AM, Stanislav Malyshev wrote: > Hi! > >> Yes, Dart has a different understanding of const, which is exactly why I >> posted it for you guys. In the hope that it helps to get more different >> views on the topic. Currently you are too concentrated on how it is >> implemented in PHP at this time, and argue that it is impossible to >> diverge from that path. Which is simply not true, we only have to ensure >> backwards compatibility. > > I am not arguing it's impossible, I am arguing it is not a good idea. We > have the concept of constants in this language, and bolting on it a > completely different concept from different language, which by > coincidence was named with the same term, would only be a source of > confusion. If we wanted immutable objects in language - which I am not > convinced at all we do, but assuming for a minute we did - there's no > reason to conflate them with constants as we have them now. These are > different things. > I did not mean to say that we have to have everything exactly as Dart has it. I just wanted to show, that the meaning of const as we have is not universally the same. Abstract constants would also only be truly useful if we could define the type as well on them. Which is currently not possible. Also, I am not saying that the requested feature MUST be done with const. However, it should behave like one, which is impossible with methods. -- Richard "Fleshgrinder" Fussenegger signature.asc Description: OpenPGP digital signature
Re: [PHP-DEV] Constants and Access Modifiers
Hi! > Yes, Dart has a different understanding of const, which is exactly why I > posted it for you guys. In the hope that it helps to get more different > views on the topic. Currently you are too concentrated on how it is > implemented in PHP at this time, and argue that it is impossible to > diverge from that path. Which is simply not true, we only have to ensure > backwards compatibility. I am not arguing it's impossible, I am arguing it is not a good idea. We have the concept of constants in this language, and bolting on it a completely different concept from different language, which by coincidence was named with the same term, would only be a source of confusion. If we wanted immutable objects in language - which I am not convinced at all we do, but assuming for a minute we did - there's no reason to conflate them with constants as we have them now. These are different things. -- Stas Malyshev smalys...@gmail.com -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Constants and Access Modifiers
On 11/11/2017 18:39, Fleshgrinder wrote: On 11/6/2017 1:44 AM, Stanislav Malyshev wrote: From this link, it looks like const in Dart has pretty much nothing in common with const in PHP, besides name, so in the interest of avoiding confusion, I would not discuss it in the same topic. Yes, Dart has a different understanding of const, which is exactly why I posted it for you guys. In the hope that it helps to get more different views on the topic. Currently you are too concentrated on how it is implemented in PHP at this time, and argue that it is impossible to diverge from that path. Which is simply not true, we only have to ensure backwards compatibility. I think the point is that adding "single-assignment variables" (which Dart calls "final") or "deeply immutable values" (which Dart calls "const") would be a completely different feature which could be added side-by-side with what we have now, under a different name. What PHP calls "const" (in the context of classes) is neither of those features. The debate seems to be whether you view class constants as more like static properties, or static methods. Given this: class A { public const Foo = 42; } echo A::Foo; Is it equivalent to this (using an imaginary "readonly" modifier)... class A { public static readonly $foo = 42; } echo A::$foo; ...or is it equivalent to this (particularly if you imagine an optimising compiler that caches / inlines the result)? class A { public static function foo(): int { return 42; } } echo A::foo(); The difference is that a field is never "abstract" - it either has a value, or it is undefined; you can't add a contract to an interface saying "you must have this field" either. A method, on the other hand, is assumed to encapsulate something - it's a black box with a contract, so defining the contract without any implementation makes sense. (Note that I've called $foo a "field" to distinguish it from a "property", as C# does: a property with a contract like "$foo { public get; private set; }" could indeed be abstract.) The interesting thing about the above examples is that the static method with a fixed return *already works right now*, whereas the readonly field doesn't exist; so it makes some sense to say that "const FOO" is PHP's way of saying "static readonly $FOO", and have it subject to similar semantics. Regards, -- Rowan Collins [IMSoP] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Constants and Access Modifiers
On 11/6/2017 1:44 AM, Stanislav Malyshev wrote: > Hi! > >> An abstract constant is a constant that requires its value to be defined >> later, like an abstract method that requires its implementation to be >> defined later. > > It's not a constant then, and should be a method. > No, because a method can change what it returns, it is not constant. On 11/6/2017 1:44 AM, Stanislav Malyshev wrote: >> >> The thing is that I want something that CANNOT CHANGE. I want to require > > You are contradicting yourself. If it is not known upfront, then it can > change - otherwise, you'd know it upfront. I'm not sure what you're > trying to do here, but I am getting pretty sure you shouldn't be doing > it with const's :) > No, I want to split the definition and initialization. The value cannot change, once it is initialized. On 11/6/2017 1:44 AM, Stanislav Malyshev wrote: >> Dropping support for constant inheritance is imho also wrong from a pure >> logical point of view, since a constant's value is only constant if I >> refer to the very same constant. Meaning, the value of a constant in a >> subclass must not be the same value as the value in the superclass. >> >> class Integer extends Number { >> public const MAX = \PHP_INT_MAX; >> public const MIN = \PHP_INT_MIN; >> } >> >> class WholeNumber extends Integer { >> public const MIN = 0; >> } >> >> class NaturalNumber extends WholeNumber { >> public const MIN = 1; >> } > > Integer::MIN and NaturalNumber::MIN are different constants. So, it is > natural that they can have different values. Though using constants with > these names is slightly misleading, but if you always use full name, not > by much. > I do not follow, what is misleading about them? Referencing them without the full name is also not possible in PHP, hence, not an issue. On 11/6/2017 1:44 AM, Stanislav Malyshev wrote: >> does, simply because it is a different value. Of course we expect it to >> be compatible, they are after all in a tight relationship (inheritance). > > Here you are getting into a dangerous territory, btw. Depending on your > modeling needs, of course, but your NaturalNumber can violate contract > of Integer, such as "being able to represent -10". Thus, inheritance > could be wrong way to do it, at least in the way you described above. > One has to be very careful with which exactly contract are you modelling > - inheritance is not just shortcut for avoiding copy-paste. > I am not sure how you deduce that NaturalNumber can be -10. There are not invariants defined anywhere on the classes. You are correct that inheritance should not be misused for code reuse, it should be used to build type systems. Which is exactly what I am doing in the example. On 11/6/2017 1:44 AM, Stanislav Malyshev wrote: >> I mentioned Dart in the initial message, they have a much richer >> understanding of const than we have it in PHP. Maybe this also helps to >> broaden your views on the topic: >> >> https://news.dartlang.org/2012/06/const-static-final-oh-my.html > > From this link, it looks like const in Dart has pretty much nothing in > common with const in PHP, besides name, so in the interest of avoiding > confusion, I would not discuss it in the same topic. > Yes, Dart has a different understanding of const, which is exactly why I posted it for you guys. In the hope that it helps to get more different views on the topic. Currently you are too concentrated on how it is implemented in PHP at this time, and argue that it is impossible to diverge from that path. Which is simply not true, we only have to ensure backwards compatibility. -- Richard "Fleshgrinder" Fussenegger signature.asc Description: OpenPGP digital signature
Re: [PHP-DEV] Constants and Access Modifiers
Hi! > An abstract constant is a constant that requires its value to be defined > later, like an abstract method that requires its implementation to be > defined later. It's not a constant then, and should be a method. > > The thing is that I want something that CANNOT CHANGE. I want to require You are contradicting yourself. If it is not known upfront, then it can change - otherwise, you'd know it upfront. I'm not sure what you're trying to do here, but I am getting pretty sure you shouldn't be doing it with const's :) > Dropping support for constant inheritance is imho also wrong from a pure > logical point of view, since a constant's value is only constant if I > refer to the very same constant. Meaning, the value of a constant in a > subclass must not be the same value as the value in the superclass. > > class Integer extends Number { > public const MAX = \PHP_INT_MAX; > public const MIN = \PHP_INT_MIN; > } > > class WholeNumber extends Integer { > public const MIN = 0; > } > > class NaturalNumber extends WholeNumber { > public const MIN = 1; > } Integer::MIN and NaturalNumber::MIN are different constants. So, it is natural that they can have different values. Though using constants with these names is slightly misleading, but if you always use full name, not by much. > does, simply because it is a different value. Of course we expect it to > be compatible, they are after all in a tight relationship (inheritance). Here you are getting into a dangerous territory, btw. Depending on your modeling needs, of course, but your NaturalNumber can violate contract of Integer, such as "being able to represent -10". Thus, inheritance could be wrong way to do it, at least in the way you described above. One has to be very careful with which exactly contract are you modelling - inheritance is not just shortcut for avoiding copy-paste. > I mentioned Dart in the initial message, they have a much richer > understanding of const than we have it in PHP. Maybe this also helps to > broaden your views on the topic: > > https://news.dartlang.org/2012/06/const-static-final-oh-my.html >From this link, it looks like const in Dart has pretty much nothing in common with const in PHP, besides name, so in the interest of avoiding confusion, I would not discuss it in the same topic. -- Stas Malyshev smalys...@gmail.com -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Constants and Access Modifiers
On 11/5/2017 1:03 PM, Niklas Keller wrote: >> >> Hi! >> >>> My wording was maybe a bit wrong here, and I was biased by the fact that >>> I would like to see abstract constants. The fact that not everything can >> >> What is "abstract constant"? If you need something that can change, just >> use a method. Constant is meant to be a nice way to write something >> inherently constant, such as instead of "/very long >> (and+)cubmber|some?*regexp/" you'd write NICE_REGEXP_CONSTANT. But it's >> not supposed to create parallel inheritance structure or something. If >> it needs to be non-constant, just use a method. >> > > Totally agree with that. We should deprecate constant inheritance instead. > > Regards, Niklas > An abstract constant is a constant that requires its value to be defined later, like an abstract method that requires its implementation to be defined later. The thing is that I want something that CANNOT CHANGE. I want to require that you define the value, a value that is known at compile time, a value that is immutable, a value that can never changes during the program's execution. This is not achievable by current, available means. What you describe is the intention of the current class constant implementation of PHP, and some other languages. Pure logic does not support this claim. The only thing a constant should provide is that its value is known at compile time. That being said, we already violate that by supporting dynamic constant definitions via define, but let's not go down that road here. Dropping support for constant inheritance is imho also wrong from a pure logical point of view, since a constant's value is only constant if I refer to the very same constant. Meaning, the value of a constant in a subclass must not be the same value as the value in the superclass. class Integer extends Number { public const MAX = \PHP_INT_MAX; public const MIN = \PHP_INT_MIN; } class WholeNumber extends Integer { public const MIN = 0; } class NaturalNumber extends WholeNumber { public const MIN = 1; } We expect that `Integer::MIN` always yields the same value, rightly so, since it is a constant. However, nobody expects that `NaturalNumber::MIN` is going to yield the same value as `Integer::MIN` does, simply because it is a different value. Of course we expect it to be compatible, they are after all in a tight relationship (inheritance). They also have to be compatible to each other, otherwise we would violate the substitutability. I mentioned Dart in the initial message, they have a much richer understanding of const than we have it in PHP. Maybe this also helps to broaden your views on the topic: https://news.dartlang.org/2012/06/const-static-final-oh-my.html -- Richard "Fleshgrinder" Fussenegger signature.asc Description: OpenPGP digital signature
Re: [PHP-DEV] Constants and Access Modifiers
> > Hi! > > > My wording was maybe a bit wrong here, and I was biased by the fact that > > I would like to see abstract constants. The fact that not everything can > > What is "abstract constant"? If you need something that can change, just > use a method. Constant is meant to be a nice way to write something > inherently constant, such as instead of "/very long > (and+)cubmber|some?*regexp/" you'd write NICE_REGEXP_CONSTANT. But it's > not supposed to create parallel inheritance structure or something. If > it needs to be non-constant, just use a method. > Totally agree with that. We should deprecate constant inheritance instead. Regards, Niklas
Re: [PHP-DEV] Constants and Access Modifiers
Hi! > My wording was maybe a bit wrong here, and I was biased by the fact that > I would like to see abstract constants. The fact that not everything can What is "abstract constant"? If you need something that can change, just use a method. Constant is meant to be a nice way to write something inherently constant, such as instead of "/very long (and+)cubmber|some?*regexp/" you'd write NICE_REGEXP_CONSTANT. But it's not supposed to create parallel inheritance structure or something. If it needs to be non-constant, just use a method. -- Stas Malyshev smalys...@gmail.com -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Constants and Access Modifiers
On 10/27/2017 11:15 PM, Nikita Popov wrote: > 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 > My wording was maybe a bit wrong here, and I was biased by the fact that I would like to see abstract constants. The fact that not everything can be detected at compile time, but only later at runtime is normal in a highly dynamic language like PHP. Self-referencing constants make no sense, hence, it is fine. It would of course be better if the compiler could detect that earlier, but we are not doing AOT so imho that is fine. The behavior here is also consistent among versions as well as HHVM, all good. What do you think about the other ideas I raised? -- Richard "Fleshgrinder" Fussenegger signature.asc Description: OpenPGP digital signature
Re: [PHP-DEV] Constants and Access Modifiers
On Fri, Oct 27, 2017 at 10:51 PM, Fleshgrinderwrote: > 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 > >
[PHP-DEV] Constants and Access Modifiers
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