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/
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php