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