Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:110956 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 9515 invoked from network); 11 Jul 2020 22:12:57 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 11 Jul 2020 22:12:57 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id BA032180541 for ; Sat, 11 Jul 2020 14:04:42 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=3.4.2 X-Spam-Virus: No X-Envelope-From: Received: from mail-ed1-f50.google.com (mail-ed1-f50.google.com [209.85.208.50]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Sat, 11 Jul 2020 14:04:42 -0700 (PDT) Received: by mail-ed1-f50.google.com with SMTP id d18so7481814edv.6 for ; Sat, 11 Jul 2020 14:04:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=msOGFQefvpdvRpVPnb5K4bcLyfMFDvHv5e4b7dawmwU=; b=o9gjFzwNiE3A4vk6ng8eSca2wV97HN7CJ4suzUiIMGkWyYoar6POhSIjv6v3DKda1i JfhMMY16Z2ePm9rSC6YQsZLlv20CkhaGWtpUGHjF+dgRT3Y2/Re3S5FfXfDN9xk8Wm8/ YZk5Ba80cquCvFPasF2G1QccOCtQK6NeDgCN8S90IAM3mg16uBdJXyEuK8KEAn4TacLT HOL7C6yctKuV3r96TFQi8n0Uy45aJJ023FdvU9DWV1tUhVIUUtUHC3jHYt6aSFqVVo3L EMKfQvOCRe9LnfFR0DRYACbFm/pIVyizqprawMkG5EzZ31Y3qQ3956Vv3Qn7syEl6ApR 8wIw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=msOGFQefvpdvRpVPnb5K4bcLyfMFDvHv5e4b7dawmwU=; b=YmGB2EWOOcR+kEDtyydi0NYxuWF2pRs1ztOF5v1e7mF1vFrJ+bAkugzm9cshQe3gzz 9kDU1TcdvbkECrboJqhUdigyqAWsNfXQf/FlsReHshTWMbVOqJXMx0oN9pBfll8UQspI s6alaR46jIz9NVHBwIKLyFSZXvwy2rktcnKPAYctzjufv+Kl7ruAHBPy/AZWqeKDduBH eRR6R/nyE8O01CM8LO9zp1ODz6tj5G3BX2CbWIQEofotfpj5wH8YotfUH7qRnuX6doYl +xJ1HYxuHLJyYBxBEGDYolKpvQshIKu/br3+Mak5rHglXf21Fco+OYAKhR2/K2jt/RGr psRA== X-Gm-Message-State: AOAM5308iLIQd4D80vsqkvpavU79OaVbh7Vcflz237vs+UOxbDSE2Xah 38+V3izZMW0kVTJSrDE7/uDxLYm2/5wH8Lajs8c6sQ== X-Google-Smtp-Source: ABdhPJyPpRXgEZ2Lrh3AWmKb7bUxtIp3w3W2ijL3yV1v/s+ziiKscepUeFnlQHGKyGM1WRO4Rnxiqsy+0YxLRQw6Y10= X-Received: by 2002:aa7:c24d:: with SMTP id y13mr87457554edo.123.1594501474752; Sat, 11 Jul 2020 14:04:34 -0700 (PDT) MIME-Version: 1.0 Received: by 2002:a54:3091:0:0:0:0:0 with HTTP; Sat, 11 Jul 2020 14:04:34 -0700 (PDT) In-Reply-To: <1e39fdcb-16d2-42c3-95cf-507f7b647b50@www.fastmail.com> References: <1e39fdcb-16d2-42c3-95cf-507f7b647b50@www.fastmail.com> Date: Sat, 11 Jul 2020 21:04:34 +0000 Message-ID: To: Larry Garfield Cc: php internals Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Subject: Re: [PHP-DEV] Possible RFC: UniqueInterface that throws exception at refcount > 1 From: olleharstedt@gmail.com (=?UTF-8?Q?Olle_H=C3=A4rstedt?=) 2020-07-11 19:08 GMT, Larry Garfield : > On Sat, Jul 11, 2020, at 9:06 AM, Olle H=C3=A4rstedt wrote: >> Dear internals, >> >> I'd like to discuss the concept of ownership in PHP, from the point of >> view of a new interface UniqueInterface (or SplUniqueInterface or >> something), which will throw a UniqueException if refcount > 1. >> >> Use-case: Mutable objects that cannot be shared (without (deep) cloning)= . >> >> Rational: Immutable objects are considered "easier to reason about" >> and generally more safe, and as a way to avoid >> spooky-action-at-a-distance. I argue that mutability is totally fine >> as long as it's not *being shared*. Currently, there's no way to >> enforce this in PHP, *but* PHP has a refcounting GC which could do >> this. This would be a more performant alternative than to build lots >> of immutable objects using $obj->whereSomething('bla') constructs. >> >> Cons: If PHP switches to tracing GC, it will be unusable. >> >> What do you think? Should I write it down as an RFC? Implementation >> should be straight-forward, assuming refcount is manipulated at a >> single place in the source. >> >> Regards >> Olle > > I like the goal of addressing shared mutable state is a laudable one and = I > think most here share it. However, I think uniqueness checking is the wr= ong > approach, for reasons others have already explained. > > You're correct that the thing to avoid is shared mutable state. That can= be > avoided either by getting rid of mutable state or shared state. Either > would work. (Channeling Kevlin Henny here.) > > In the case of PHP, since we don't have threads to worry about the main > source of shared state is reference variables, or refrence-esque objects. > (Or globals, but I'm assuming most here know to avoid those already.) Th= at > is, mutability or shared-ness within a function is, meh, who cares. It's= at > function boundaries that we care. > > As others noted, a ref count check wouldn't help with that much, because = the > act of passing an object to another function necessarily increases the > refcount, thus eliminating the main benefit. > > Rather, the way to eliminate shared-ness is to have "structs," that is, > objects that pass by value-ish rather than pass-by-reference-ish. (Yes i= t's > more complicated than that, I know, I'm talking about the user-space > implications.) PHP 4 objects all worked that way, which was a problem fo= r > anything with services our resources behind it. That's why it changed in > PHP 5 to the more common by-ref-ish behavior, which... is a problem for > value objects. > > Both use cases are valid. It's why newer languages like Go and Rust take= a > completely different approach to what "object" even means in the first > place. > > It's been discussed before but never really implemented; I do think the w= ay > to help break the "shared state" side is to allow objects to get flagged = as > "will use by-value passing" or "will use by-reference passing" (again, > implications, not implementation). That is, if you have a by-val object = and > pass it to a function, it behaves the same way as passing a string or an > array: Copy-on-write of the object when any changes are made to propertie= s > of the object. Probably we'd also need to require that properties of by-= val > objects cannot be by-ref objects or resources, which seems reasonable to > me. > > I think that would do a far better job of addressing the > shared-mutable-state issue than reference counting, because it attacks th= e > root problem rather than a symptom. > > --Larry Garfield > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php I think freezing objects might be better fit for my imagined use-case. The only problem I see is that you can't really unfreeze them. Imagine a database connection that only can be open/closed at refcount =3D 1: ``` $connection =3D new OwnershipConnection(); $connection->open(); $ps =3D new PostService($connection); $ps->updateAllPosts(); // Throws exception if $connection->close() $connection->close(); ``` With freeze, you could also do ``` $ps =3D new PostService($connection->freeze()); ``` to ensure it's not closed by mistake. But then you couldn't close the connection at all, except in __destruct. Especially, CoW for objects (at opt-in) is not a replacement where ownership is supposed to replace immutability for performance reason, e.g. creating a separate immutable database connection for every class that uses it. Immutable builder are already part of PSR, e.g. here: https://www.php-fig.org/psr/psr-7/ I have to wonder how reasonable this is, when freezing or ownership are also relevant solutions, with different trade-offs. Olle