Constants and Access Modifiers

  100972
October 27, 2017 20:51 Fleshgrinder <php@fleshgrinder.com>
--r2IdpcPpMMPTlRklTWBNrAVTt1oAdF6lE
Content-Type: text/plain; charset=utf-8
Content-Language: en-US
Content-Transfer-Encoding: quoted-printable

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. --=20 Richard "Fleshgrinder" Fussenegger --r2IdpcPpMMPTlRklTWBNrAVTt1oAdF6lE--
  100974
October 27, 2017 21:15 nikita.ppv@gmail.com (Nikita Popov)
On Fri, Oct 27, 2017 at 10:51 PM, Fleshgrinder <php@fleshgrinder.com> wrote:

> 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 > >
  100975
October 28, 2017 07:56 Fleshgrinder <php@fleshgrinder.com>
--DnGB6uVdtim6Ua1jjLpu9rLTK6tR1R6ES
Content-Type: text/plain; charset=utf-8
Content-Language: en-US
Content-Transfer-Encoding: quoted-printable

On 10/27/2017 11:15 PM, Nikita Popov wrote:
> PHP does not permit self-referencing constants. >=20 > However, this is only checked when the constant is first accessed. In y= our
> first example the constant is never accessed, so no error is thrown. Th= is
> has nothing to do with subclasses defining the value -- you're using la= te
> static binding, so you're accessing the constant of the child class > directly. >=20 > PHP cannot detect self-referencing constants during compilation, becaus= e
> they may be formed through non-trivial cycles involving multiple consta= nts,
> across multiple files. >=20 > Nikita >=20
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? --=20 Richard "Fleshgrinder" Fussenegger --DnGB6uVdtim6Ua1jjLpu9rLTK6tR1R6ES--
  101059
November 5, 2017 00:21 smalyshev@gmail.com (Stanislav Malyshev)
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 smalyshev@gmail.com
  101062
November 5, 2017 12:03 me@kelunik.com (Niklas Keller)
> > 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
  101067
November 5, 2017 21:49 Fleshgrinder <php@fleshgrinder.com>
--wBxN4r3ihru9XjIxu1EWnC7ErTBgWO1Tw
Content-Type: text/plain; charset=utf-8
Content-Language: en-US
Content-Transfer-Encoding: quoted-printable

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 t= hat
>>> I would like to see abstract constants. The fact that not everything = can
>> >> What is "abstract constant"? If you need something that can change, ju= st
>> 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. >> >=20 > Totally agree with that. We should deprecate constant inheritance inste= ad.
>=20 > Regards, Niklas >=20
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 =3D \PHP_INT_MAX; public const MIN =3D \PHP_INT_MIN; } class WholeNumber extends Integer { public const MIN =3D 0; } class NaturalNumber extends WholeNumber { public const MIN =3D 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 --=20 Richard "Fleshgrinder" Fussenegger --wBxN4r3ihru9XjIxu1EWnC7ErTBgWO1Tw--
  101068
November 6, 2017 00:44 smalyshev@gmail.com (Stanislav Malyshev)
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 smalyshev@gmail.com
  101122
November 11, 2017 18:39 Fleshgrinder <php@fleshgrinder.com>
--qhDojdx5DCdWEmT9ak4VO3QQ4Ud9uMIDL
Content-Type: text/plain; charset=utf-8
Content-Language: en-US
Content-Transfer-Encoding: quoted-printable

On 11/6/2017 1:44 AM, Stanislav Malyshev wrote:
> Hi! >=20 >> An abstract constant is a constant that requires its value to be defin= ed
>> later, like an abstract method that requires its implementation to be >> defined later. >=20 > It's not a constant then, and should be a method. >=20
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 requi= re
>=20 > 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 :) >=20
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 pu= re
>> 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 =3D \PHP_INT_MAX; >> public const MIN =3D \PHP_INT_MIN; >> } >> >> class WholeNumber extends Integer { >> public const MIN =3D 0; >> } >> >> class NaturalNumber extends WholeNumber { >> public const MIN =3D 1; >> } >=20 > Integer::MIN and NaturalNumber::MIN are different constants. So, it is > natural that they can have different values. Though using constants wit= h
> these names is slightly misleading, but if you always use full name, no= t
> by much. >=20
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 t= o
>> be compatible, they are after all in a tight relationship (inheritance= ).
>=20 > 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 modellin= g
> - inheritance is not just shortcut for avoiding copy-paste. >=20
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 t= o
>> broaden your views on the topic: >> >> https://news.dartlang.org/2012/06/const-static-final-oh-my.html >=20 > 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. >=20
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. --=20 Richard "Fleshgrinder" Fussenegger --qhDojdx5DCdWEmT9ak4VO3QQ4Ud9uMIDL--
  101123
November 11, 2017 20:51 rowan.collins@gmail.com (Rowan Collins)
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]
  101127
November 12, 2017 09:49 Fleshgrinder <php@fleshgrinder.com>
--oUpqNtkF3Qo0MlWlmRlF3wKtLdtJVcdjf
Content-Type: text/plain; charset=utf-8
Content-Language: en-US
Content-Transfer-Encoding: quoted-printable

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: >> >>> =C2=A0From this link, it looks like const in Dart has pretty much not= hing in
>>> common with const in PHP, besides name, so in the interest of avoidin= g
>>> 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 differen= t
>> 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 ensu= re
>> backwards compatibility. >=20 > 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.=
>=20
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: >=20 > class A { public const Foo =3D 42; } > echo A::Foo; >=20 > Is it equivalent to this (using an imaginary "readonly" modifier)... >=20 > class A { public static readonly $foo =3D 42; } > echo A::$foo; >=20 > ...or is it equivalent to this (particularly if you imagine an > optimising compiler that caches / inlines the result)? >=20 > class A { public static function foo(): int { return 42; } } > echo A::foo(); >=20 >=20 > 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.) >=20 > The interesting thing about the above examples is that the static metho= d
> 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. >=20 > Regards, >=20
Other languages allow you to have a contract on fields. class A { const FOO: int =3D 42; } class A { final static $foo: int =3D 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. --=20 Richard "Fleshgrinder" Fussenegger --oUpqNtkF3Qo0MlWlmRlF3wKtLdtJVcdjf--
  101130
November 12, 2017 18:25 rowan.collins@gmail.com (Rowan Collins)
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]
  101131
November 12, 2017 19:00 lists@rhsoft.net ("lists@rhsoft.net")
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
  101132
November 12, 2017 19:44 Fleshgrinder <php@fleshgrinder.com>
--IPj8ULwD3cWuvKAx0H4ET6p5mG59DeE01
Content-Type: text/plain; charset=utf-8
Content-Language: en-US
Content-Transfer-Encoding: quoted-printable

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. >> >> =C2=A0=C2=A0=C2=A0=C2=A0 class A { const FOO: int =3D 42; } >> =C2=A0=C2=A0=C2=A0=C2=A0 class A { final static $foo: int =3D 42; } >> >> These are basically the same, as you already said. However, I added a >> contract to both of them. >=20 > Yes, I wondered whether to mention type constraints; certainly the > previous, stalled, proposal would have added them directly on what I wa= s
> 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. >=20 > Consider "int $foo { public get; private set; }" as defining the follow= ing:
>=20 > - a field which like any other variable could theoretically have any > value, but which will never be accessed except via the property definit= ion
> - a getter method with the signature "function(): int" > - a setter method with the signature "function(int $foo): void" >=20 > It immediately makes sense why you can't assign by reference (the sette= r
> 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). >=20 > You could then also have syntax for a property with a compile-time valu= e
> and no setter, but I'm not sure whether this meets your requirements. >=20
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! >> >> =C2=A0=C2=A0=C2=A0=C2=A0 class A { abstract public const FOO: int; } >> =C2=A0=C2=A0=C2=A0=C2=A0 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. >=20 > 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? >=20
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 =3D self::X + self::Y; } final class B extends A { const X =3D 1; const Y =3D 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? >=20 > 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; } = }
>=20 > Regards, >=20
Pure functions in general would be an awesome thing in PHP, as they also allow for many optimizations. --=20 Richard "Fleshgrinder" Fussenegger --IPj8ULwD3cWuvKAx0H4ET6p5mG59DeE01--
  101124
November 11, 2017 23:44 smalyshev@gmail.com (Stanislav Malyshev)
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 smalyshev@gmail.com
  101125
November 12, 2017 09:32 Fleshgrinder <php@fleshgrinder.com>
--NAMsLe2H6bvNSS1g79U7Oq2V3tEne75If
Content-Type: text/plain; charset=utf-8
Content-Language: en-US
Content-Transfer-Encoding: quoted-printable

On 11/12/2017 12:44 AM, Stanislav Malyshev wrote:
> Hi! >=20 >> 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 differen= t
>> 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 ensu= re
>> backwards compatibility. >=20 > I am not arguing it's impossible, I am arguing it is not a good idea. W= e
> 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. >=20
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. --=20 Richard "Fleshgrinder" Fussenegger --NAMsLe2H6bvNSS1g79U7Oq2V3tEne75If--
  101126
November 12, 2017 09:38 TonyMarston@hotmail.com ("Tony Marston")
wrote in message 
news:549c4634-ac38-41d3-ab43-f816a9f2b1e5@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. -- Tony Marston
  101128
November 12, 2017 09:50 alice@librelamp.com (Alice Wonder)
On 11/12/2017 01:38 AM, Tony Marston wrote:
> wrote in message > news:549c4634-ac38-41d3-ab43-f816a9f2b1e5@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.
  101129
November 12, 2017 10:10 lists@rhsoft.net ("lists@rhsoft.net")
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