Hi,

> On 1 Feb 2015, at 02:09, Stanislav Malyshev <smalys...@gmail.com> 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/





--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to