Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:115344 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 61045 invoked from network); 7 Jul 2021 12:10:59 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 7 Jul 2021 12:10:59 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id AE0C51804B0 for ; Wed, 7 Jul 2021 05:32:56 -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=0.0 required=5.0 tests=BAYES_40,HTML_MESSAGE, SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=3.4.2 X-Spam-Virus: No X-Envelope-From: Received: from srv015.mail.ichtushosting.com (srv015.mail.ichtushosting.com [159.69.182.195]) (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 ; Wed, 7 Jul 2021 05:32:55 -0700 (PDT) Authentication-Results: srv015.mail.ichtushosting.com; iprev=pass (srv020.mail.ichtushosting.com) smtp.remote-ip=78.46.213.219; spf=pass smtp.mailfrom=stitcher.io; dmarc=pass header.from=stitcher.io Received: from srv020.mail.ichtushosting.com ([78.46.213.219]) by srv015.mail.ichtushosting.com stage1 with esmtp (Exim MailCleaner) id 1m16jT-0005no-6j for from ; Wed, 07 Jul 2021 14:32:53 +0200 Received: from ptr-fq9l27uogse8urofe8x.18120a2.ip6.access.telenet.be (ptr-fq9l27uogse8urofe8x.18120a2.ip6.access.telenet.be [IPv6:2a02:1812:c3b:6800:381d:5c43:4595:39e1]) (Authenticated sender: brendt@stitcher.io) by srv020.mail.ichtushosting.com (Postfix) with ESMTPSA id 1974A3EB3E for ; Wed, 7 Jul 2021 14:32:50 +0200 (CEST) X-MailCleaner-SPF: pass Content-Type: multipart/alternative; boundary="Apple-Mail=_A8A49E4A-C4D5-4C78-9190-A7AE348A8CC1" Mime-Version: 1.0 (Mac OS X Mail 14.0 \(3654.60.0.2.21\)) Message-ID: Date: Wed, 7 Jul 2021 14:32:49 +0200 To: PHP Internals X-Mailer: Apple Mail (2.3654.60.0.2.21) X-MailCleaner-TrustedIPs: Ok Subject: [PHP-DEV] Readonly properties and interfaces From: brendt@stitcher.io (Brent Roose) --Apple-Mail=_A8A49E4A-C4D5-4C78-9190-A7AE348A8CC1 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 Hi internals With the readonly properties RFC almost certainly accepted, I'd like to = discuss an idea that's slightly related to them. One of the problems that readonly properties solve is that they reduce = the overhead of writing getters and setters. This is especially = noticeable in objects that hold lots of data =E2=80=94 data transfer = objects, value objects, entities. And while public readonly properties = will be a style of programming that not everyone likes, it's clear from = the vote on the readonly RFC, as well as the community feedback, that = it's a feature wanted by many. That brings me to interfaces: currently we're only allowed to define = methods on interfaces; historically this makes sense, since interfaces = are meant to define behaviour, and not the implementation. Most OO = language define behaviour using methods, and state using properties, = which in turn are used to define the implementation. But now, readonly properties are added. Suddenly, class properties aren't just used for state anymore, they are = also used to expose that state in an immutable way to the outside, where = we'd use public getters (behaviour) and private properties (state) in = the past, we can now combine them as public readonly properties. = Wouldn't that imply that there are at least some cases where interface = properties could also make sense? A simple example: Imagine we've got 10 different classes that share some behaviour: they = are identifiable by a UUID. Next, imagine we've got a function that can = specifically work with all classes that have a UUID. Proper OO teaches = us to write an interface for this behaviour `Identifiable` or `HasUuid` = or something alike. This interface would probably require its = implementers to expose a `getUuid(): string` method.=20 Without interfaces being able to define properties, we'll now have to = implement a `getUuid()` method on all our 10 classes, nullifying the = advantage we got from using `public readonly string $uuid` in the first = place. If, on the other hand, this functionality was supported, we could = write our interface like so, and wouldn't have to worry about any more = boilerplate code: ``` interface HasUuid { public readonly string $uuid; } ``` With the addition of readonly properties, now seems like a good time to = discuss changing these rules. I realise these questions touch the core = ideas of OO, so I reckon some people might have another opinion and I'd = like to hear your thoughts. To give you some more reading material, there is a precedent for = interface properties in other languages: - TypeScript supports them [1] - C# supports them, albeit using property accessors [2] - Swift supports them via Protocols [3] Looking forward to hearing your thoughts. Kind regards Brent [1] https://www.typescriptlang.org/docs/handbook/type-compatibility.html = =20= [2] = https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-a= nd-structs/interface-properties = =20 [3] https://docs.swift.org/swift-book/LanguageGuide/Protocols.html = =20= --Apple-Mail=_A8A49E4A-C4D5-4C78-9190-A7AE348A8CC1--