On Sun, Nov 9, 2025, at 21:51, Tim Düsterhus wrote:
> For this one I am however not sure if it ticks the “composes well” 
> checkbox - that greatly depends on the syntax choice and how modules 
> will look like if/when they eventually arrive.

I understand the concern. Composability matters a lot, especially for features 
that touch visibility. My goal with this RFC is to take a boundary PHP already 
has (the lexical namespace) and make it enforceable without needing to answer 
the bigger "what’s a module/package?" question 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’t. Trying to define prefix rules, upward/downward 
access, or package-like confinement gets us right back into the same 
conversation we’ve been stuck on. That’s why this RFC deliberately picks the 
simplest rule PHP could enforce today: exact namespace equality.

If a future RFC defines modules/packages, namespace-visibility can either:
- fold into that boundary,
- be superseded by it, or
- 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 “RFC Impact” section 
> which doesn't yet include the “Ecosystem Impact” subsection, but 
> indicating that “significant OPcache changes” are required makes me 
> wonder about the cost-benefit ratio.

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

> 
> > Aviz establishes `visibility(operation)` as the pattern for asymmetric 
> > visibility, where the keyword controls the caller set and parentheses 
> > restrict the operation (get/set). That’s why `private(namespace)(set)` 
> > follows the same rule: the base visibility is still "private", and the 
> > parentheses narrows who may call it.
> > 
> > If we introduced a standalone keyword like `internal` or `nsviz`, we’d 
> > effectively be adding a new visibility class, not a refinement of `private` 
> > and would bring its own semantics, collision issues, and interactions with 
> > any future module work. This RFC aims to minimise surface area, which is 
> > why it treats namespace visibility as a refinement.
> 
> As noted in my reply in the thread from Faizan, calling this a 
> refinement of `private` is not really accurate / doesn't work in practice.

Agreed. After the discussion with you, Alex, and Larray, I think it's clearer 
to describe `private(namespace)` as a distinct caller-set, not a subset of 
protected or private. I’ll update the RFC text to reflect that and disallow 
weird combinations (to be more clearly defined in the RFC).

> 
> > If the community prefers prefix-based visibility or package-level 
> > visibility, that could be explored in a follow-up RFC. I’m not opposed to 
> > more expressive forms; I’m just not binding this RFC to a package model the 
> > language hasn’t 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 as “symbol soup” that 
> doesn't really fit the existing language syntactically.

My earliest version simply used `namespace`:

class P {
  namespace function x() {} 
}

It might make sense to return to that syntax if people don’t like the current 
syntax. I don’t have a strong attachment to the exact spelling, what matters is 
the semantics.

— Rob

Reply via email to