Re: [RFC] Immutable variables and objects

From: Date: Sun, 01 Feb 2015 02:56:22 +0000
Subject: Re: [RFC] Immutable variables and objects
References: 1 2 3 4 5 6  Groups: php.internals 
Request: Send a blank email to [email protected] to get a copy of this message
Hi,

> On 1 Feb 2015, at 02:09, Stanislav Malyshev <[email protected]> wrote:
> 
>> Here, there’s no redundant objects made, but if you pass $a on, it’d
>> be automatically copied by PHP, so you don’t need to worry about it
>> being modified.
> 
> I don't think it's a particularly good solution in this case, as in many
> cases (especially DI setups, many design patterns, etc.) the whole point
> of creating the object is to pass it around. Just pointlessly copying it
> out of fear somebody somewhere could modify it doesn't sound the best
> way.

Well, that’s the advantage of copy-on-write: you can avoid needless manual copies, and instead
have automatic copying done for you by the language, where needed.

Although implementing copy-on-write for object methods might be a challenge, give PHP doesn’t
track which functions have side effects.

> I'd rather just have a clear separation between mutating and
> non-mutating APIs, and instruct people to use the right ones in right
> situation - i.e. if you created the object or own it, use mutating ones,
> if you got object from outside and do not have full ownership of it, use
> non-mutating ones.
> 

This isn’t very nice in practice, though. Mutating APIs are easy to use and performant,
non-mutating APIs are neither of these things. What you want is the benefits of the first without
the disadvantages of the second.

>> Would that make sense? It’s no different than how our existing value
>> types like scalars and arrays work.
> 
> Scalars don't have this problem as, except for string offsets (IMHO not
> the best idea to have mutable strings too) scalars can not really be
> changed, just replaced with other scalars. But implementing value
> objects in PHP is not hard right now - if you don't provide any methods
> that allow changing state, you've got an immutable object. It's just not
> always what people using it would want, especially with something as
> complex as HTTP message.

You’re ignoring arrays, which *also* have our copy-on-write behaviour. Also, the bigint RFC (if
passed) would be another kind of mutable scalar. It’s not mutable in very many cases, but it is in
some places as a performance optimisation.

We have value objects, sure, but they’re not efficient. Every mutation requires the creation of a
new object, because you can’t do copy-on-write. Compare that to arrays: mutations there only
create new arrays if the refcount is > 1.

The following code using immutable value objects requires the creation of five new objects:

$a = $somefoo
     ->withBar(…)
     ->withBaz(…)
     ->withQux(…)
     ->withoutFooBar();

Yet the following code using arrays, which are passed by value in PHP, requires the creation of only
one new array, and modifies in-place:

$a = $somefoo;
$a[‘bar’] = …;
$a[‘baz’] = …;
$a[‘qux’] = …;
unset($a[‘foobar’]);

Is that not superior?

--
Andrea Faulds
http://ajf.me/






Thread (23 messages)

« previous php.internals (#81516) next »