Re: RFC: Namespace-Scoped Visibility for Methods and Properties

From: Date: Sun, 09 Nov 2025 09:45:08 +0000
Subject: Re: RFC: Namespace-Scoped Visibility for Methods and Properties
References: 1 2  Groups: php.internals 
Request: Send a blank email to internals+get-129160@lists.php.net to get a copy of this message

On Sun, Nov 9, 2025, at 07:09, Alexandru Pătrănescu wrote:
> Hi Rob
> 
> On Sat, Nov 8, 2025, 14:46 Rob Landers <rob@bottled.codes> wrote:
>> __
>> Hello Internals,
>> 
>> I’d like to introduce an RFC for discussion: https://wiki.php..net/rfc/namespace_visibility
>> which proposes a new visibility modifier: private(namespace).
>> 
>> This idea has appeared several times in previous threads but never progressed to a formal
>> proposal (from what I could find). My hope is that with defined semantics, examples, and
>> implementation details, we can evaluate it properly and see whether there’s support for moving
>> forward. Feedback is very welcome.
>> 
>> 
> 
> Nice work on this.
> 
> 
> I have one issue:
> > *Visibility hierarchy: *public < protected < private(namespace) < private
> 
>> 
> I think is not a correct view of the real problem space, as the protected and private namespace
> scopes are separate sets that might have things in common but can also be distinct.
> 
> I think the correct way to model it, is to have two hierarchies:
> public < protected < private
> public < private(namespace) < private
> 
> Otherwise you can have things like
> protected private(namespace)(set)
> that is unclear how it should be handled.
> Can you clarify what is the right-now expected get and set allowance for these cases:
> - child classes in the same namespace
> - child classes in another namespace
> - non-child classes in the same namespace
> 
> 
> My suggestion is to not allow mixing protected and private namespace for aviz.
> 
> -- 
> Alex

Hi Alex,

I think you’re right, treating this as a simple linear hierarchy is misleading.
Protected and private(namespace) *are *based on different axes:

- protected is inheritance-based
- private(namespace) is namespace-based

So, for protected private(namespace):
- child class in the same namespace: read + write
- child class in a different namespace: read-only
- non-child class in the same namespace: forbidden

Formally, we can consider the caller sets:

- C[public]
- C[protected] (declaring class ∪ subclasses)
- C[ns] (all code in the exact declaring namespace)
- C[private] (declaring class only)

We have two partial orders:
- C[public] ⊇ C[protected] ⊇ C[private]
- C[public] ⊇ C[ns] ⊇ C[private]

In general, C[protected] and C[ns] are incomparable (neither is a subset of the other).

For asymmetric properties, the (set) visibility must satisfy C[set] ⊇ C[base]. If
C[set] and C[base] are incomparable or otherwise not a subset, it’s a compile-time error.

That yields:

- public with any (set) visibility: C[any] ⊆ C[public]
- protected with protected(set) or private(set) only:
C[private] ⊆ C[protected]
- private(namespace) with private(namespace)(set) or
private(set) only: C[private] ⊆ C[ns]
- private with private(set) only: C[private] ⊆ C[private]
- protected with private(namespace)(set): incomparable
- private with private(namespace)(set): C[ns] ⊈ C[private]

I’ll update the RFC to drop the linear hierarchy and update with the subset rule explicitly with
some examples.

— Rob


Thread (32 messages)

« previous php.internals (#129160) next »