Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:129184 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 lists.php.net (Postfix) with ESMTPS id DEC521A00BC for ; Sun, 9 Nov 2025 21:33:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1762723991; bh=EI60ysaTmlSpFA3ONEWsChalYqx9kCaLP82+P++jER0=; h=Date:From:To:In-Reply-To:References:Subject:From; b=gLJU6ga7q6jMcAYcQ5dACnnA2uvCHlb2NNozAC7mhVHgm1aqazr9d7ccz3cvFKTaN Y4d4m3WAaMZQzq7YLHxXHTBicl4ebRrgX7wmuK8fChgVTL6e28BufVdRSkzkN9aRkx fa7YDc/1wodTbwJerp/5UjVQUIVi9ExsQbD1dpgKb5egr/tUJLtXsvzrymwwKMTygR pijeoNgX5n71NAg6TaD2nCwXefIY/yr0VoRWjooJH8866f2H3+ilo7R2iCb6WHIXgi BbQ6X3fZCMiwuGUobF/n2Ei3wV9oXTj8H8dxyV/47OYgTLYZ/7ik+B9KR89FwOXPJj hi/yc8fjWViKw== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 08B6E180079 for ; Sun, 9 Nov 2025 21:33:07 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-0.1 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_MISSING,HTML_MESSAGE, RCVD_IN_DNSWL_LOW,SPF_HELO_PASS,T_SPF_TEMPERROR autolearn=no autolearn_force=no version=4.0.1 X-Spam-Virus: No X-Envelope-From: Received: from fout-b1-smtp.messagingengine.com (fout-b1-smtp.messagingengine.com [202.12.124.144]) (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 ; Sun, 9 Nov 2025 21:33:06 +0000 (UTC) Received: from phl-compute-12.internal (phl-compute-12.internal [10.202.2.52]) by mailfout.stl.internal (Postfix) with ESMTP id 5D1D41D00195; Sun, 9 Nov 2025 16:33:01 -0500 (EST) Received: from phl-imap-05 ([10.202.2.95]) by phl-compute-12.internal (MEProxy); Sun, 09 Nov 2025 16:33:01 -0500 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=fm1; t=1762723981; x=1762810381; bh=fe3tN2mKCk Z2wJEvcbKBNIjBIxfhH/YqaEI/wqjSdmQ=; b=u1AR5cT5cSHKnIU7ukkVlBDbfA PJSHzpwCUtuEw+e8VVlfrsx2SHRhDSNYnHiStd90XPxi1tXJl+Xn5LnAQeSOIQgP 86xN0uLv5zYP7K6ThSiuJTQOY0zKqji1imZ8Bj2Ju7/PsEUAAPLAii2FHRIN/Qj/ QsVXNzqpne6fWP3aqz0Drg+1+pnHWZ50awN9d2yTsOWsQnQ0kuXf4QcgntMpp04D XUi/T/T39OQo3SnAm5zYpn9DkV9usYYJKAgG0wTkUZEhNHXpO/MnyHfjkVlD/6yP TCX7l6sNq6N26PCYauTev/m4kZXPZjMM5yH0g/AaDsgB0da6+c0Ar/3hPkbw== 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=fm3; t= 1762723981; x=1762810381; bh=fe3tN2mKCkZ2wJEvcbKBNIjBIxfhH/YqaEI /wqjSdmQ=; b=b6eE9AwhNp/hp0VI9LMkAZ54pvD3TEylBy3pJMsBQWL0CAXpeha tIpIHhnlMTyJIUCG03pWh2J3LeIBP7js29R6B6AxJejHx9n3dOTT/JXEGISFj9JX cb4+A7lwwgQtyYSdV9cnmMmvMDLzoSbDIUI4b44ZwTrCrq5kEDrTwD7FnsGpGFY+ F2GqwhNHnMV8zvLZw9Bqn88Qs6ptLa8AanRh9Btc/Yf5chRwflkpt6ASqK4ZynxP FPz4SyM/9ZCELqK4vJKsCezw2+1y42tJeZSohNjFnmVATWJoq9iXiCNtHMIGRy/0 84uxH2Y2AgUPGPIFceMoM2ImSB3OyxQbY9w== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeeffedrtdeggdduleeiheduucetufdoteggodetrf dotffvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfurfetoffkrfgpnffqhgenuceu rghilhhouhhtmecufedttdenucenucfjughrpefoggffhffvkfgjfhfutgesrgdtreerre dtjeenucfhrhhomhepfdftohgsucfnrghnuggvrhhsfdcuoehrohgssegsohhtthhlvggu rdgtohguvghsqeenucggtffrrghtthgvrhhnpedtueejtdethfeulefhtdelieduteelff dtudelheffgedtieehhfelieejgfevgeenucevlhhushhtvghrufhiiigvpedtnecurfgr rhgrmhepmhgrihhlfhhrohhmpehrohgssegsohhtthhlvggurdgtohguvghspdhnsggprh gtphhtthhopedvpdhmohguvgepshhmthhpohhuthdprhgtphhtthhopehtihhmsegsrghs thgvlhhsthhurdgsvgdprhgtphhtthhopehinhhtvghrnhgrlhhssehlihhsthhsrdhphh hprdhnvght X-ME-Proxy: Feedback-ID: ifab94697:Fastmail Received: by mailuser.phl.internal (Postfix, from userid 501) id B61431820054; Sun, 9 Nov 2025 16:33:00 -0500 (EST) X-Mailer: MessagingEngine.com Webmail Interface Precedence: list list-help: list-unsubscribe: list-post: List-Id: x-ms-reactions: disallow MIME-Version: 1.0 X-ThreadId: AZgO4gJIj6HZ Date: Sun, 09 Nov 2025 22:32:19 +0100 To: =?UTF-8?Q?Tim_D=C3=BCsterhus?= , internals@lists.php.net Message-ID: In-Reply-To: References: <72f90052-fa19-415c-9f5a-ae75275fd030@rwec.co.uk> <2d9f8f1d-e568-4bb5-b30c-0a9e54a8f5fe@rwec.co.uk> <8978174c-04fc-451a-8bf5-cb7c54346318@app.fastmail.com> <1606b9e5-62b8-446b-adac-519ac19d01c3@app.fastmail.com> Subject: Re: [PHP-DEV] RFC: Namespace-Scoped Visibility for Methods and Properties Content-Type: multipart/alternative; boundary=f377ce3ab3004b378a8454a8c0e83706 From: rob@bottled.codes ("Rob Landers") --f377ce3ab3004b378a8454a8c0e83706 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On Sun, Nov 9, 2025, at 21:51, Tim D=C3=BCsterhus wrote: > For this one I am however not sure if it ticks the =E2=80=9Ccomposes w= ell=E2=80=9D=20 > checkbox - that greatly depends on the syntax choice and how modules=20 > will look like if/when they eventually arrive. I understand the concern. Composability matters a lot, especially for fe= atures that touch visibility. My goal with this RFC is to take a boundar= y PHP already has (the lexical namespace) and make it enforceable withou= t needing to answer the bigger "what=E2=80=99s a module/package?" questi= on first. Right now, different people in the ecosystem use namespaces in different= ways: some treat them as hierarchical, some as flat prefixes, some map = them to directory trees, some don=E2=80=99t. Trying to define prefix rul= es, upward/downward access, or package-like confinement gets us right ba= ck into the same conversation we=E2=80=99ve been stuck on. That=E2=80=99= s why this RFC deliberately picks the simplest rule PHP could enforce to= day: exact namespace equality. If a future RFC defines modules/packages, namespace-visibility can eithe= r: - fold into that boundary, - be superseded by it, or - be used inside it (e.g. `internal` for modules, `private(namespace)` w= ithin module internals). Nothing in this RFC makes that harder. >=20 > Your RFC appears to use the old template for the =E2=80=9CRFC Impact=E2= =80=9D section=20 > which doesn't yet include the =E2=80=9CEcosystem Impact=E2=80=9D subse= ction, but=20 > indicating that =E2=80=9Csignificant OPcache changes=E2=80=9D are requ= ired makes me=20 > wonder about the cost-benefit ratio. Thanks! I=E2=80=99ll look at the new template and call out ecosystem imp= act (this was originally written back in April/May?). On the OPcache poi= nt: "significant" is probably overstating it. The change is limited to p= ersisting one additional interned string on zend_op_array and refcountin= g it correctly. The cost is paid at compile time, not at call time, so r= untime performance impact should be negligible. I=E2=80=99ll reword this= to be more precise. >=20 > > Aviz establishes `visibility(operation)` as the pattern for asymmetr= ic visibility, where the keyword controls the caller set and parentheses= restrict the operation (get/set). That=E2=80=99s why `private(namespace= )(set)` follows the same rule: the base visibility is still "private", a= nd the parentheses narrows who may call it. > >=20 > > If we introduced a standalone keyword like `internal` or `nsviz`, we= =E2=80=99d effectively be adding a new visibility class, not a refinemen= t of `private` and would bring its own semantics, collision issues, and = interactions with any future module work. This RFC aims to minimise surf= ace area, which is why it treats namespace visibility as a refinement. >=20 > As noted in my reply in the thread from Faizan, calling this a=20 > refinement of `private` is not really accurate / doesn't work in pract= ice. Agreed. After the discussion with you, Alex, and Larray, I think it's cl= earer to describe `private(namespace)` as a distinct caller-set, not a s= ubset of protected or private. I=E2=80=99ll update the RFC text to refle= ct that and disallow weird combinations (to be more clearly defined in t= he RFC). >=20 > > If the community prefers prefix-based visibility or package-level vi= sibility, that could be explored in a follow-up RFC. I=E2=80=99m not opp= osed to more expressive forms; I=E2=80=99m just not binding this RFC to = a package model the language hasn=E2=80=99t defined yet. >=20 > To do so, the syntax would need to account for that. I have not yet se= en=20 > a good proposal for that that doesn't end up as =E2=80=9Csymbol soup=E2= =80=9D that=20 > doesn't really fit the existing language syntactically. My earliest version simply used `namespace`: class P { namespace function x() {}=20 } It might make sense to return to that syntax if people don=E2=80=99t lik= e the current syntax. I don=E2=80=99t have a strong attachment to the ex= act spelling, what matters is the semantics. =E2=80=94 Rob --f377ce3ab3004b378a8454a8c0e83706 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable


On Sun, Nov 9, 2025, at 21:51, Tim D=C3=BCsterhus wrot= e:
For this one= I am however not sure if it ticks the =E2=80=9Ccomposes well=E2=80=9D&n= bsp;
checkbox - that greatly depends on the syntax choice and = how modules 
will look like if/when they eventually arriv= e.

I understand the concern. C= omposability matters a lot, especially for features that touch visibilit= y. My goal with this RFC is to take a boundary PHP already has (the lexi= cal namespace) and make it enforceable without needing to answer the big= ger "what=E2=80=99s a module/package?" question first.

Right now, different people in the ecosystem use namespaces in d= ifferent ways: some treat them as hierarchical, some as flat prefixes, s= ome map them to directory trees, some don=E2=80=99t. Trying to define pr= efix rules, upward/downward access, or package-like confinement gets us = right back into the same conversation we=E2=80=99ve been stuck on. That=E2= =80=99s why this RFC deliberately picks the simplest rule PHP could enfo= rce today: exact namespace equality.

If a futur= e RFC defines modules/packages, namespace-visibility can either:
- fold into that boundary,
- be superseded by it, or
<= div>- be used inside it (e.g. internal for modules, private(namespace) within module internals).

Nothing in this RFC makes that harder.


Your RFC appears to use the old template for the =E2=80=9CRFC Impa= ct=E2=80=9D section 
which doesn't yet include the =E2=80= =9CEcosystem Impact=E2=80=9D subsection, but 
indicating = that =E2=80=9Csignificant OPcache changes=E2=80=9D are required makes me=  
wonder about the cost-benefit ratio.
=

Thanks! I=E2=80=99ll look at the new template and ca= ll out ecosystem impact (this was originally written back in April/May?)= . On the OPcache point: "significant" is probably overstating it. The ch= ange is limited to persisting one additional interned string on zend_op_= array and refcounting it correctly. The cost is paid at compile time, no= t at call time, so runtime performance impact should be negligible. I=E2= =80=99ll reword this to be more precise.


> Aviz establ= ishes `visibility(operation)` as the pattern for asymmetric visibility, = where the keyword controls the caller set and parentheses restrict the o= peration (get/set). That=E2=80=99s why `private(namespace)(set)` follows= the same rule: the base visibility is still "private", and the parenthe= ses narrows who may call it.
> If we i= ntroduced a standalone keyword like `internal` or `nsviz`, we=E2=80=99d = effectively be adding a new visibility class, not a refinement of `priva= te` and would bring its own semantics, collision issues, and interaction= s with any future module work. This RFC aims to minimise surface area, w= hich is why it treats namespace visibility as a refinement.
As noted in my reply in the thread from Faizan, calling thi= s a 
refinement of `private` is not really accurate / doe= sn't work in practice.

Agreed. Aft= er the discussion with you, Alex, and Larray, I think it's clearer to de= scribe private(names= pace) as a distinct caller-set, not a subset of protected or priv= ate. I=E2=80=99ll update the RFC text to reflect that and disallow weird= combinations (to be more clearly defined in the RFC).


&g= t; If the community prefers prefix-based visibility or package-level vis= ibility, that could be explored in a follow-up RFC. I=E2=80=99m not oppo= sed to more expressive forms; I=E2=80=99m just not binding this RFC to a= package model the language hasn=E2=80=99t defined yet.

To do so, the syntax would need to account for that. I have not= yet seen 
a good proposal for that that doesn't end up a= s =E2=80=9Csymbol soup=E2=80=9D that 
doesn't really fit = the existing language syntactically.

My earliest version simply used namespace:

class P {=0A  namespace function x() {}=20=
=0A}

It might make sense to return to that = syntax if people don=E2=80=99t like the current syntax. I don=E2=80=99t = have a strong attachment to the exact spelling, what matters is the sema= ntics.

=E2=80=94 Rob
<= /body> --f377ce3ab3004b378a8454a8c0e83706--