Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:81516 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 29041 invoked from network); 1 Feb 2015 02:56:29 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 1 Feb 2015 02:56:29 -0000 Authentication-Results: pb1.pair.com header.from=ajf@ajf.me; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=ajf@ajf.me; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain ajf.me designates 192.64.116.208 as permitted sender) X-PHP-List-Original-Sender: ajf@ajf.me X-Host-Fingerprint: 192.64.116.208 imap2-3.ox.privateemail.com Received: from [192.64.116.208] ([192.64.116.208:50111] helo=imap2-3.ox.privateemail.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 50/CC-01632-CD59DC45 for ; Sat, 31 Jan 2015 21:56:29 -0500 Received: from localhost (localhost [127.0.0.1]) by mail.privateemail.com (Postfix) with ESMTP id BFD228C0069; Sat, 31 Jan 2015 21:56:25 -0500 (EST) X-Virus-Scanned: Debian amavisd-new at imap2.ox.privateemail.com Received: from mail.privateemail.com ([127.0.0.1]) by localhost (imap2.ox.privateemail.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id u-a1r-HvZl5k; Sat, 31 Jan 2015 21:56:25 -0500 (EST) Received: from oa-res-26-240.wireless.abdn.ac.uk (oa-res-26-240.wireless.abdn.ac.uk [137.50.26.240]) (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.privateemail.com (Postfix) with ESMTPSA id C48868C0057; Sat, 31 Jan 2015 21:56:24 -0500 (EST) Content-Type: text/plain; charset=utf-8 Mime-Version: 1.0 (Mac OS X Mail 8.1 \(1993\)) In-Reply-To: <54CD8AEE.2070407@gmail.com> Date: Sun, 1 Feb 2015 02:56:22 +0000 Cc: Larry Garfield , internals@lists.php.net Content-Transfer-Encoding: quoted-printable Message-ID: <1ABAD752-418C-4BAA-92B6-0AAB68CB86F9@ajf.me> References: <54CBC804.7050706@gmail.com> <54CD7668.30301@garfieldtech.com> <54CD7975.8040908@gmail.com> <54CD8AEE.2070407@gmail.com> To: Stanislav Malyshev X-Mailer: Apple Mail (2.1993) Subject: Re: [PHP-DEV] [RFC] Immutable variables and objects From: ajf@ajf.me (Andrea Faulds) Hi, > On 1 Feb 2015, at 02:09, Stanislav Malyshev = wrote: >=20 >> Here, there=E2=80=99s no redundant objects made, but if you pass $a = on, it=E2=80=99d >> be automatically copied by PHP, so you don=E2=80=99t need to worry = about it >> being modified. >=20 > 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=E2=80=99s 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=E2=80=99t 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. >=20 This isn=E2=80=99t 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=E2=80=99s no different than how our = existing value >> types like scalars and arrays work. >=20 > 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=E2=80=99re ignoring arrays, which *also* have our copy-on-write = behaviour. Also, the bigint RFC (if passed) would be another kind of = mutable scalar. It=E2=80=99s not mutable in very many cases, but it is = in some places as a performance optimisation. We have value objects, sure, but they=E2=80=99re not efficient. Every = mutation requires the creation of a new object, because you can=E2=80=99t = 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 =3D $somefoo ->withBar(=E2=80=A6) ->withBaz(=E2=80=A6) ->withQux(=E2=80=A6) ->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 =3D $somefoo; $a[=E2=80=98bar=E2=80=99] =3D =E2=80=A6; $a[=E2=80=98baz=E2=80=99] =3D =E2=80=A6; $a[=E2=80=98qux=E2=80=99] =3D =E2=80=A6; unset($a[=E2=80=98foobar=E2=80=99]); Is that not superior? -- Andrea Faulds http://ajf.me/