Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:112714 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 5024 invoked from network); 2 Jan 2021 21:50:01 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 2 Jan 2021 21:50:01 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 9EF5B1804D3 for ; Sat, 2 Jan 2021 13:25:32 -0800 (PST) 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.6 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_LOW,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL, SPF_HELO_PASS,SPF_NONE autolearn=no autolearn_force=no version=3.4.2 X-Spam-Virus: No X-Envelope-From: Received: from out5-smtp.messagingengine.com (out5-smtp.messagingengine.com [66.111.4.29]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Sat, 2 Jan 2021 13:25:31 -0800 (PST) Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id BF3AB5C00E5 for ; Sat, 2 Jan 2021 16:25:30 -0500 (EST) Received: from imap26 ([10.202.2.76]) by compute4.internal (MEProxy); Sat, 02 Jan 2021 16:25:30 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to:x-me-proxy :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=Q7vpHP KkXGHgQRhswyctTXAREBQGtkV1CyLUkRx+mE0=; b=c/1qEwzbzSDwrDO8rYpV5r 8wMjcOLdVtnEBMhVVH4ve4UeLbP6AaWpVsXBCZaXsdojn5lq3uFWUfPORh1L5bnU 8vJE8gSIer6/0j6kKUM5cSr5NTG2YTj0SkU5eCKFtez1cTlFrgtRHlPR+8cC6V7e aQVrGxdEiBtYu5n6N2uxzUcNqJEEPo9aAyJVOl8l+KHGttZTUcxlGnnpKat69egY BHIPROXs1PzBCPdrdsFQwEUnyf7M1AadcopuiL1L5a3bxEAsF0L+GlfwUMbqxezF 8q4SfQajkvho2HylweQqJl3G6axq8XnAMztiNOXQbUW2Q8Yu/8qArTr3NLib78vA == X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedujedrvddvledguddviecutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfgh necuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd enucfjughrpefofgggkfgjfhffhffvufgtsehttdertderreejnecuhfhrohhmpedfnfgr rhhrhicuifgrrhhfihgvlhgufdcuoehlrghrrhihsehgrghrfhhivghlughtvggthhdrtg homheqnecuggftrfgrthhtvghrnheplefhjeduueegudeghfehudfgvdeflefffeeuteev uedtjeffkeetkeeiveejkefgnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpe hmrghilhhfrhhomheplhgrrhhrhiesghgrrhhfihgvlhguthgvtghhrdgtohhm X-ME-Proxy: Received: by mailuser.nyi.internal (Postfix, from userid 501) id 236A114200A2; Sat, 2 Jan 2021 16:25:30 -0500 (EST) X-Mailer: MessagingEngine.com Webmail Interface User-Agent: Cyrus-JMAP/3.3.1-61-gb52c239-fm-20201210.001-gb52c2396 Mime-Version: 1.0 Message-ID: <6f51556b-a566-45d2-939e-3d6c3441eb00@www.fastmail.com> In-Reply-To: References: <1d0abb04-4987-43a9-85bc-bccc3bd6be9a@www.fastmail.com> <03108284-740a-4a5d-130f-15b2e67e9df9@mabe.berlin> <459d7ff7-e553-dce9-7d43-c3b1e772e572@gmail.com> <7f4fe9ca-1c20-6f69-cef0-a9718af742a3@gmail.com> <30906866-1971-8395-05a0-fd78d054bb89@gmail.com> <0C621FEF-B76F-41F5-A5A8-E6F24D69DD3D@pmjones.io> Date: Sat, 02 Jan 2021 15:25:08 -0600 To: "php internals" Content-Type: text/plain Subject: =?UTF-8?Q?Re:_[PHP-DEV]_Analysis_of_property_visibility,_immutability,_a?= =?UTF-8?Q?nd_cloning_proposals?= From: larry@garfieldtech.com ("Larry Garfield") On Sat, Jan 2, 2021, at 12:56 PM, Rowan Tommins wrote: > On 01/01/2021 20:31, Paul M. Jones wrote: > > The complaints against the incomplete and inconsistent immutability of PSR-7 have merit. > > > The big mistake of PSR-7, in my view, is mixing immutable objects with > streams, which are inherently mutable/stateful. I wonder if there are > any lessons to be learned there in terms of what kinds of immutability > the language should encourage / make easy. > > For instance, is it better to constrain entire objects to be immutable > rather than individual properties? And should there be restrictions on > what you can declare as immutable, since "immutable resource" is largely > nonsensical? > > Or is it rather a reflection that building purely immutable > implementations is hard, and the language needs other facilities > (monads? ownership?) to mix in those parts that don't fit? > > Regards, I rarely hear that called out as a PSR-7 complaint specifically, in practice, but moving on... IMO, it's better to put the focus on immutable properties. There are use cases where you want only some properties to be immutable, but not the whole class. If you do want the whole class, then marking all the properties immutable is effectively the same thing. Though, again, in practice, at least in PHP, I don't think immutable properties should be the goal. Asymmetric visibility lets us built safely immutable-from-the-outside objects that are "up to you" on the inside. I think that gives us a better end result given the nature of PHP. In other languages that wouldn't make as much sense, but PHP is what it is. Copy on write makes "immutable data structures" not something we need to build explicitly; we get "close enough" for free. If you really wanted to micro-optimize the memory and CPU usage further than that... go build it in Rust instead. Wrapping immutable behavior around IO is... ugly, gross, and disgusting. :-) Even supposedly Twue Pure languages like Haskell don't actually do that; it just hides the IO mutability in the engine and whistles innocently while muttering "monad" under its breath. :-) At least in the abstract, immutability and IO would require IO primitives that returned both a read value and a new stream pointer, possibly consuming and destroying the old one. If a stream is seekable, you could conceptually do something like: $fp = file_open('foo.txt'); [$line, $fp2] = read_line($fp); In which $fp2 and $fp refer to the same file stream on disk, but their stream pointers are different. In practice you'd likely use $fp as the second parameter and lose the old reference, which is good enough. That's a bit clumsy, though, and where one might use something monad-based to make the code a bit simpler. I don't know off hand what that would look like, though. [$line1, $fp2] = read_line($fp); [$line2, $fp2] = read_line($fp); [$line3, $fp2] = read_line($fp); [$line4, $fp2] = read_line($fp); In the above example, since $fp is never overwritten, all 4 $line variables are the same thing. If a stream is not seekable, then it would have to consume and destroy $fp in the process (unset it). So: [$line1, $fp2] = read_line($fp); [$line2, $fp2] = read_line($fp); The second line would throw an error that $fp "has been consumed" or something like that. But even that still creates potential for spooky-action-at-a-distance if $fp was passed into a function, gets read in that function, and then the parent call scope has a broken $fp lying around. IO is inherently impure and mutable, and always will be. I don't think it's realistic for us to fix that, certainly not in PHP. Instead we should be making it easy to encapsulate the IO into safe corners where you can guard it carefully and keep everything else as pure as reasonable. All of which is why the scope I'm looking at is not how to make PHP Haskell-esque pure. It's how do we make it more ergonomic for developers to build stateless code in those places where it's reasonable to do so. It's a much less ambitious, but therefore more achievable, scope. --Larry Garfield