Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:126798 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 A17D61A00BC for ; Mon, 17 Mar 2025 07:11:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1742195354; bh=lfgkKh6XIsnqfKAQPjhberQJLVosqgjCnKwPP3Fu8F0=; h=Date:From:To:In-Reply-To:References:Subject:From; b=Pve30Gq88rXc9ZrPwE7njngKBVJNUhthCxQj9VdPCZgvNdQzc01LOPQg5D4FA94Og W30jnB08pDtynOinCxD4zks0oHSmfnWBqvD7pMRL6kiB7f+POD3GUCi5DHcuMny44I TwRJgwt2Ji0EcSUpOkxZ8QyP1djOHYjT9XQu3OvbE5cRF3P4y28KqD3xCd6wbHwgkh rAv859HX3hgQidxQZ0AHYPej4yDHvQuhCTj6XmcsjuOKCAdpnbfL6NJglRLjrG1Dsw lUee1UeqmxKQP5JSnFG2FEqKv8VOSWx+iBfIHmW03Y7wV8z1x8dM0/WLKQ10ZNWlLX h0wGvgGT37GXQ== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 2D6AE18004E for ; Mon, 17 Mar 2025 07:09:13 +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,SPF_HELO_PASS,SPF_PASS autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: No X-Envelope-From: Received: from fhigh-a1-smtp.messagingengine.com (fhigh-a1-smtp.messagingengine.com [103.168.172.152]) (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 ; Mon, 17 Mar 2025 07:09:12 +0000 (UTC) Received: from phl-compute-11.internal (phl-compute-11.phl.internal [10.202.2.51]) by mailfhigh.phl.internal (Postfix) with ESMTP id 32832114013B for ; Mon, 17 Mar 2025 03:11:44 -0400 (EDT) Received: from phl-imap-09 ([10.202.2.99]) by phl-compute-11.internal (MEProxy); Mon, 17 Mar 2025 03:11:44 -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=fm2; t=1742195504; x=1742281904; bh=XhF5dU+EqM 7uNqQYVvGHhl/1uCisVypBCtem6nTB6/M=; b=Y+la8TIRWlB5rgZUThL1bWWYQa zgNDiZI14dSXcfcN/75f1cKfhRUj3vr/BSlhO8dkaiSspKyiE8Qv5rZOjrfoRaxi mq5X5RbDk1hkpv1IuhMH4wIytdVHcKUtpP/KN85rdwS57NXQfxAgV5aLkVgO6Ek6 q3/W9B92dC12U0SgpS0t4VH7k4aReINBnawMfGnRplUzQv8kFR2jQmj70S8XgNAQ UOij+qV9231ifW/ysVgGn6Mj7cXqKxZoh/XfQAr5jDQMhg6f8rrQP2RGbd78m+wO bXH3eGnlOtgfFyRWiEZloFZ90IDNQCuV8X8opnDmo/Vp+0+s5Z/aBlxsFWmQ== 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=fm1; t= 1742195504; x=1742281904; bh=XhF5dU+EqM7uNqQYVvGHhl/1uCisVypBCte m6nTB6/M=; b=0aAV+7Xh4VfRavCyG7h0gBnlgsNFV4uyco1zuOwmG+KKEH4oyZy /NfbTwHF6TuBzg8PxnEtWUIQScK/JSynqcTXRBv9eKU1tuLGf1STp5RSOBK0Jdj/ nIquH19anmY1ExDQRI4XjVAU+9pbdRSgEwlqCZxCbfxwXmmsPdFH9yDhXmqBt4AE Tone9bSR8X7tLQY/pkV7KOXUP6OI8o0QT/n8/nNuo/OcHo6vh9TQuXHoTPwkQ1rD dXxYc2DS8/HdtF/db02ZCfnZiecdHOabY8JAV3LRRgqtznW1qk4ZFOUm+Bi00tic cri/UV1N8Cwp5wK9xveaxlys+5FcopNAAEQ== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefvddrtddtgddufeekkeejucetufdoteggodetrf dotffvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdggtfgfnhhsuhgsshgtrhhisggv pdfurfetoffkrfgpnffqhgenuceurghilhhouhhtmecufedttdenucenucfjughrpefogg ffhffvkfgjfhfutgesrgdtreerredtjeenucfhrhhomhepfdftohgsucfnrghnuggvrhhs fdcuoehrohgssegsohhtthhlvggurdgtohguvghsqeenucggtffrrghtthgvrhhnpedtue ejtdethfeulefhtdelieduteelffdtudelheffgedtieehhfelieejgfevgeenucevlhhu shhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehrohgssegsohhtth hlvggurdgtohguvghspdhnsggprhgtphhtthhopedupdhmohguvgepshhmthhpohhuthdp rhgtphhtthhopehinhhtvghrnhgrlhhssehlihhsthhsrdhphhhprdhnvght X-ME-Proxy: Feedback-ID: ifab94697:Fastmail Received: by mailuser.phl.internal (Postfix, from userid 501) id DAA15780068; Mon, 17 Mar 2025 03:11:43 -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 Date: Mon, 17 Mar 2025 08:11:23 +0100 To: internals@lists.php.net Message-ID: <8bbb484b-96a3-4a3e-881e-2c47d7f433b9@app.fastmail.com> In-Reply-To: <0F1E4400-5E26-4E39-88B9-ABD7ABBAEBC4@rwec.co.uk> References: <4abd7008-ae33-46fe-8bbd-7c99f7c48158@app.fastmail.com> <0F1E4400-5E26-4E39-88B9-ABD7ABBAEBC4@rwec.co.uk> Subject: Re: [PHP-DEV] RFC: short and inner classes Content-Type: multipart/alternative; boundary=e29859c7b6884f14b34fc26fc9744f87 From: rob@bottled.codes ("Rob Landers") --e29859c7b6884f14b34fc26fc9744f87 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On Sat, Mar 15, 2025, at 12:53, Rowan Tommins [IMSoP] wrote: >=20 >=20 > On 14 March 2025 23:37:08 GMT, Rob Landers wrote: > >I could get behind `::`, but I feel that it introduces human ambiguit= y. I don't believe it would introduce compiler ambiguity, but as a human= , I have to hope the programmers are using a style that makes it obvious= what are inner classes and what are constants/methods. >=20 > As far as I can see, all four languages I looked up last night (Java, = C#, Swift, Kotlin) use the same syntax for accessing a nested type as fo= r accessing a property or method, so we'd be following the crowd to use = "::" >=20 > That said, I think they all also use that same syntax for namespace (o= r equivalent) lookups, so the same argument can be made for "\". (Why PH= P separates those isn't entirely clear to me.) >=20 > Having some new syntax makes them feel more "exotic" to me. The C# and= Swift docs give the impression that nesting types is "just something th= at can happen", rather than a whole new language concept to learn. >=20 > Java's "inner classes" are something different, and I think we should = avoid using that term. >=20 >=20 >=20 > > Furthermore, I'm relatively certain this approach can be slightly mo= dified to support "namespace private/protected" classes, in general. So,= that will also possibly be a follow-up RFC and having them mixed up wil= l complicate things. In any case, I am not a fan of using the namespace = separator here. >=20 > To me namespace, module, or file visibility seem like much more natura= l additions to the language, and to solve most of the same problems as n= esting types. >=20 > I guess a public nested class is a bit like a "friend class"? In that = it has special access to its surrounding class, but otherwise might as w= ell just be sharing a namespace with it. But it's also necessarily in th= e same file, so marking those members "file private" rather than "privat= e" would also allow that. >=20 > A private nested class can only be explicitly mentioned within that na= rrow context, which again feels very much equivalent to "file private". >=20 >=20 > > $user =3D new User:>Builder("Rob")->withEmail("rob@bottled.codes")->= build(); > > > > The user builder is intrinsically tied to the User class itself, it = isn't just a namespace. The user builder shares scope with the user clas= s and is able to be the only way to construct a user (barring reflection= ). >=20 > If we had either file or namespace visibility, exactly the same thing = could be achieved with those, and would look like this:=20 >=20 > $user =3D new User\Builder("Rob")->withEmail("rob@bottled.codes")->bui= ld(); >=20 > The "User" class would have a "file private" or "namespace private" co= nstructor, callable from the "User\Builder" class but not elsewhere; the= build() method would return the "User" instance. >=20 >=20 >=20 > I think I'm coming to the conclusion that we should use backslash: nes= ted types can be viewed as a shorthand way of having a class and namespa= ce with the same name, plus applying some visibility rules to that names= pace. >=20 > Rowan Tommins > [IMSoP] >=20 I don=E2=80=99t think `\` is viable. If we used slash it would complicat= e autoloading and be impossible to differentiate between=20 namespace Outer; class Inner {} And class Outer { class Inner {} } These would both resolve to the same class name for Outer\Inner. Which o= ne it resolves to would depend on how you implement autoloading (which m= ay be desirable for BC reasons). Then there becomes the question of eith= er letting user-land implement the autoloading changes, or have php walk= =E2=80=9Cup=E2=80=9D the namespace chain in the hopes it implements an = inner class. So, maybe, it could be useful to use `\` but in the long run, I=E2=80=99= m not sure it makes sense.=20 =E2=80=94 Rob --e29859c7b6884f14b34fc26fc9744f87 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable

=
On Sat, Mar 15, 2025, at 12:53, Rowan Tommins [IMSoP] wro= te:


On 14 March 2025 23:37:08 GMT, Rob Landers <rob@bottled.codes> wrote:
<= /div>
>I could get behind `::`, but I feel that it introduces hum= an ambiguity. I don't believe it would introduce compiler ambiguity, but= as a human, I have to hope the programmers are using a style that makes= it obvious what are inner classes and what are constants/methods.

As far as I can see, all four languages I looked= up last night (Java, C#, Swift, Kotlin) use the same syntax for accessi= ng a nested type as for accessing a property or method, so we'd be follo= wing the crowd to use "::"

That said, I thi= nk they all also use that same syntax for namespace (or equivalent) look= ups, so the same argument can be made for "\". (Why PHP separates those = isn't entirely clear to me.)

Having some ne= w syntax makes them feel more "exotic" to me. The C# and Swift docs give= the impression that nesting types is "just something that can happen", = rather than a whole new language concept to learn.

Java's "inner classes" are something different, and I think we s= hould avoid using that term.



> Furthermore, I'm relatively certain this approach c= an be slightly modified to support "namespace private/protected" classes= , in general. So, that will also possibly be a follow-up RFC and having = them mixed up will complicate things. In any case, I am not a fan of usi= ng the namespace separator here.

To me name= space, module, or file visibility seem like much more natural additions = to the language, and to solve most of the same problems as nesting types= .

I guess a public nested class is a bit li= ke a "friend class"? In that it has special access to its surrounding cl= ass, but otherwise might as well just be sharing a namespace with it. Bu= t it's also necessarily in the same file, so marking those members "file= private" rather than "private" would also allow that.
A private nested class can only be explicitly mentioned with= in that narrow context, which again feels very much equivalent to "file = private".


> $user =3D new= User:>Builder("Rob")->withEmail("rob@bottled.codes")->build();
>
> The user builder is intrinsically tied to the User class itself,= it isn't just a namespace. The user builder shares scope with the user = class and is able to be the only way to construct a user (barring reflec= tion).

If we had either file or namespace v= isibility, exactly the same thing could be achieved with those, and woul= d look like this: 

$user =3D new User\= Builder("Rob")->withEmail("rob@b= ottled.codes")->build();

The "User" = class would have a "file private" or "namespace private" constructor, ca= llable from the "User\Builder" class but not elsewhere; the build() meth= od would return the "User" instance.



I think I'm coming to the conclusion that we sho= uld use backslash: nested types can be viewed as a shorthand way of havi= ng a class and namespace with the same name, plus applying some visibili= ty rules to that namespace.

Rowan Tommins
[IMSoP]


I don=E2=80=99t think `\` is viable. If we used slash it would com= plicate autoloading and be impossible to differentiate between 
=

namespace Outer;

= class Inner {}

And

=
class Outer {
  class Inner {}
}

These would both resolve to the same class n= ame for Outer\Inner. Which one it resolves to would depend on how you im= plement autoloading (which may be desirable for BC reasons). Then there = becomes the question of either letting user-land implement the autoloadi= ng changes, or have php walk =E2=80=9Cup=E2=80=9D the namespace chain in= the hopes it implements an inner class.

So= , maybe, it could be useful to use `\` but in the long run, I=E2=80=99m = not sure it makes sense. 

=E2=80=94 Rob
--e29859c7b6884f14b34fc26fc9744f87--