Re: [RFC][DISCUSSION] - Immutable classes and properties
| From: | Silvio Marijić | Date: | Mon, 12 Dec 2016 09:11:17 +0000 |
| Subject: | Re: [RFC][DISCUSSION] - Immutable classes and properties | ||
| References: | 1 2 3 4 5 6 7 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-97364@lists.php.net to get a copy of this message | ||
@Davey,
There was similar suggestion that $this represents clone of the object. I
think that is a bit vague, and I'am not sure about the 'scope' you refer to
because 'double scoping' could be also a reason to downvote this rfc and it
can lead to confusion in my opinion. I will check HHVM also.
Regarding my proposal above, since copy() would essentially operate only on
immutable objects, why not put it only there. So you would be able to make
a call like this one $immutable->copy(array $args); or $this->copy(array
$args); depending on whether you are inside let's say with* method or
outside of the object.
2016-12-12 6:58 GMT+01:00 Davey Shafik <davey@php.net>:
> On Sun, Dec 11, 2016 at 7:40 PM, Mathieu Rochette <mathieu@texthtml.net>
> wrote:
>
>>
>>
>> On 12/12/2016 01:16 AM, Silvio Marijić wrote:
>> > This have occurred to me also, I wanted to separate that into two RFC's,
>> > but then how we deal with RFC's that depend on each other?
>> well that's just my opinion but I don't think they depend on each other,
>> this rfc seems useful on its own. The "clone" one might depends on this
>> one but it does not *need* to either (otoh it certainly would be much
>> more useful with immutable classes than mutable classes)
>>
>> plus, this part might already trigger enough discussion and adding
>> everything at once might get confusion. I can think of : clone, late
>> initialization, DateTimeImmutable and probably other subjects that could
>> make the discussion noisy
>>
>> I'm not as familiar as you are with this mailing list so I might very
>> well be wrong too ^^
>> >
>> > 2016-12-12 1:03 GMT+01:00 Larry Garfield <larry@garfieldtech.com>:
>> >
>> >> Assuming this was intended for the list...
>> it was, thank you
>> >>
>> >> On 12/11/2016 05:55 PM, Mathieu Rochette wrote:
>> >>
>> >>> Currently the only "unlocked context" for an object is its
>> >>> constructor. As discussed previously, that is insufficient. For any
>> >>> non-trivial object (more than 1-3 internal properties) creating a new
>> >>> one via the constructor only when incrementally building is
>> >>> prohibitively difficult. The pattern of with*() methods that spawn
>> >>> new objects via clone(), a la PSR-7, needs to be supported. That is:
>> >>>
>> >>> immutable class Money {
>> >>> // ...
>> >>>
>> >>> public function add(Money $other) : Money {
>> >>> $new = clone($this);
>> >>> $new->amount += $other->amount;
>> >>> return $new;
>> >>> }
>> >>> }
>> >>>
>> >>> I'm not sure how easily we can denote that sort of case. It's
>> >>> outside
>> >>> the __clone() function itself, which is what makes it difficult.
>> >>> Without that, though, such immutable objects are of only limited use..
>> >>>
>> >>
>> >>
>> >>> As you said, it has been already been discussed that a method to build
>> >>> new altered object from an existing one could be improved. Different
>> >>> options were proposed but maybe it's better to start small to get this
>> >>> first part right and add this in another rfc ? having everything at
>> the
>> >>> same time might makes the rfc more difficult to be accepted
>> >>>
>> >> On the contrary, an RFC that doesn't fully solve the issue at hand and
>> >> leaves major gaps in place is a poor RFC, and I would expect to be
>> >> justifiably voted down.
>>
>
> I wonder if we can essentially make all public methods act like they are
> static (no access to $this) and then use something like:
>
> immutable class Foo {
> protected $bar;
> public function getBar() with (Foo $instance): string // $instance is
> a clone of $this
> {
> // context == $instance, so access to private/protected
> return $instance->bar;
> }
>
> public function withBar($bar) with (Foo $instance): Foo
> {
> $instance->bar = $bar; // Allowed as we're in scope
> return $instance;
> }
> }
>
> Only operations in the scope of the class itself (and it's descendants,
> adhering to standard visibility rules) can make changes on the cloned
> variant. The
with ($instance) is optional, $instance is just a
> variable
> name. In reality you'll want to use it most of the time I imagine.
>
> I suppose you can re-use the use keyword here too.
>
> Also, this shouldn't allow for immutable properties.
>
> Another option is to look at the way that HHVM does immutable types,
> though that is _file_ based.
>
> - Davey
>
>
>
--
Silvio Marijić
Software Engineer
2e Systems