Fleshgrinder
[PHP-DEV] Constants and Access Modifiers
October 27, 2017 11:00PM
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
Nikita Popov
Re: [PHP-DEV] Constants and Access Modifiers
October 27, 2017 11:20PM
On Fri, Oct 27, 2017 at 10:51 PM, Fleshgrinder <[email protected]> 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
>
>
Fleshgrinder
Re: [PHP-DEV] Constants and Access Modifiers
October 28, 2017 10:00AM
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
Stanislav Malyshev
Re: [PHP-DEV] Constants and Access Modifiers
November 05, 2017 01:30AM
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

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Niklas Keller
Re: [PHP-DEV] Constants and Access Modifiers
November 05, 2017 01:10PM
>
> 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
Fleshgrinder
Re: [PHP-DEV] Constants and Access Modifiers
November 05, 2017 11:00PM
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
Stanislav Malyshev
Re: [PHP-DEV] Constants and Access Modifiers
November 06, 2017 01:50AM
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

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Fleshgrinder
Re: [PHP-DEV] Constants and Access Modifiers
November 11, 2017 07:50PM
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
Rowan Collins
Re: [PHP-DEV] Constants and Access Modifiers
November 11, 2017 10:00PM
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
Stanislav Malyshev
Re: [PHP-DEV] Constants and Access Modifiers
November 12, 2017 12:50AM
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

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Fleshgrinder
Re: [PHP-DEV] Constants and Access Modifiers
November 12, 2017 10:40AM
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
Tony Marston
Re: [PHP-DEV] Constants and Access Modifiers
November 12, 2017 10:40AM
wrote in message
news:[email protected]
>
>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


--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Fleshgrinder
Re: [PHP-DEV] Constants and Access Modifiers
November 12, 2017 11:00AM
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
Alice Wonder
Re: [PHP-DEV] Constants and Access Modifiers
November 12, 2017 11:00AM
On 11/12/2017 01:38 AM, Tony Marston wrote:
> wrote in message
> news:[email protected]
>>
>> 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
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
Rowan Collins
Re: [PHP-DEV] Constants and Access Modifiers
November 12, 2017 07:30PM
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
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
Fleshgrinder
Re: [PHP-DEV] Constants and Access Modifiers
November 12, 2017 08:50PM
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
Sorry, only registered users may post in this forum.

Click here to login