Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:115359 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 7882 invoked from network); 7 Jul 2021 20:54:56 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 7 Jul 2021 20:54:56 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 3A2901804D1 for ; Wed, 7 Jul 2021 14:17:01 -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.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 out1-smtp.messagingengine.com (out1-smtp.messagingengine.com [66.111.4.25]) (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 ; Wed, 7 Jul 2021 14:17:00 -0700 (PDT) Received: from compute1.internal (compute1.nyi.internal [10.202.2.41]) by mailout.nyi.internal (Postfix) with ESMTP id 319E05C01A5 for ; Wed, 7 Jul 2021 17:16:59 -0400 (EDT) Received: from imap43 ([10.202.2.93]) by compute1.internal (MEProxy); Wed, 07 Jul 2021 17:16:59 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=content-transfer-encoding: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=fm3; bh=Xkcx0yhuSe3nAdOdhXTNGzavCnrtzL19K1ksCyxx/ 2c=; b=qXDn9EOcufbBhQw4E4e0/AChdXEPmTxqIA9lFRlF8E0SBTDVomWRe4NJV LXc02hg81p1708W/wF1VplZnjJOSFbgC59xqU79ZnsMeLtGBWuvqHDXynSdQX4ZT Be+yoe0fW7rGlEuQT/qlZKlH5W+pcgoOZ0lvoyOG/mmY878Q6CGuT8z8ZzMYijKv ZRUvBunVLHkIdECGNxl2M98VWEKw81Aa4NxaQG1p6PfUgF0GVv15NlF1BwH/vnqb sJ/J5IGg9I1WJRu3v9r3dyN8vwamvPlqcz0zdxqneJ0tr/YCnyjl5ctaaSLSDx+y WKhaGpxYE7B7oVVTBfLItVEdtRb4w== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvtddrtddvgdduheefucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepofgfggfkjghffffhvffutgfgsehtqhertderreejnecuhfhrohhmpedfnfgr rhhrhicuifgrrhhfihgvlhgufdcuoehlrghrrhihsehgrghrfhhivghlughtvggthhdrtg homheqnecuggftrfgrthhtvghrnhepjedthffgfeefudeviefgvdevheduhedtffekhedt heegieeiledvtdeuiefgteegnecuffhomhgrihhnpehthihpvghstghrihhpthhlrghngh drohhrghdpmhhitghrohhsohhfthdrtghomhdpshifihhfthdrohhrghenucevlhhushht vghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehlrghrrhihsehgrghrfh hivghlughtvggthhdrtghomh X-ME-Proxy: Received: by mailuser.nyi.internal (Postfix, from userid 501) id EC682AC0082; Wed, 7 Jul 2021 17:16:58 -0400 (EDT) X-Mailer: MessagingEngine.com Webmail Interface User-Agent: Cyrus-JMAP/3.5.0-alpha0-531-g1160beca77-fm-20210705.001-g1160beca Mime-Version: 1.0 Message-ID: <0a035a3f-60ef-4001-8c55-f26ab518c3d5@www.fastmail.com> In-Reply-To: References: Date: Wed, 07 Jul 2021 16:16:38 -0500 To: "php internals" Content-Type: text/plain;charset=utf-8 Content-Transfer-Encoding: quoted-printable Subject: Re: [PHP-DEV] Readonly properties and interfaces From: larry@garfieldtech.com ("Larry Garfield") On Wed, Jul 7, 2021, at 7:32 AM, Brent Roose wrote: > Hi internals >=20 > With the readonly properties RFC almost certainly accepted, I'd like t= o=20 > discuss an idea that's slightly related to them. >=20 > One of the problems that readonly properties solve is that they reduce= =20 > the overhead of writing getters and setters. This is especially=20 > noticeable in objects that hold lots of data =E2=80=94 data transfer o= bjects,=20 > value objects, entities. And while public readonly properties will be = a=20 > style of programming that not everyone likes, it's clear from the vote= =20 > on the readonly RFC, as well as the community feedback, that it's a=20= > feature wanted by many. >=20 > That brings me to interfaces: currently we're only allowed to define=20= > methods on interfaces; historically this makes sense, since interfaces= =20 > are meant to define behaviour, and not the implementation. Most OO=20 > language define behaviour using methods, and state using properties,=20= > which in turn are used to define the implementation. >=20 > But now, readonly properties are added. >=20 > Suddenly, class properties aren't just used for state anymore, they ar= e=20 > also used to expose that state in an immutable way to the outside,=20 > where we'd use public getters (behaviour) and private properties=20 > (state) in the past, we can now combine them as public readonly=20 > properties. Wouldn't that imply that there are at least some cases=20 > where interface properties could also make sense? >=20 > A simple example: >=20 > Imagine we've got 10 different classes that share some behaviour: they= =20 > are identifiable by a UUID. Next, imagine we've got a function that ca= n=20 > specifically work with all classes that have a UUID. Proper OO teaches= =20 > us to write an interface for this behaviour `Identifiable` or `HasUuid= `=20 > or something alike. This interface would probably require its=20 > implementers to expose a `getUuid(): string` method.=20 >=20 > Without interfaces being able to define properties, we'll now have to=20= > implement a `getUuid()` method on all our 10 classes, nullifying the=20= > advantage we got from using `public readonly string $uuid` in the firs= t=20 > place. If, on the other hand, this functionality was supported, we=20 > could write our interface like so, and wouldn't have to worry about an= y=20 > more boilerplate code: >=20 > ``` > interface HasUuid > { > public readonly string $uuid; > } > ``` >=20 > With the addition of readonly properties, now seems like a good time t= o=20 > discuss changing these rules. I realise these questions touch the core= =20 > ideas of OO, so I reckon some people might have another opinion and I'= d=20 > like to hear your thoughts. >=20 > To give you some more reading material, there is a precedent for=20 > interface properties in other languages: >=20 > - TypeScript supports them [1] > - C# supports them, albeit using property accessors [2] > - Swift supports them via Protocols [3] >=20 > Looking forward to hearing your thoughts. >=20 > Kind regards > Brent >=20 > [1]=20 > https://www.typescriptlang.org/docs/handbook/type-compatibility.html=20= > = =20 > [2]=20 > https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/class= es-and-structs/interface-properties =20= > [3] https://docs.swift.org/swift-book/LanguageGuide/Protocols.html=20 > =20 The property accessor RFC (which didn't get to a vote) discussed this, a= nd specifically proposed making properties part of the interface for... = basically all the reasons given here. My preference would be to add property accessors in 8.2 (at least the as= ymmetric visibility part), and then redefine `readonly` properties as a = shorthand for a "get only" implicit accessor property; which, if I recal= l correctly, is essentially the same semantics as `readonly`. (I didn't= check the RFC; I'm going by memory here.) That would include interface= properties by nature. --Larry Garfield