Hi,
To anyone who is interested in this RFC. What do you think what behavour we
should have when you try to compare two immutable objects by identity like
this:
immutable class A {
public $a;
public function __construct($a) {
$this->a = $a
}
}
$a1 = new A(1);
$a2 = new A(1);
$a1 === $a2
If we treat those objects as values then this should return true. But then
again there might be some confusion because then two operators are doing
the same thing. Maybe throw an error ? Suggestions ?
Cheers.
Silvio Marijić
Software Engineer
2e Systems
On Wed, Nov 16, 2016 at 6:57 AM, Silvio Marijić marijic.silvio@gmail.com
wrote:
Hi,
To anyone who is interested in this RFC. What do you think what behavour we
should have when you try to compare two immutable objects by identity like
this:immutable class A {
public $a;
public function __construct($a) {
$this->a = $a
}}
$a1 = new A(1);
$a2 = new A(1);
I would personally expect that:
var_dump($a1 === $a2); // bool(false)
var_dump($a1 == $a2); // bool(true)
$a1 === $a2
If we treat those objects as values then this should return true. But then
again there might be some confusion because then two operators are doing
the same thing. Maybe throw an error ? Suggestions ?Cheers.
Silvio Marijić
Software Engineer
2e Systems
@Ryan which is existing behaviour in language. Because object is immutable
I don't think we should care anymore about 'references' instead maybe we
could focus on value that object represents.
2016-11-16 15:29 GMT+01:00 Ryan Pallas derokorian@gmail.com:
On Wed, Nov 16, 2016 at 6:57 AM, Silvio Marijić marijic.silvio@gmail.com
wrote:Hi,
To anyone who is interested in this RFC. What do you think what behavour
we
should have when you try to compare two immutable objects by identity like
this:immutable class A {
public $a;
public function __construct($a) {
$this->a = $a
}}
$a1 = new A(1);
$a2 = new A(1);I would personally expect that:
var_dump($a1 === $a2); // bool(false)
var_dump($a1 == $a2); // bool(true)$a1 === $a2
If we treat those objects as values then this should return true. But then
again there might be some confusion because then two operators are doing
the same thing. Maybe throw an error ? Suggestions ?Cheers.
Silvio Marijić
Software Engineer
2e Systems
--
Silvio Marijić
Software Engineer
2e Systems
Hi Silvio,
I don’t see why this wouldn’t simply return false?
Cheers,
Stephen
Hi,
To anyone who is interested in this RFC. What do you think what behavour we
should have when you try to compare two immutable objects by identity like
this:immutable class A {
public $a;
public function __construct($a) {
$this->a = $a
}}
$a1 = new A(1);
$a2 = new A(1);$a1 === $a2
If we treat those objects as values then this should return true. But then
again there might be some confusion because then two operators are doing
the same thing. Maybe throw an error ? Suggestions ?Cheers.
Silvio Marijić
Software Engineer
2e Systems
Hi Stepehen,
Since immutable objects doesn't have identity, I'm wondering what would be
best to do in this case when we try to compare them by identity.
Cheers
2016-11-16 15:51 GMT+01:00 Stephen Reay php-lists@koalephant.com:
Hi Silvio,
I don’t see why this wouldn’t simply return false?
Cheers,
Stephen
On 16 Nov 2016, at 20:57, Silvio Marijić marijic.silvio@gmail.com
wrote:Hi,
To anyone who is interested in this RFC. What do you think what behavour
we
should have when you try to compare two immutable objects by identity
like
this:immutable class A {
public $a;
public function __construct($a) {
$this->a = $a
}}
$a1 = new A(1);
$a2 = new A(1);$a1 === $a2
If we treat those objects as values then this should return true. But
then
again there might be some confusion because then two operators are doing
the same thing. Maybe throw an error ? Suggestions ?Cheers.
Silvio Marijić
Software Engineer
2e Systems
--
Silvio Marijić
Software Engineer
2e Systems
2016-11-16 11:57 GMT-02:00 Silvio Marijić marijic.silvio@gmail.com:
If we treat those objects as values then this should return true. But then
again there might be some confusion because then two operators are doing
the same thing. Maybe throw an error ? Suggestions ?
I just thinking about "how it will be done"?
I imagine that we should store all calling to memory, then I see two
problems for this case:
-
High memory consumption: all immutable objects should be stored on
memory eternally (or until the script ends). I mean: if I call it a
hundred times with differents parameters, I'll have a hundred of used
memory, that will avoid any used variables of be GC (once that it
should stores it for references). -
High CPU consumption: every time that I instantiate an immutable
class, the engine will loop on each possibilities and check if all
parameters match to then return the same object (or then, create a
new). Then the major question for it is: should all parameters of an
immutable constructor be considered on instantiate? Should I pass the
exactly copy (read "reference") of object to the parameter to return
the same instance or a "shallow copy"?
For both problems above, I guess that a "factory pattern with cache"
should works better, once that I could consider the exact value where
it requires to be immutable, and I could cache only if it is really
required, for instance:
class SomeFactory {
private static $cache = [];
public static function getType(Type $type) {
if (!$type->shouldBeCache()) {
// Code flexibility...
return new self($type);
}
if (!array_key_exists($type->id, self::$cache) {
self::$cache[$type->id] = new self($type);
}
return self::$cache[$type->id];
}
}
--
David Rodrigues
16.11.2016 16:39 "David Rodrigues" david.proweb@gmail.com napisał(a):
2016-11-16 11:57 GMT-02:00 Silvio Marijić marijic.silvio@gmail.com:
If we treat those objects as values then this should return true. But
then
again there might be some confusion because then two operators are doing
the same thing. Maybe throw an error ? Suggestions ?I just thinking about "how it will be done"?
I imagine that we should store all calling to memory, then I see two
problems for this case:
- High memory consumption: all immutable objects should be stored on
memory eternally (or until the script ends). I mean: if I call it a
hundred times with differents parameters, I'll have a hundred of used
memory, that will avoid any used variables of be GC (once that it
should stores it for references).
All instances are GC the same as nornal classes when unneeded any longer.
- High CPU consumption: every time that I instantiate an immutable
class, the engine will loop on each possibilities and check if all
parameters match to then return the same object (or then, create a
new). Then the major question for it is: should all parameters of an
immutable constructor be considered on instantiate? Should I pass the
exactly copy (read "reference") of object to the parameter to return
the same instance or a "shallow copy"?
There is no cache - each immutable objects is created the same as normal
object except it won't let you pass references.
For both problems above, I guess that a "factory pattern with cache"
should works better, once that I could consider the exact value where
it requires to be immutable, and I could cache only if it is really
required, for instance:class SomeFactory {
private static $cache = [];public static function getType(Type $type) { if (!$type->shouldBeCache()) { // Code flexibility... return new self($type); } if (!array_key_exists($type->id, self::$cache) { self::$cache[$type->id] = new self($type); } return self::$cache[$type->id]; }
}
--
David Rodrigues
Hi,
To anyone who is interested in this RFC. What do you think what behavour we
should have when you try to compare two immutable objects by identity like
this:
I don't mean to be overly-nitpicky here, but it strikes me that the issue might not be "immutable object" so much as "value object."
That is, an immutable object (or at least a read-only object) might very well have an identity. But a value object, in addition to read-only or immutable, would have no identity proper.
Maybe using the alternative term (if it applies) would help to clarify the situation.
--
Paul M. Jones
pmjones88@gmail.com
http://paul-m-jones.com
Modernizing Legacy Applications in PHP
https://leanpub.com/mlaphp
Solving the N+1 Problem in PHP
https://leanpub.com/sn1php
@Paul,
I understand that immutable doesn't automatically apply value object. Can
you give us some examples where immutable object should have identity?
Cheers
On Nov 16, 2016, at 07:57, Silvio Marijić marijic.silvio@gmail.com
wrote:Hi,
To anyone who is interested in this RFC. What do you think what behavour
we
should have when you try to compare two immutable objects by identity
like
this:I don't mean to be overly-nitpicky here, but it strikes me that the issue
might not be "immutable object" so much as "value object."That is, an immutable object (or at least a read-only object) might very
well have an identity. But a value object, in addition to read-only or
immutable, would have no identity proper.Maybe using the alternative term (if it applies) would help to clarify the
situation.--
Paul M. Jones
pmjones88@gmail.com
http://paul-m-jones.comModernizing Legacy Applications in PHP
https://leanpub.com/mlaphpSolving the N+1 Problem in PHP
https://leanpub.com/sn1php
I'm not Paul, but...
If you have a data storage system using CRAP (Create Read Archive Purge)
instead of CRUD, or EventSourcing, or any other system that needs to
maintain history, then you need stored objects that have identities
(document abc revision 123, for instance) so you can reference them. In
order to maintain history, however, when you load that data into a
classed object you do NOT want that object to be mutable, because there
is, by design, no way to "update" that object in place in storage.
Rather, you'd want to have a special "new object" class that is mutable,
persist that to storage, and then on load of historical data you want a
read-only object to expose to application code. That object will still
have an identity, however.
I'm actually working on such a library on the side right now.
--Larry Garfield
@Paul,
I understand that immutable doesn't automatically apply value object. Can
you give us some examples where immutable object should have identity?Cheers
On Nov 16, 2016, at 07:57, Silvio Marijić marijic.silvio@gmail.com
wrote:
Hi,To anyone who is interested in this RFC. What do you think what behavour
we
should have when you try to compare two immutable objects by identity
like
this:
I don't mean to be overly-nitpicky here, but it strikes me that the issue
might not be "immutable object" so much as "value object."That is, an immutable object (or at least a read-only object) might very
well have an identity. But a value object, in addition to read-only or
immutable, would have no identity proper.Maybe using the alternative term (if it applies) would help to clarify the
situation.--
Paul M. Jones
pmjones88@gmail.com
http://paul-m-jones.comModernizing Legacy Applications in PHP
https://leanpub.com/mlaphpSolving the N+1 Problem in PHP
https://leanpub.com/sn1php
19.11.2016 19:15 "Larry Garfield" larry@garfieldtech.com napisał(a):
I'm not Paul, but...
If you have a data storage system using CRAP (Create Read Archive Purge)
instead of CRUD, or EventSourcing, or any other system that needs to
maintain history, then you need stored objects that have identities
(document abc revision 123, for instance) so you can reference them. In
order to maintain history, however, when you load that data into a classed
object you do NOT want that object to be mutable, because there is, by
design, no way to "update" that object in place in storage. Rather, you'd
want to have a special "new object" class that is mutable, persist that to
storage, and then on load of historical data you want a read-only object to
expose to application code. That object will still have an identity,
however.
In Event Sourced application Aggregates and Entities are mutable but
pushing Events for later write but speaking of ValueObject which ideally
could be immutable classes there is must on immutability and AFAIK there is
no need for identity for them. Am I right?
I'm actually working on such a library on the side right now.
--Larry Garfield
@Paul,
I understand that immutable doesn't automatically apply value object. Can
you give us some examples where immutable object should have identity?Cheers
On Nov 16, 2016, at 07:57, Silvio Marijić marijic.silvio@gmail.com
wrote:
Hi,
To anyone who is interested in this RFC. What do you think what
behavourwe
should have when you try to compare two immutable objects by identity
like
this:
I don't mean to be overly-nitpicky here, but it strikes me that the
issue
might not be "immutable object" so much as "value object."That is, an immutable object (or at least a read-only object) might very
well have an identity. But a value object, in addition to read-only
or
immutable, would have no identity proper.Maybe using the alternative term (if it applies) would help to clarify
the
situation.--
Paul M. Jones
pmjones88@gmail.com
http://paul-m-jones.comModernizing Legacy Applications in PHP
https://leanpub.com/mlaphpSolving the N+1 Problem in PHP
https://leanpub.com/sn1php
In Event Sourced application Aggregates and Entities are mutable but
pushing Events for later write but speaking of ValueObject which ideally
could be immutable classes there is must on immutability and AFAIK there is
no need for identity for them.
Sure; a Value Object probably needs to be Immutable. But: an Immutable need not be a Value Object.
As such, it sounds to me like your concerns in this thread apply to Value Objects, not Immutables per se.
--
Paul M. Jones
pmjones88@gmail.com
http://paul-m-jones.com
Modernizing Legacy Applications in PHP
https://leanpub.com/mlaphp
Solving the N+1 Problem in PHP
https://leanpub.com/sn1php
@Larry,
I see your point, but when I said 'identity', I was thinking about
referential identity, not wether that object has identity in the user
application.
Cheers
I'm not Paul, but...
If you have a data storage system using CRAP (Create Read Archive Purge)
instead of CRUD, or EventSourcing, or any other system that needs to
maintain history, then you need stored objects that have identities
(document abc revision 123, for instance) so you can reference them. In
order to maintain history, however, when you load that data into a classed
object you do NOT want that object to be mutable, because there is, by
design, no way to "update" that object in place in storage. Rather, you'd
want to have a special "new object" class that is mutable, persist that to
storage, and then on load of historical data you want a read-only object to
expose to application code. That object will still have an identity,
however.I'm actually working on such a library on the side right now.
--Larry Garfield
@Paul,
I understand that immutable doesn't automatically apply value object. Can
you give us some examples where immutable object should have identity?Cheers
On Nov 16, 2016, at 07:57, Silvio Marijić marijic.silvio@gmail.com
wrote:
Hi,
To anyone who is interested in this RFC. What do you think what behavour
we
should have when you try to compare two immutable objects by identity
like
this:
I don't mean to be overly-nitpicky here, but it strikes me that the issue
might not be "immutable object" so much as "value object."That is, an immutable object (or at least a read-only object) might very
well have an identity. But a value object, in addition to read-only or
immutable, would have no identity proper.Maybe using the alternative term (if it applies) would help to clarify
the
situation.--
Paul M. Jones
pmjones88@gmail.com
http://paul-m-jones.comModernizing Legacy Applications in PHP
https://leanpub.com/mlaphpSolving the N+1 Problem in PHP
https://leanpub.com/sn1php
Reading through the RFC and the replies, I'm confused about this question.
Why would the comparison operators work any differently on immutable
objects?
If these were value objects, the question would make sense, but it doesn't
sound like that's what you're proposing?
With regards to the feature itself, I frankly don't feel like it makes any
sense. I disagree with the entire premise of the RFC.
Currently PHP lacks native support for immutability.
No, it doesn't. You show several examples of immutable classes in the RFC,
then demonstrate a slightly more abbreviated syntax to accomplish the same
thing.
Because of that user-land applications are using third party libraries or
resort to custom implementations and still there is no easy enforcement of
immutability.
Really? There are third-party libraries for immutable classes? .... Why?
It's true that there is no way for a class, internally, to enforce
immutability on itself - but why would you need to do that? You're writing
the class. If you want immutable state inside your class, simply don't
change the state.
Why would you need the language to enforce rules that you can already
enforce with the language?
Introducing this feature would help bring one unified solution to this
problem, and also it would remove unnecessary logic from user-land
applications.
What is this unnecessary logic you're referring to? Get-methods generally
do not contain logic. There is no more or less logic in the examples you
show in your before/after code samples.
Perhaps you mean boilerplate? So yes, this feature removes a little bit of
boilerplate. Writing immutable classes becomes a little less ceremonious.
I think that the problem of writing get-methods is exaggerated and somewhat
contrived.
This feature doesn't enable you to do something you couldn't do before - it
obviates the need to write get-methods, but that's basically all, and I'm
not even convinced that's a good thing.
Public properties, in practice, are almost never used in PHP code. You very
rarely see anybody use them, because they're not generally safe, e.g.
permits client code to inject values of the wrong type, etc.
What you're proposing will make public properties the default for immutable
objects.
This will lead to inconsistencies - for example:
immutable class Name {
public $first;
public $last;
public function getFullName() {
return "{$this->first} {$this->last}";
}
}
This will get confusing quickly - you will have to learn or memorize which
attributes of your model are available as properties or methods, e.g.
$name->first is pretty far removed from $name->getFullName() both in terms
of syntax and style.
I think this will become quite confusing in practice, as nobody currently
expects or looks for public properties.
Also, having to refactor from a get-method to a public property, or
vice-versa, becomes a chore that causes a breaking change.
The term 'immutable", especially for the property-annotation, doesn't
strictly seem correct to me either, as for example, I can annotate a public
property as immutable, but if I put an object in there, that object is not
necessarily immutable. The correct term for this feature, especially for
properties, I would think is "readonly" - which would be consistent with
the description of certain existing properties in PHP APIs, such as
PDOStatement::$queryString, as well as with other languages such as C#.
Either way, this feature proposes to introduce "asynchronous" properties as
a new concept in PHP, where properties are generally "synchronous", in the
sense that they can always be read and written. Other languages that
support asynchronous properties (C#, Objective-C, Dart, probably many
others) typically leverage that concept for more than just simple
immutability - the concept of properties that behave differently when you
attempt to read and write is not typically a mere annotation/directive
instructing the compiler to enforce a rule, it's typically made possible
via support for accessors.
This might limit future options for the language, perhaps depending on how
it's implemented.
I hope it doesn't mean we can't have accessors at some point, in the
distant future.
In my opinion, all of these things go hand-in-hand: accessors, read-only,
property type-hints, as these are all essentially about defining and
enforcing constraints and making assertions about the state of a model.
I feel that this feature is a poor substitute for accessors, for example,
because this feature really applies only to immutable models - whereas a
feature such as accessors could be used equally to create immutable models,
but would permit us to move away from get/set-methods entirely, e.g. would
allow to write models with more consistent APIs, for example something like:
class Name {
public readonly $first;
public readonly $last;
public $full_name {
get { return "{$this->first} {$this->last}"; }
}
}
Something like that makes for more consistent client code, e.g.
$name->first and $name->full_name, etc.
I'd like to see us adding features that work everywhere, for many
use-cases, mutable and immutable - introducing a language feature that
works only for immutable objects just feels to exotic to me, in a language
that is mutable by default.
I'd prefer to see features with broader applications.
On Wed, Nov 16, 2016 at 2:57 PM, Silvio Marijić marijic.silvio@gmail.com
wrote:
Hi,
To anyone who is interested in this RFC. What do you think what behavour we
should have when you try to compare two immutable objects by identity like
this:immutable class A {
public $a;
public function __construct($a) {
$this->a = $a
}}
$a1 = new A(1);
$a2 = new A(1);$a1 === $a2
If we treat those objects as values then this should return true. But then
again there might be some confusion because then two operators are doing
the same thing. Maybe throw an error ? Suggestions ?Cheers.
Silvio Marijić
Software Engineer
2e Systems
Reading through the RFC and the replies, I'm confused about this question.
Why would the comparison operators work any differently on immutable
objects?If these were value objects, the question would make sense, but it doesn't
sound like that's what you're proposing?With regards to the feature itself, I frankly don't feel like it makes any
sense. I disagree with the entire premise of the RFC.Currently PHP lacks native support for immutability.
No, it doesn't. You show several examples of immutable classes in the RFC,
then demonstrate a slightly more abbreviated syntax to accomplish the same
thing.Because of that user-land applications are using third party libraries or
resort to custom implementations and still there is no easy enforcement of
immutability.Really? There are third-party libraries for immutable classes? .... Why?
It's true that there is no way for a class, internally, to enforce
immutability on itself - but why would you need to do that? You're writing
the class. If you want immutable state inside your class, simply don't
change the state.Why would you need the language to enforce rules that you can already
enforce with the language?
The two main reasons I can think of are: I want the language to help me
(ie: sometime we make mistakes) & I want classes implementing that
interface to be immutable (eg: PSR7)Introducing this feature would help bring one unified solution to this
problem, and also it would remove unnecessary logic from user-land
applications.What is this unnecessary logic you're referring to? Get-methods generally
do not contain logic. There is no more or less logic in the examples you
show in your before/after code samples.Perhaps you mean boilerplate? So yes, this feature removes a little bit of
boilerplate. Writing immutable classes becomes a little less ceremonious.I think that the problem of writing get-methods is exaggerated and somewhat
contrived.This feature doesn't enable you to do something you couldn't do before - it
obviates the need to write get-methods, but that's basically all, and I'm
not even convinced that's a good thing.Public properties, in practice, are almost never used in PHP code. You very
rarely see anybody use them, because they're not generally safe, e.g.
permits client code to inject values of the wrong type, etc.What you're proposing will make public properties the default for immutable
objects.This will lead to inconsistencies - for example:
immutable class Name {
public $first;
public $last;
public function getFullName() {
return "{$this->first} {$this->last}";
}
}This will get confusing quickly - you will have to learn or memorize which
attributes of your model are available as properties or methods, e.g.
$name->first is pretty far removed from $name->getFullName() both in terms
of syntax and style.I think this will become quite confusing in practice, as nobody currently
expects or looks for public properties.Also, having to refactor from a get-method to a public property, or
vice-versa, becomes a chore that causes a breaking change.
you don't have to move from getters to public properties. It's not
needed as a "security" point a view, but I think most will still use
getter to access the object values. It's especially true if you are
implementing interfaces (or immutable interfaces). from the rfc :
"Notice in above examples removing getters and setting properties to
public is optional. They simply doesn't need to be protected anymore in
fact that immutable class objects are deeply frozen with eceptions on
write."The term 'immutable", especially for the property-annotation, doesn't
strictly seem correct to me either, as for example, I can annotate a public
property as immutable, but if I put an object in there, that object is not
necessarily immutable. The correct term for this feature, especially for
properties, I would think is "readonly" - which would be consistent with
the description of certain existing properties in PHP APIs, such as
PDOStatement::$queryString, as well as with other languages such as C#.
I'm not sure about that one because I can't find it explicitly in the
rfc (maybe it need to be added ?) but I think immutable properties only
accept immutable scalar or objects. otherwise you're right, it would not
be immutableEither way, this feature proposes to introduce "asynchronous" properties as
a new concept in PHP, where properties are generally "synchronous", in the
sense that they can always be read and written. Other languages that
support asynchronous properties (C#, Objective-C, Dart, probably many
others) typically leverage that concept for more than just simple
immutability - the concept of properties that behave differently when you
attempt to read and write is not typically a mere annotation/directive
instructing the compiler to enforce a rule, it's typically made possible
via support for accessors.This might limit future options for the language, perhaps depending on how
it's implemented.I hope it doesn't mean we can't have accessors at some point, in the
distant future.In my opinion, all of these things go hand-in-hand: accessors, read-only,
property type-hints, as these are all essentially about defining and
enforcing constraints and making assertions about the state of a model.I feel that this feature is a poor substitute for accessors, for example,
because this feature really applies only to immutable models - whereas a
feature such as accessors could be used equally to create immutable models,
but would permit us to move away from get/set-methods entirely, e.g. would
allow to write models with more consistent APIs, for example something like:class Name {
public readonly $first;
public readonly $last;
public $full_name {
get { return "{$this->first} {$this->last}"; }
}
}Something like that makes for more consistent client code, e.g.
$name->first and $name->full_name, etc.I'd like to see us adding features that work everywhere, for many
use-cases, mutable and immutable - introducing a language feature that
works only for immutable objects just feels to exotic to me, in a language
that is mutable by default.I'd prefer to see features with broader applications.
On Wed, Nov 16, 2016 at 2:57 PM, Silvio Marijić marijic.silvio@gmail.com
wrote:Hi,
To anyone who is interested in this RFC. What do you think what behavour we
should have when you try to compare two immutable objects by identity like
this:immutable class A {
public $a;
public function __construct($a) {
$this->a = $a
}}
$a1 = new A(1);
$a2 = new A(1);$a1 === $a2
If we treat those objects as values then this should return true. But then
again there might be some confusion because then two operators are doing
the same thing. Maybe throw an error ? Suggestions ?Cheers.
Silvio Marijić
Software Engineer
2e Systems
@Rasmus
We are not changing behaviour of operators since we are not dealing here
just with Value Objects.
It's not even a question that matter of this RFC can be achieved with
encapsulation. Already there are couple of features that got passed, which
also could be achieved without 'syntax' sugar, so I don't think that is a
valid argument, but I'm not going to into any of that, since it would not
result in any constructive argument.
I do have to apologize for still incomplete RFC. Your question regarding if
you declare property immutable and put 'non' immutable object there has
been addressed from beginning.
And also regarding getters, I really see them as a neccesary evil, the more
internal state you expose, the more you have to test since that's you
contract to the rest of application and etc.
Cheers,
Silvio.
2016-11-21 9:46 GMT+01:00 Mathieu Rochette mathieu@rochette.cc:
Reading through the RFC and the replies, I'm confused about this question.
Why would the comparison operators work any differently on immutable
objects?If these were value objects, the question would make sense, but it doesn't
sound like that's what you're proposing?With regards to the feature itself, I frankly don't feel like it makes any
sense. I disagree with the entire premise of the RFC.Currently PHP lacks native support for immutability.
No, it doesn't. You show several examples of immutable classes in the RFC,
then demonstrate a slightly more abbreviated syntax to accomplish the same
thing.Because of that user-land applications are using third party libraries or
resort to custom implementations and still there is no easy enforcement of
immutability.Really? There are third-party libraries for immutable classes? .... Why?
It's true that there is no way for a class, internally, to enforce
immutability on itself - but why would you need to do that? You're writing
the class. If you want immutable state inside your class, simply don't
change the state.Why would you need the language to enforce rules that you can already
enforce with the language?The two main reasons I can think of are: I want the language to help me
(ie: sometime we make mistakes) & I want classes implementing that
interface to be immutable (eg: PSR7)Introducing this feature would help bring one unified solution to this
problem, and also it would remove unnecessary logic from user-land
applications.What is this unnecessary logic you're referring to? Get-methods generally
do not contain logic. There is no more or less logic in the examples you
show in your before/after code samples.Perhaps you mean boilerplate? So yes, this feature removes a little bit of
boilerplate. Writing immutable classes becomes a little less ceremonious.I think that the problem of writing get-methods is exaggerated and
somewhat
contrived.This feature doesn't enable you to do something you couldn't do before -
it
obviates the need to write get-methods, but that's basically all, and I'm
not even convinced that's a good thing.Public properties, in practice, are almost never used in PHP code. You
very
rarely see anybody use them, because they're not generally safe, e.g.
permits client code to inject values of the wrong type, etc.What you're proposing will make public properties the default for
immutable
objects.This will lead to inconsistencies - for example:
immutable class Name {
public $first;
public $last;
public function getFullName() {
return "{$this->first} {$this->last}";
}
}This will get confusing quickly - you will have to learn or memorize which
attributes of your model are available as properties or methods, e.g.
$name->first is pretty far removed from $name->getFullName() both in terms
of syntax and style.I think this will become quite confusing in practice, as nobody currently
expects or looks for public properties.Also, having to refactor from a get-method to a public property, or
vice-versa, becomes a chore that causes a breaking change.you don't have to move from getters to public properties. It's not needed
as a "security" point a view, but I think most will still use getter to
access the object values. It's especially true if you are implementing
interfaces (or immutable interfaces). from the rfc : "Notice in above
examples removing getters and setting properties to public is optional.
They simply doesn't need to be protected anymore in fact that immutable
class objects are deeply frozen with eceptions on write."The term 'immutable", especially for the property-annotation, doesn't
strictly seem correct to me either, as for example, I can annotate a
public
property as immutable, but if I put an object in there, that object is not
necessarily immutable. The correct term for this feature, especially for
properties, I would think is "readonly" - which would be consistent with
the description of certain existing properties in PHP APIs, such as
PDOStatement::$queryString, as well as with other languages such as C#.I'm not sure about that one because I can't find it explicitly in the rfc
(maybe it need to be added ?) but I think immutable properties only accept
immutable scalar or objects. otherwise you're right, it would not be
immutableEither way, this feature proposes to introduce "asynchronous" properties
as
a new concept in PHP, where properties are generally "synchronous", in the
sense that they can always be read and written. Other languages that
support asynchronous properties (C#, Objective-C, Dart, probably many
others) typically leverage that concept for more than just simple
immutability - the concept of properties that behave differently when you
attempt to read and write is not typically a mere annotation/directive
instructing the compiler to enforce a rule, it's typically made possible
via support for accessors.This might limit future options for the language, perhaps depending on how
it's implemented.I hope it doesn't mean we can't have accessors at some point, in the
distant future.In my opinion, all of these things go hand-in-hand: accessors, read-only,
property type-hints, as these are all essentially about defining and
enforcing constraints and making assertions about the state of a model.I feel that this feature is a poor substitute for accessors, for example,
because this feature really applies only to immutable models - whereas a
feature such as accessors could be used equally to create immutable
models,
but would permit us to move away from get/set-methods entirely, e.g. would
allow to write models with more consistent APIs, for example something
like:class Name {
public readonly $first;
public readonly $last;
public $full_name {
get { return "{$this->first} {$this->last}"; }
}
}Something like that makes for more consistent client code, e.g.
$name->first and $name->full_name, etc.I'd like to see us adding features that work everywhere, for many
use-cases, mutable and immutable - introducing a language feature that
works only for immutable objects just feels to exotic to me, in a language
that is mutable by default.I'd prefer to see features with broader applications.
On Wed, Nov 16, 2016 at 2:57 PM, Silvio Marijić <marijic.silvio@gmail.com
wrote:
Hi,
To anyone who is interested in this RFC. What do you think what behavour
we
should have when you try to compare two immutable objects by identity
like
this:immutable class A {
public $a;
public function __construct($a) {
$this->a = $a
}}
$a1 = new A(1);
$a2 = new A(1);$a1 === $a2
If we treat those objects as values then this should return true. But
then
again there might be some confusion because then two operators are doing
the same thing. Maybe throw an error ? Suggestions ?Cheers.
Silvio Marijić
Software Engineer
2e Systems--
--
Silvio Marijić
Software Engineer
2e Systems
The term 'immutable", especially for the property-annotation, doesn't
strictly seem correct to me either, as for example, I can annotate a
public
property as immutable, but if I put an object in there, that object is
not
necessarily immutable. The correct term for this feature, especially for
properties, I would think is "readonly" - which would be consistent with
the description of certain existing properties in PHP APIs, such as
PDOStatement::$queryString, as well as with other languages such as C#.
I'm not sure about that one because I can't find it explicitly in the
rfc (maybe it need to be added ?) but I think immutable properties only
accept immutable scalar or objects. otherwise you're right, it would not
be immutable
The RFC is yet another attempt to add rules to areas of PHP without
getting back to the very basic ... variables are the base element that
in an ideal world would have a full set of properties. type, range/enum,
size, read-only and the like. A sub set of properties on an object may
need to be read-only and if that includes the values returned by the
methods of the object then the object itself becomes read-only. Current
options for doing this include things like 'getters' and 'setters' and
other standards applied in user land including PHP-FIG, but there still
seems not incentive to address the basic building block and make it work
the same way for everybody whether simply validating raw data, or
protecting fields that have rules preventing updating.
--
Lester Caine - G8HFL
Contact - http://lsces.co.uk/wiki/?page=contact
L.S.Caine Electronic Services - http://lsces.co.uk
EnquirySolve - http://enquirysolve.com/
Model Engineers Digital Workshop - http://medw.co.uk
Rainbow Digital Media - http://rainbowdigitalmedia.co.uk