Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:129200 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 37EF91A00BC for ; Tue, 11 Nov 2025 17:52:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1762883576; bh=HvaOsCoqr4qtY5T9q7yWLiKjprRnrkD76SdIbmR/uVo=; h=Date:From:To:In-Reply-To:References:Subject:From; b=SUdimtVgorhZzxIibXa130QK2ErAHc+Eyjr3OruhS6Z0gumusR79rWr3y2iKSO5d1 UGrR79zRob95sqGsPayQrDnoHEDNVWY5c84km1T+nYQue/OVPIB4O8UyHlJBQbCmrk atKODQ2P90In6uHA3Mtq9urtIinVQhPV/ZyjRpcQ1h3a5KELJrNmCJXp/8e1TMvQuu G4mx9vZbnS4U0H20A8PxcTw+N+gIVLSra5Lx3mSlfmTqjK08kofftWxb48vAUKV5No emRn/xupZNUYfC8LQYvnAZ9qCCsD17ESc4bNle4vdJciH9NJJ/lK5OL8Q+7kl3ttUr TDi707XuPMd0w== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 264C0180081 for ; Tue, 11 Nov 2025 17:52:55 +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,SPF_PASS autolearn=no autolearn_force=no version=4.0.1 X-Spam-Virus: No X-Envelope-From: Received: from fout-b5-smtp.messagingengine.com (fout-b5-smtp.messagingengine.com [202.12.124.148]) (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 ; Tue, 11 Nov 2025 17:52:54 +0000 (UTC) Received: from phl-compute-12.internal (phl-compute-12.internal [10.202.2.52]) by mailfout.stl.internal (Postfix) with ESMTP id D3E181D00172; Tue, 11 Nov 2025 12:52:48 -0500 (EST) Received: from phl-imap-05 ([10.202.2.95]) by phl-compute-12.internal (MEProxy); Tue, 11 Nov 2025 12:52:48 -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=1762883568; x=1762969968; bh=0enSwiE3Xo Kz4CGmYVLhMxvNR9wJ0wL8QeL2vb7Rl6M=; b=p4cC/s0hoVVm9lljV1ohEEampK lSPD/W+uthVDykbMl2WSUj7A6oEB/ijSrfUP/9y0LmFCNrmPPHN6HMABJq00ymdT a4fN7hw1baQDO2ItUBI/rJOY4NqgkajiOyyEVvFMBpvCEtbVCBNEt5ujdJjT7hTS 4vB8Oeu4+2CDq5aOA2EmZtezZ0r3YvZszwdPvDv27GZ4h9lJw8tPITZnN3d8/kWH pFHZZXWhFZeXmrZYKK+Gnhso4k0JU6hk/lEMOLIV8W9BYD3R66nNJgSMNZokwsbW KzAJ8taSuZu218WIw7HpYfzmg4SY9R4dAfPQKCYq9G5EZ11Ym/QA/3hR7Kyg== 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= 1762883568; x=1762969968; bh=0enSwiE3XoKz4CGmYVLhMxvNR9wJ0wL8QeL 2vb7Rl6M=; b=amFUVkJNHqEgYFN+Rk9CxFiWIolre8OomHgZC75eQyME84IpL8M hkoVzLkDBw81kANavydF5LOawf1Pg39c78bObfkj3YPLK8VGOyos5QFSKYyhpBbJ xzMBi0j+Dtq6kRehyL30SXs0vAzeCskTL+iWSl9/FIb/WICibyjD16QifoQtTyHi ZxfEQsG+rpdOeUHXXTfmN6AYD9yQSXggq33OzW4lLxm0tAsvazmH1BsqPSHJeDFO aHs1bTSDn0xnfQBsJQqBzD2kUaacmBFJPeUvisG//uvdhDLa7FVoau12m4Sad+9B v9JjDTGDaF+1atrhOuvcciJOeV2XYAru0IA== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeeffedrtdeggddvtddukeegucetufdoteggodetrf dotffvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfurfetoffkrfgpnffqhgenuceu rghilhhouhhtmecufedttdenucenucfjughrpefoggffhffvkfgjfhfutgesrgdtreerre dtjeenucfhrhhomhepfdftohgsucfnrghnuggvrhhsfdcuoehrohgssegsohhtthhlvggu rdgtohguvghsqeenucggtffrrghtthgvrhhnpefgtdegkedvveduffeigfelteehheejud eigfeludefveeiffefgffgleelvedtfeenucffohhmrghinhepphhhphdrnhgvthdptghh rghtghhpthdrtghomhdpghhithhhuhgsrdgtohhmnecuvehluhhsthgvrhfuihiivgeptd enucfrrghrrghmpehmrghilhhfrhhomheprhhosgessghothhtlhgvugdrtghouggvshdp nhgspghrtghpthhtohepvddpmhhouggvpehsmhhtphhouhhtpdhrtghpthhtohepthhimh essggrshhtvghlshhtuhdrsggvpdhrtghpthhtohepihhnthgvrhhnrghlsheslhhishht shdrphhhphdrnhgvth X-ME-Proxy: Feedback-ID: ifab94697:Fastmail Received: by mailuser.phl.internal (Postfix, from userid 501) id D9C8F1820074; Tue, 11 Nov 2025 12:52:47 -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: Tue, 11 Nov 2025 18:52:27 +0100 To: =?UTF-8?Q?Tim_D=C3=BCsterhus?= , internals@lists.php.net Message-ID: <6a8553d1-0a7e-45e8-9745-54c2400bbcda@app.fastmail.com> 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=6ba6ebfeab7043d08cbbe1c5ab377207 From: rob@bottled.codes ("Rob Landers") --6ba6ebfeab7043d08cbbe1c5ab377207 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On Mon, Nov 10, 2025, at 20:19, Rob Landers wrote: >=20 >=20 > On Sun, Nov 9, 2025, at 22:32, Rob Landers wrote: >>=20 >>=20 >> 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= well=E2=80=9D=20 >>> checkbox - that greatly depends on the syntax choice and how modules=20 >>> will look like if/when they eventually arrive. >>=20 >> I understand the concern. Composability matters a lot, especially for= features that touch visibility. My goal with this RFC is to take a boun= dary PHP already has (the lexical namespace) and make it enforceable wit= hout needing to answer the bigger "what=E2=80=99s a module/package?" que= stion first. >>=20 >> Right now, different people in the ecosystem use namespaces in differ= ent ways: some treat them as hierarchical, some as flat prefixes, some m= ap them to directory trees, some don=E2=80=99t. Trying to define prefix = 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 enforce= today: exact namespace equality. >>=20 >> If a future RFC defines modules/packages, namespace-visibility can ei= ther: >> - fold into that boundary, >> - be superseded by it, or >> - be used inside it (e.g. `internal` for modules, `private(namespace)= ` within module internals). >>=20 >> Nothing in this RFC makes that harder. >>=20 >>>=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 sub= section, but=20 >>> indicating that =E2=80=9Csignificant OPcache changes=E2=80=9D are re= quired makes me=20 >>> wonder about the cost-benefit ratio. >>=20 >> Thanks! I=E2=80=99ll 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 t= o persisting one additional interned string on zend_op_array and refcoun= ting it correctly. The cost is paid at compile time, not at call time, s= o runtime performance impact should be negligible. I=E2=80=99ll reword t= his to be more precise. >>=20 >>>=20 >>> > Aviz establishes `visibility(operation)` as the pattern for asymme= tric visibility, where the keyword controls the caller set and parenthes= es restrict the operation (get/set). That=E2=80=99s why `private(namespa= ce)(set)` follows the same rule: the base visibility is still "private",= and 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 refinem= ent of `private` and would bring its own semantics, collision issues, an= d interactions with any future module work. This RFC aims to minimise su= rface 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 pra= ctice. >>=20 >> 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=E2=80=99ll update the RFC text to re= flect that and disallow weird combinations (to be more clearly defined i= n the RFC). >>=20 >>>=20 >>> > If the community prefers prefix-based visibility or package-level = visibility, that could be explored in a follow-up RFC. I=E2=80=99m not o= pposed to more expressive forms; I=E2=80=99m just not binding this RFC t= o 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 = seen=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. >>=20 >> My earliest version simply used `namespace`: >>=20 >> class P { >> namespace function x() {}=20 >> } >>=20 >> 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 semantics. >>=20 >> =E2=80=94 Rob >=20 > I=E2=80=99ve updated the RFC and the implementation with some signific= ant clarifications and corrections: > =E2=80=A2 *Inheritance semantics now follow `protected` rather than `= private`* > `private(namespace)` members are inherited and must follow normal sign= ature-compatibility rules. > Visibility is enforced based on the declaring namespace rather than th= e inheritance hierarchy. > =E2=80=A2 *Incompatible redeclarations are now clearly defined* > Transitions between `protected` and `private(namespace)` are disallowe= d in either direction. > This avoids unsound cases where substitutability would be broken for c= allers in the declaring namespace. > =E2=80=A2 *Asymmetric visibility rules clarified* > `protected` and `private(namespace)` operate on different axes (inheri= tance vs namespace), so mixed AViz like > `protected private(namespace)(set)` is now a compile-time error. > =E2=80=A2 *Expanded examples and error messages* > The RFC now includes clearer examples of the invalid cases, inheritanc= e rules, and AViz combinations. > =E2=80=A2 *Syntax moved to an explicit open issue* > Because the semantics now line up with `protected` rather than `privat= e`, the spelling `private(namespace)` may not be ideal. > I=E2=80=99ve listed this in the =E2=80=9COpen Issues=E2=80=9D section = and I'll include some previously considered alternatives that preserve t= he semantics here: > =E2=80=A2 `namespace function x() {}` > =E2=80=A2 `local function x() {}` > =E2=80=A2 `private:ns function x() {}` > =E2=80=A2 `protected:ns function x() {}` > My personal preference is toward the simpler forms (`namespace` or `lo= cal`), but I=E2=80=99d like to collect feedback before changing the RFC = text. >=20 > Updated RFC: > https://wiki.php.net/rfc/namespace_visibility >=20 > Implementation: > https://github.com/php/php-src/pull/20421 >=20 > Thanks to everyone who pointed out the inheritance edge cases; those s= urfaced issues that needed to be addressed. Further feedback is welcome. >=20 > =E2=80=94 Rob On my commute, I was exploring the syntax further and the feedback I've = gotten so far. Specifically: class A { local function x() {} } This is accssible only with the exact same namespace where it is declare= d (this RFC). I was reminded that this is very similar to "file private"= but allows the boundary to extend across multiple files in the same nam= espace. Then, we could have this in a followup RFC (which I've already started d= rafting) that doesn't actually require `local` but provides a broader "= package-like" scope without requiring PHP to define what a package is. class A { namespace function x() {} } This would be accessible within the namespace it is declared, as well as= parent and child namespaces (thus we don't make any assumptions about h= ierarchy). Using the following namespace structure: App\ =E2=94=9C=E2=94=80=E2=94=80 Auth\ =E2=94=82 =E2=94=9C=E2=94=80=E2=94=80 SessionManager (declares namespa= ce function validateToken()) =E2=94=82 =E2=94=9C=E2=94=80=E2=94=80 OAuth\ =E2=94=82 =E2=94=82 =E2=94=94=E2=94=80=E2=94=80 OAuthProvider =E2=94=82 =E2=94=94=E2=94=80=E2=94=80 Session\ =E2=94=82 =E2=94=94=E2=94=80=E2=94=80 SessionStore =E2=94=9C=E2=94=80=E2=94=80 Billing\ =E2=94=82 =E2=94=94=E2=94=80=E2=94=80 PaymentProcessor =E2=94=94=E2=94=80=E2=94=80 Controllers\ =E2=94=94=E2=94=80=E2=94=80 LoginController The following can access `validateToken()` : - App\Auth\* (So, SessionStore/OAuthProvider) - App\* (parent namespace) But the following cannot access it: - App\Billing\* - App\Controllers\* - \ (global namespace) The global namespace is a special case where `namespace` and `local` beh= ave exactly the same. Before rewriting the RFC around this, I'd like to guage whether people f= eel like the keyword based approach is a clearer direction than `private= (namespace)`. =E2=80=94 Rob --6ba6ebfeab7043d08cbbe1c5ab377207 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable


On Mon, Nov 10, 2025, at 20:19, Rob Landers wrote:

On Sun, Nov 9, 2025, at 22:32, Rob Landers wrote:


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

I understand the concern. Composabi= lity matters a lot, especially for features that touch visibility. My go= al with this RFC is to take a boundary PHP already has (the lexical name= space) and make it enforceable without needing to answer the bigger "wha= t=E2=80=99s 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=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 either:
- f= old into that boundary,
- be superseded by it, or
- = be used inside it (e.g. i= nternal 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 Impact=E2=80=9D= section 
which doesn't yet include the =E2=80=9CEcosyste= m 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 call out ecos= ystem impact (this was originally written back in April/May?). On the OP= cache point: "significant" is probably overstating it. The change is lim= ited to persisting one additional interned string on zend_op_array and r= efcounting it correctly. The cost is paid at compile time, not at call t= ime, so runtime performance impact should be negligible. I=E2=80=99ll re= word 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 operat= ion (get/set). That=E2=80=99s why `private(namespace)(set)` follows the = same rule: the base visibility is still "private", and the parentheses n= arrows who may call it.
> If we introd= uced a standalone keyword like `internal` or `nsviz`, we=E2=80=99d effec= tively be adding a new visibility class, not a refinement of `private` a= nd would bring its own semantics, collision issues, and interactions wit= h 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&n= bsp;
refinement of `private` is not really accurate / doesn't = work in practice.

Agreed. After th= e discussion with you, Alex, and Larray, I think it's clearer to describ= e private(namespace) as a distinct caller-set, not a subset of protected or private. I=E2=80= =99ll update the RFC text to reflect that and disallow weird combination= s (to be more clearly defined in the RFC).


> If = the community prefers prefix-based visibility or package-level visibilit= y, that could be explored in a follow-up RFC. I=E2=80=99m not opposed to= more expressive forms; I=E2=80=99m just not binding this RFC to a packa= ge model the language hasn=E2=80=99t defined yet.

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

My ea= rliest 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 attachmen= t to the exact spelling, what matters is the semantics.

=E2=80=94 Rob
=
I=E2=80=99ve updated the RFC and the implementation with = some significant clarifications and corrections:
  • = Inheritance semantics now follow protected rather than private
    private(namespace) members are inherited and = must follow normal signature-compatibility rules.
    Visibility = is enforced based on the declaring namespace rather than the inheritance= hierarchy.
  • Incompatible redeclarations= are now clearly defined
    Transitions between protected and private(namespace) are disallowed in= either direction.
    This avoids unsound cases where substituta= bility would be broken for callers in the declaring namespace.
  • Asymmetric visibility rules clarified
    <= div> protected and= private(namespace) operate on different axes (inheritance vs namespace), so mixed AViz li= ke
    protected p= rivate(namespace)(set) is now a compile-time error.
  • Expanded examples and error messages
    = The RFC now includes clearer examples of the invalid cases, inheritance = rules, and AViz combinations.
  • Syntax mo= ved to an explicit open issue
    Because the semantics now l= ine up with protected rather than private, the spelling priva= te(namespace) may not be ideal.
    I=E2=80=99ve listed th= is in the =E2=80=9COpen Issues=E2=80=9D section and I'll include some pr= eviously considered alternatives that preserve the semantics here:
    =
    • namesp= ace function x() {}
    • local function x() {}
    • private:ns function x() {}
    • = protected:ns function x() {}
  • My per= sonal preference is toward the simpler forms (namespace or local), but I=E2=80=99d like to collect feedback = before changing the RFC text.



    Thanks to everyone who = pointed out the inheritance edge cases; those surfaced issues that neede= d to be addressed. Further feedback is welcome.

    =E2=80=94 Rob

    <= div>On my commute, I was exploring the syntax further and the feedback I= 've gotten so far. Specifically:

    class A {=0A  local function x() {}=0A}
    <= div>
    This is accssible only with the exact same namespace = where it is declared (this RFC). I was reminded that this is very simila= r to "file private" but allows the boundary to extend across multiple fi= les in the same namespace.

    Then, we could have = this in a followup RFC (which I've already started drafting) that doesn'= t actually require local<= /code>  but provides a broader "package-like" scope without requiri= ng PHP to define what a package is.

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

    This would be accessible within the namespace = it is declared, as well as parent and child namespaces (thus we don't ma= ke any assumptions about hierarchy).

    Using the = following namespace structure:
    App\<=
    br>=E2=94=9C=E2=94=80=E2=94=80 Auth\
    =E2=94=82 =E2=94=9C=E2=94=80=E2= =94=80 SessionManager (declares namespace function validateToken())
    =E2= =94=82 =E2=94=9C=E2=94=80=E2=94=80 OAuth\
    =E2=94=82 =E2=94=82 =E2= =94=94=E2=94=80=E2=94=80 OAuthProvider
    =E2=94=82 =E2=94=94=E2=94=80= =E2=94=80 Session\
    =E2=94=82 =E2=94=94=E2=94=80=E2=94=80 Sessio= nStore
    =E2=94=9C=E2=94=80=E2=94=80 Billing\
    =E2=94=82 =E2=94=94=E2= =94=80=E2=94=80 PaymentProcessor
    =E2=94=94=E2=94=80=E2=94=80 Controll= ers\
    =E2=94=94=E2=94=80=E2=94=80 LoginController

    =

    The following can access validateToken() :
    - App\Auth\*= (So, SessionStore/OAuthProvider)
    - App\* (parent namespace)

    But the following cannot access it:
    - = App\Billing\*
    - App\Controllers\*
    - \ (global namesp= ace)

    The global namespace is a special case whe= re namespace and <= code style=3D"border-top-width:1px;border-right-width:1px;border-bottom-= width:1px;border-left-width:1px;border-top-style:solid;border-right-styl= e:solid;border-bottom-style:solid;border-left-style:solid;border-top-col= or:rgb(204, 204, 204);border-right-color:rgb(204, 204, 204);border-botto= m-color:rgb(204, 204, 204);border-left-color:rgb(204, 204, 204);border-i= mage-source:initial;border-image-slice:initial;border-image-width:initia= l;border-image-outset:initial;border-image-repeat:initial;border-top-lef= t-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;= border-bottom-left-radius:3px;background-image:initial;background-positi= on-x:initial;background-position-y:initial;background-size:initial;backg= round-repeat:initial;background-attachment:initial;background-origin:ini= tial;background-clip:initial;background-color:rgb(246, 246, 246);font-fa= mily:menlo, consolas, monospace;font-size:90%;padding-top:1px;padding-ri= ght:3px;padding-bottom:1px;padding-left:3px;">local behave exactl= y the same.

    Before rewriting the RFC around thi= s, I'd like to guage whether people feel like the keyword based approach= is a clearer direction than private(namespace).

    =E2=80=94 Rob
    --6ba6ebfeab7043d08cbbe1c5ab377207--