Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:126726 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 1A1181A00BC for ; Wed, 12 Mar 2025 10:11:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1741774120; bh=7ojLQiyhpAuyD+X76dq3WsphAv5y/ap/2FEuE/LRCho=; h=Date:From:To:In-Reply-To:References:Subject:From; b=f7vj8QBAwIZrHebPRqHafypP/EOSVph2NUgmyN2lHig/exHf0KcUHwX70kTU3utx/ +2xtu6IiovU4N9y9RGIYjZJFY4Fk7zBePYLUe8Z1dmhLlWqQMRaEufDPZwZjMTS3Qz BFlXQrKX5LbABEuiISbA40hgL/kub4kuiVX+ZDrQ9d8vWnXt1Z/6Gly6Zcv4iY3eWP wvBze3Toe/b0Z2OwY+ycxd+A99w7c6kOkgQq0ENM7uV/Wt1NDYoneMyy4yUnkJwWOA t/n/z22NaPPTPey2/tVWmYgclWXYM1JjCHDnbB52boCUCz8Ts5/9Ah2bqY8qWcluC1 E61DM+CAGbNGA== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 2BDB518007E for ; Wed, 12 Mar 2025 10:08:36 +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-b1-smtp.messagingengine.com (fhigh-b1-smtp.messagingengine.com [202.12.124.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 ; Wed, 12 Mar 2025 10:08:35 +0000 (UTC) Received: from phl-compute-11.internal (phl-compute-11.phl.internal [10.202.2.51]) by mailfhigh.stl.internal (Postfix) with ESMTP id EC083254007C for ; Wed, 12 Mar 2025 06:11:08 -0400 (EDT) Received: from phl-imap-09 ([10.202.2.99]) by phl-compute-11.internal (MEProxy); Wed, 12 Mar 2025 06:11:09 -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=1741774268; x=1741860668; bh=rNgQ1fnkhD 5HcxAXnbHrpe7Oat83OpQ6ipDJh5raayw=; b=LlQgBXQanH+5oC7J7UW5TaRqoS S/2KdAXpLWx+tJWZF9tyrNxOfY7hw74cvE9kLHOWgHR4RMzX8iwSYZTKp6kHdAlo mOcWD+KmtrvDZ0CshoymCo7uyiO6PJ4JS3n99sSmUrHulKoQ+xko2gGLYpUwDura N+G3GLrD9FDl/mkNQfDZTTG3s313rGabTRgoKoi0bXzq/iToOs6I/u3eeWXCGTMm BC/8mBsWWaAZiAG1hr7mBXfc5DBEsHma/lUmVLtY3CyK8C1HR+47X4XjW9kC58nB LlvinwBvLqSOyAmk1cSfDCcPwy7r/4zbmSO43EVMyD2W/CdB839G8kp/6CKQ== 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= 1741774268; x=1741860668; bh=rNgQ1fnkhD5HcxAXnbHrpe7Oat83OpQ6ipD Jh5raayw=; b=L2d9qgp9orqK8SwlmX95rBWjhZ1mrzk0kUSV97KzcRvTD3TZMg7 201bQw7c7OeW3uN9o5iCB6qyVJRu6ho0KZWBIBxcWgF9W0ClJUqfnFWGdArcjrY1 TvYoWd+jzciWfUf9gDIVNzE9juRDHo5ef/SNgwErzsWtFO2wCJWClgUdDiMb2QmF BGLlhz2rjYko63QQZD9vscFBVht4TIV/bNze6Ug6sGMyRMHh29cPsf4tZR7Tvzgv loXQVoIhKyxhox5YlbyTymjfTh2uBH/A93op4g4/EQjwkMjC4kaGwpCH3qE48k4V Z/zsQd7FZZotj5Juag5TS1hB1s8PVCcFq4g== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefvddrtddtgdduvdegjeelucetufdoteggodetrf dotffvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdggtfgfnhhsuhgsshgtrhhisggv pdfurfetoffkrfgpnffqhgenuceurghilhhouhhtmecufedttdenucenucfjughrpefogg ffhffvkfgjfhfutgesrgdtreerredtjeenucfhrhhomhepfdftohgsucfnrghnuggvrhhs fdcuoehrohgssegsohhtthhlvggurdgtohguvghsqeenucggtffrrghtthgvrhhnpeehie ffkeetleejueefjeffueffheevudfgteevfeeijeevfffhhfegueetteffleenucffohhm rghinhepphhhphdrnhgvthdpghhithhhuhgsrdgtohhmnecuvehluhhsthgvrhfuihiivg eptdenucfrrghrrghmpehmrghilhhfrhhomheprhhosgessghothhtlhgvugdrtghouggv shdpnhgspghrtghpthhtohepuddpmhhouggvpehsmhhtphhouhhtpdhrtghpthhtohepih hnthgvrhhnrghlsheslhhishhtshdrphhhphdrnhgvth X-ME-Proxy: Feedback-ID: ifab94697:Fastmail Received: by mailuser.phl.internal (Postfix, from userid 501) id 62A90780068; Wed, 12 Mar 2025 06:11:08 -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: Wed, 12 Mar 2025 11:10:48 +0100 To: internals@lists.php.net Message-ID: <2935d0e2-ddc4-447c-ab37-c9b7337b8b60@app.fastmail.com> In-Reply-To: References: Subject: [PHP-DEV] Re: RFC: short and inner classes Content-Type: multipart/alternative; boundary=63f4321edaca478eb340ed0f554f8dcc From: rob@bottled.codes ("Rob Landers") --63f4321edaca478eb340ed0f554f8dcc Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On Thu, Mar 6, 2025, at 00:11, Rob Landers wrote: > Hello PHP Internals, >=20 > I'd like to introduce my RFC for discussion: https://wiki.php.net/rfc/= short-and-inner-classes >=20 > This RFC defines a short class syntax as well as the ability to nest c= lasses inside another class. This introduces an unprecedented amount of = control, flexibility, and expressiveness over how objects are used and i= nstantiated in PHP. There is a PR (https://github.com/php/php-src/pull/1= 7895) that implements this functionality -- all test failures are relate= d to different/new/incorrect error messages being generated. However, th= e core functionality exists to take for a test ride. >=20 > So, what do I mean by "unprecedented amount of control"? With this cha= nge, you can declare an inner class as private or protected, preventing = its usage outside of the outer class: >=20 > class User { > private class Id {} >=20 > public function __construct(public self::Id $id) {} > } >=20 > In the above example, the class `User` is impossible to construct even= though it has a public constructor (except through reflection) because = User::Id is private; User::Id cannot be instantiated, used as a type hin= t, or even via `instanceof` outside of the User class itself. This examp= le isn't practical but demonstrates something that is nearly impossible = in previous versions of PHP, where all classes are essentially publicly = accessible from anywhere within the codebase. >=20 > As a number of inner classes will probably be used as DTOs, the RFC in= troduces a "short syntax" for declaring classes, which enhances expressi= veness, even allowing the usage of traits, all in a single line: >=20 > // declare a readonly Point, that implements Vector2 and uses the Evol= vable trait > readonly class Point(public int $x, public int $y) implements Vector2 = use Evolvable; >=20 > When combined with inner classes, it looks something like this: >=20 > class Pixel { > public readonly class Point(public int $x, public int $y) implements= Vector2 use Evolvable; > } >=20 > // Create a new pixel point with property $x and $y set to 0 > $p =3D new Pixel::Point(0, 0); >=20 > There are far more details in the RFC itself, so please check it out. = I'm quite excited to hear your thoughts! >=20 > =E2=80=94 Rob >=20 > PS. I know I tend to rush into things, but I want to make it clear tha= t I'm not rushing this -- I've learned from my mistakes (thank you to th= ose who have given me advice). I'm going to do this right. >=20 >=20 Hello internals, I've made some major updates to the text of the RFC to clarify behaviors= and revisited the implementation (which is still under development, tho= ugh I hope to have a draft by the end of this weekend). Here's a broad o= verview of what has changed in inner classes: - Accessing inner classes is done via a new token: ":>" instead of "::". - Inner classes may now be infinitely nested. - Inner classes may be declared `abstract`. - Documented changes to ReflectionClass. - Usage of `static` to refer to inner classes is restricted to prevent a= ccidental violations of LSP. Otherwise, there are not any big changes, but a lot of time was spent cl= arifying behavior and expanding on the reasoning for those decisions in = the RFC itself. =E2=80=94 Rob --63f4321edaca478eb340ed0f554f8dcc Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable
On Thu, Mar = 6, 2025, at 00:11, Rob Landers wrote:
Hello PHP Internals,

=
I'd like to introduce my RFC for discussion: https://wiki.php.net/rfc/sho= rt-and-inner-classes

This RFC defines a= short class syntax as well as the ability to nest classes inside anothe= r class. This introduces an unprecedented amount of control, flexibility= , and expressiveness over how objects are used and instantiated in PHP. = There is a PR (htt= ps://github.com/php/php-src/pull/17895) that implements this functio= nality -- all test failures are related to different/new/incorrect error= messages being generated. However, the core functionality exists to tak= e for a test ride.

So, what do I mean by "u= nprecedented amount of control"? With this change, you can declare an in= ner class as private or protected, preventing its usage outside of the o= uter class:

class User {
&nbs= p; private class Id {}

  public functi= on __construct(public self::Id $id) {}
}
In the above example, the class `User` is impossible to cons= truct even though it has a public constructor (except through reflection= ) because User::Id is private; User::Id cannot be instantiated, used as = a type hint, or even via `instanceof` outside of the User class itself. = This example isn't practical but demonstrates something that is nearly i= mpossible in previous versions of PHP, where all classes are essentially= publicly accessible from anywhere within the codebase.
As a number of inner classes will probably be used as DTOs,= the RFC introduces a "short syntax" for declaring classes, which enhanc= es expressiveness, even allowing the usage of traits, all in a single li= ne:

// declare a readonly Point, that imple= ments Vector2 and uses the Evolvable trait
readonly class = Point(public int $x, public int $y) implements Vector2 use Evolvable;

When combined with inner classes, it looks so= mething like this:

class Pixel {
<= div>  public readonly class Point(public int $x, public int $y) imp= lements Vector2 use Evolvable;
}

<= div>// Create a new pixel point with property $x and $y set to 0
$p =3D new Pixel::Point(0, 0);

There= are far more details in the RFC itself, so please check it out. I'm qui= te excited to hear your thoughts!

=E2=80=94 Rob

PS. I know I tend to rush into things, but I want to make i= t clear that I'm not rushing this -- I've learned from my mistakes (than= k you to those who have given me advice). I'm going to do this right.



<= div>Hello internals,

I've made some major u= pdates to the text of the RFC to clarify behaviors and revisited the imp= lementation (which is still under development, though I hope to have a d= raft by the end of this weekend). Here's a broad overview of what has ch= anged in inner classes:

- Accessing inner c= lasses is done via a new token: ":>" instead of "::".
-= Inner classes may now be infinitely nested.
- Inner class= es may be declared `abstract`.
- Documented changes to Ref= lectionClass.
- Usage of `static` to refer to inner classe= s is restricted to prevent accidental violations of LSP.

<= /div>
Otherwise, there are not any big changes, but a lot of time wa= s spent clarifying behavior and expanding on the reasoning for those dec= isions in the RFC itself.

=E2= =80=94 Rob
--63f4321edaca478eb340ed0f554f8dcc--