Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:126951 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: from php-smtp4.php.net (php-smtp4.php.net [45.112.84.5]) by qa.php.net (Postfix) with ESMTPS id 6CB4A1A00BC for ; Wed, 26 Mar 2025 00:23:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1742948443; bh=tH4UlydoYu/vfH4VRWV5ZBqz5rmrQwDXbmEUGuA6XKs=; h=Date:From:To:In-Reply-To:References:Subject:From; b=fmyw0FrPHfb5cdjFEvmPqR8sQSQuCSHn5unfkz6dHYh/eniJO0TA1oJtXN4Jh4Ox6 kxDrMztol34xeg8+uSz/9qpoSpuFCEyDN8K1Q/3o7flRxoe8Cw3OLgZuGbaYy4BN3i 0sBNVR6Vs8ToTyj5fNlnaMRYVbABZ+CvGBx4Fl4RzTlPQzz/3pbau4mMkbZY8ORufB RpwvkgHwDhO0VSB9PhvKJVN/X2KkcEb77X+B8qZgQ6SmAO2HWbRKM/mUxTVV5NE+OW jKkKC6A3ihGyHy0DB8y/6smd2IM7VUQqBFYAqenoZVuJkXRdco4hjxmj7Zb5PeuXf1 2zPRmkPMpfGhg== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id AAF61180088 for ; Wed, 26 Mar 2025 00:20:41 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_MISSING,HTML_MESSAGE, RCVD_IN_DNSWL_LOW,RCVD_IN_MSPIKE_H5,RCVD_IN_MSPIKE_WL,SPF_HELO_PASS, SPF_PASS autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: No X-Envelope-From: Received: from fout-a8-smtp.messagingengine.com (fout-a8-smtp.messagingengine.com [103.168.172.151]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Wed, 26 Mar 2025 00:20:41 +0000 (UTC) Received: from phl-compute-11.internal (phl-compute-11.phl.internal [10.202.2.51]) by mailfout.phl.internal (Postfix) with ESMTP id D2C361382CDA for ; Tue, 25 Mar 2025 20:23:09 -0400 (EDT) Received: from phl-imap-09 ([10.202.2.99]) by phl-compute-11.internal (MEProxy); Tue, 25 Mar 2025 20:23:09 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bottled.codes; h=cc:content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm3; t=1742948589; x=1743034989; bh=tH4UlydoYu /vfH4VRWV5ZBqz5rmrQwDXbmEUGuA6XKs=; b=D3arBIn7zqS6PrXylKK3TzLWXN yiIe8rYypO1/uF99ZpGhcvMMjHGVUAv1skZTO5tBN78mcVuGEzlQz3PKGDS1w9TH XlBdNK7ZP87DRfNZhGRabj2uL2jVBZco1SSU7QAgIVl9Pcx3A/fKRlkIuUFGN4Pa hWAqCPYf+jLvjBHQUfvw2xNLJ/ZIYppbTzK6j4xUOmFbMSxO4VdUCzvx8XgM0pAE gmGNV4J9ImjlAXEwNrlpXUPtVFhb0cijeenra76bu+ZrH+qXO9zxAIYj8PoY1ur6 0SGWQJ8/GZTsk1dv1+rGbfdsnVgMH7udTDfukSKY8Vy2AIKyxEWRcBgvtlJA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm2; t= 1742948589; x=1743034989; bh=tH4UlydoYu/vfH4VRWV5ZBqz5rmrQwDXbmE UGuA6XKs=; b=GG+YCHWBXEbv1w6VD8pP/voBL4UT3AH2SYWzlAlnAAIiAN3I5O6 Qu/YPJSpQfPdisJFBGAB/FFRjFtw4/QWgNu4botSplB9lIwKLGEBAouYMiEsHtkH dJ+Cte7TrmiC2/ocx3pHRSf7gkq4IkiaGFFUGfypbxIL210Wnl46SW5bY6qRJK2O HiimlQZ0DPJNfme9ML1aJ4k0EyGou3i4bKq1iUQzYLc8eUQvrWWXHc0CuX5X7yyT IpyToeMlHSLLb38i5x0z71J1jS2bzfIwrAziCatvIUuAOaNEvzRd4SlBtjVTbqf5 VKI+ZohMYk+QkTREm/+B+Rr/8F5cyZBJ5Rw== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefvddrtddtgdduieegtdekucetufdoteggodetrf dotffvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdggtfgfnhhsuhgsshgtrhhisggv pdfurfetoffkrfgpnffqhgenuceurghilhhouhhtmecufedttdenucgoufhushhpvggtth ffohhmrghinhculdegledmnecujfgurhepofggfffhvffkjghfufgtsegrtderreertdej necuhfhrohhmpedftfhosgcunfgrnhguvghrshdfuceorhhosgessghothhtlhgvugdrtg houggvsheqnecuggftrfgrthhtvghrnheptdeitddvvdevhfdufffhgeelffetgeffveek heekfeeluedutdeiveekvdetjedvnecuffhomhgrihhnpeefvheglhdrohhrghenucevlh hushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehrohgssegsohht thhlvggurdgtohguvghspdhnsggprhgtphhtthhopedupdhmohguvgepshhmthhpohhuth dprhgtphhtthhopehinhhtvghrnhgrlhhssehlihhsthhsrdhphhhprdhnvght X-ME-Proxy: Feedback-ID: ifab94697:Fastmail Received: by mailuser.phl.internal (Postfix, from userid 501) id 60C9E780068; Tue, 25 Mar 2025 20:23:09 -0400 (EDT) X-Mailer: MessagingEngine.com Webmail Interface Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow MIME-Version: 1.0 X-ThreadId: Tb30aece9847cbd48 Date: Wed, 26 Mar 2025 01:22:47 +0100 To: internals@lists.php.net Message-ID: <45ec0bd6-4c65-4059-8cd1-e195f91b5b13@app.fastmail.com> In-Reply-To: <2512DF25-6B2F-4C18-8F49-17F2665ADB53@rwec.co.uk> References: <48dce917-d147-456b-9f03-c7e23411adff@app.fastmail.com> <8a16b81c-7dab-4523-a352-76ba0cb4e771@app.fastmail.com> <9c4ac301-dfb2-49da-90e5-37a2824fc4e3@app.fastmail.com> <5b1e6d70-a1c9-455c-93d3-6b22cf1fef11@app.fastmail.com> <52d84a5b-09d3-4e42-9620-a62fb239c21e@app.fastmail.com> <09a82882-f1ee-4bdb-8a27-e46144a711f1@app.fastmail.com> <2512DF25-6B2F-4C18-8F49-17F2665ADB53@rwec.co.uk> Subject: Re: [PHP-DEV] RFC: short and inner classes Content-Type: multipart/alternative; boundary=f175133684a24c598d6833613acd5890 From: rob@bottled.codes ("Rob Landers") --f175133684a24c598d6833613acd5890 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On Tue, Mar 25, 2025, at 23:20, Rowan Tommins [IMSoP] wrote: >=20 >=20 > On 25 March 2025 21:23:48 GMT, Rob Landers wrote: > > > >> If we didn't have "protected", would you ask the same about "protec= ted private"? "fileprivate" would be just another access level, not some= thing you'd combine with existing ones. > > > >Actually, probably yes :) Mostly just to ask for clarification. In th= is case though, we have private(set) and protected(set); would we also w= ant fileprivate(set)? That's what I was getting at. How do we mix/match = up all these things? >=20 >=20 > I don't see what needs deciding - private(set) isn't a new access leve= l, it's basically sugar for a setter that's marked private. >=20 > Try replacing "private" with "level1", and "protected" with "level2": >=20 > level1(set) level2(get) int $foo; >=20 > And then add "level1a"; can you use it in the same places? Of course:=20 >=20 > level1a(set) level2(get) int $foo; >=20 > So why would there be any ambiguity about writing this? >=20 > fileprivate(set) protected(get) int $foo; >=20 >=20 >=20 > >> > maybe `fileprivate` on a property means `public` in the file, but= `private` outside the file. But then how would that intersect with inhe= ritance? >=20 >=20 > Just to call back to this: it's like saying "protected means public in= side the class and its descendants, but private everywhere else". It's a= n unnecessarily confusing way of describing it, because you then have to= define "public" and "private" without the definitions being recursive. >=20 > A more straightforward description is "protected means accessible insi= de the class and its descendants, and nowhere else". >=20 > Maybe having "private" in the name is putting you off, and this is cle= arer: >=20 > samefile(set) samemodule(get) int $foo; >=20 > No "private" or "public" involved anywhere, just descriptions of where= the property can be accessed. >=20 To be clear, I'm not trying to be difficult. As you mentioned, these wer= e all things I had to think about for nested classes too. I know how nes= ted classes work and why. How file-private would work, on the other hand= , I have put little thought into. You say it is obvious (to paraphrase),= but the devil is in the details, and there isn't much prior-art to draw= from here either. The only prior art I can think of is Swift's `fileprivate` and C's `stat= ic`. Beyond that, I am not aware of any other language to offer this fea= ture. That being said, we can certainly define it any way we want to, bu= t asking 'dumb questions' and challenging assumptions will help us find = the rough edges and things we didn't consider before. > >> I see no reason for inheritance to be involved at all. If we want a= n access level that means "accessible from any code in this file, or any= subclass of the current type", we can make up a keyword for that as wel= l - "fileprotected", or "fileprivate_or_protected", or whatever. > > > >Inheritance gets involved in traits. Traits do "inherit" private acce= ss properties (currently): https://3v4l.org/89I7A >=20 >=20 > Traits don't inherit anything, and they don't restrict anything either= . They paste code in, and once pasted it acts like it was written in the= new location. You can even change access levels while pasting, with the= syntax "use Foo { bar as public }". >=20 > The "private" keyword in your example is pasted into class Foo, and me= ans "accessible within class Foo". It never applies any restriction rela= tive to trait Bar, because running code never belongs to the trait. >=20 > A "fileprivate"/"samefile" keyword would be pasted into the file it wa= s used in, and mean accessible within that file; it wouldn't matter what= file the trait was defined in. It would probably be useless, but lots o= f useless code is possible in any language. I agree, but these are all things we'd have to consider. I, personally, = would consider it working the other way around. A trait declaring filepr= ivate would only be accessible in the trait; otherwise you would have to= explain how fileprivate works without saying "the file it is written in= " and in a way that is easy to understand -- for the RFC + docs. I don't= know if it would be useless or useful though. Personally, I'd probably = implement both ways and see how useful each one is when implementing a t= oy project and then weigh the pros/cons. It might even be a "why not bot= h?" type of situation. It's easier to explain if it is both (your descri= ption above works perfectly for that), but then would allow for some odd= behaviors. =E2=80=94 Rob --f175133684a24c598d6833613acd5890 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable
On Tue, Mar 25,= 2025, at 23:20, Rowan Tommins [IMSoP] wrote:


On 25 Mar= ch 2025 21:23:48 GMT, Rob Landers <rob@bottled.codes> wrote:
>
>= ;> If we didn't have "protected", would you ask the same about "prote= cted private"? "fileprivate" would be just another access level, not som= ething you'd combine with existing ones.
>
>Actually, probably yes :) Mostly just to ask for clarification. In= this case though, we have private(set) and protected(set); would we als= o want fileprivate(set)? That's what I was getting at. How do we mix/mat= ch up all these things?


I do= n't see what needs deciding - private(set) isn't a new access level, it'= s basically sugar for a setter that's marked private.

=
Try replacing "private" with "level1", and "protected" with "= level2":

level1(set) level2(get) int $foo;<= br>

And then add "level1a"; can you use it in t= he same places? Of course: 

level1a(se= t) level2(get) int $foo;

So why would there= be any ambiguity about writing this?

filep= rivate(set) protected(get) int $foo;



>> > maybe `fileprivate` on a property = means `public` in the file, but `private` outside the file. But then how= would that intersect with inheritance?

Just to call back to this: it's like saying "protected means= public inside the class and its descendants, but private everywhere els= e". It's an unnecessarily confusing way of describing it, because you th= en have to define "public" and "private" without the definitions being r= ecursive.

A more straightforward descriptio= n is "protected means accessible inside the class and its descendants, a= nd nowhere else".

Maybe having "private" in= the name is putting you off, and this is clearer:

samefile(set) samemodule(get) int $foo;

=
No "private" or "public" involved anywhere, just descriptions of wh= ere the property can be accessed.

<= div>
To be clear, I'm not trying to be difficult. As you m= entioned, these were all things I had to think about for nested classes = too. I know how nested classes work and why. How file-private would work= , on the other hand, I have put little thought into. You say it is obvio= us (to paraphrase), but the devil is in the details, and there isn't muc= h prior-art to draw from here either.

The o= nly prior art I can think of is Swift's `fileprivate` and C's `static`. = Beyond that, I am not aware of any other language to offer this feature.= That being said, we can certainly define it any way we want to, but ask= ing 'dumb questions' and challenging assumptions will help us find the r= ough edges and things we didn't consider before.

>> I see no reaso= n for inheritance to be involved at all. If we want an access level that= means "accessible from any code in this file, or any subclass of the cu= rrent type", we can make up a keyword for that as well - "fileprotected"= , or "fileprivate_or_protected", or whatever.
>
>Inheritance gets involved in traits. Traits do "inherit" priv= ate access properties (currently): https://3v4l.org/89I7A


Traits don't inherit anything, and they don't restrict anything either= . They paste code in, and once pasted it acts like it was written in the= new location. You can even change access levels while pasting, with the= syntax "use Foo { bar as public }".

The "p= rivate" keyword in your example is pasted into class Foo, and means "acc= essible within class Foo". It never applies any restriction relative to = trait Bar, because running code never belongs to the trait.

A "fileprivate"/"samefile" keyword would be pasted into= the file it was used in, and mean accessible within that file; it would= n't matter what file the trait was defined in. It would probably be usel= ess, but lots of useless code is possible in any language.

I agree, but these are all things we'd have= to consider. I, personally, would consider it working the other way aro= und. A trait declaring fileprivate would only be accessible in the trait= ; otherwise you would have to explain how fileprivate works without sayi= ng "the file it is written in" and in a way that is easy to understand -= - for the RFC + docs. I don't know if it would be useless or useful thou= gh. Personally, I'd probably implement both ways and see how useful each= one is when implementing a toy project and then weigh the pros/cons. It= might even be a "why not both?" type of situation. It's easier to expla= in if it is both (your description above works perfectly for that), but = then would allow for some odd behaviors.

=E2=80=94 Rob
--f175133684a24c598d6833613acd5890--