Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:126864 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 36A211A00BC for ; Thu, 20 Mar 2025 15:28:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1742484353; bh=5OvZUwzr7HkAvvZMm1mYdbSgrRsZ3/VOATrlxHm7MjQ=; h=Date:From:To:Cc:In-Reply-To:References:Subject:From; b=EgLofhvKmisr7oYd7gwR116xDsBqXwsDGkBEaO+6n4aqA2TLKeAMlL69Pk6GjPho7 GfkrlAXQmUdlERLYJcP7fYbCZnAY5hDZHLkVkStkLwqSPaIdZCAH2cs/MtH/aAa7wJ gu3LG5aJCyVm5K5fQzLpcffJ7BzyiaPMAJrraBF3q963cW7KqFSznDVkD2++Dr2Zkg uwUYPVTX47f+JBzqhDQmmYMVXnGnyqlAXEIa6yR9gaBxWuWWQh698n+aptNVPkijh3 6SjoOKAqidBptCCVOxA8lwE5Juy94H1CDvGAK+EVpmryb6fJsSsxVbfRDQrmHj7VwI W1Vz0IFQrAQtQ== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id E43761804DC for ; Thu, 20 Mar 2025 15:25:51 +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 fout-b8-smtp.messagingengine.com (fout-b8-smtp.messagingengine.com [202.12.124.151]) (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 ; Thu, 20 Mar 2025 15:25:51 +0000 (UTC) Received: from phl-compute-11.internal (phl-compute-11.phl.internal [10.202.2.51]) by mailfout.stl.internal (Postfix) with ESMTP id 44CF411401BB; Thu, 20 Mar 2025 11:28:22 -0400 (EDT) Received: from phl-imap-09 ([10.202.2.99]) by phl-compute-11.internal (MEProxy); Thu, 20 Mar 2025 11:28:22 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bottled.codes; h=cc: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=1742484502; x= 1742570902; bh=LBdeIGsOB7TO63TXrSDzyyrK1lvN6h6vnvJUPchpeuI=; b=p PLj6axgOBmFCZQkGC9GdwLCJrOJa4K+zJJmEeFspeMPUrrwPWdOzy/p0fhC9lwMn FMx7pNGJUSHJ5CMTAB2UIZuzhU9b9bRWrBEWxVHF+vr2mE8TAvpZMH5mbYunApZ3 2A8bL8PgDQmKAkbrJuno5OlDluberitU0F9JUpthl4rromwWoEgz8awqw8/kyWYU HvnrB6L/x1QHo4YKI3R5thzfJYsUo4j43GRjJ7PweNboJUAFwv6WCQJBMvQRkGNC xDM78m1C7RaQkI9Kt4IezNvnOEVY3bnbTPM6uarb3yI8JHwUcTMBgSbUgBct9PNZ nuSHfQooXQaiP/zBhi+cQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc: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= 1742484502; x=1742570902; bh=LBdeIGsOB7TO63TXrSDzyyrK1lvN6h6vnvJ UPchpeuI=; b=otae5IUykhPolilChAS5LLJnGABsO+awgNoO5L5QaCP8iuoBoKm EC6Ub+qI0CPNvwdRdAZrfwFIfBh7sZBHknLRLa4nSmBN5Vwj3euSlaTs2X9/Gbyu IrdWM/AeTemZOrHRl1uhyt5bsFUOZpfuaAef5SZ1rrWmtGehhDjuSiUhMpfKzBDF MqmplupLCaHOtB9sN4P6TG/mHG+qif6nVjOyrzL7bjZvSQpO57/QjAnFcD5dgiza TgCotF51qKaYtUr44dhWox0UiGXP88kv035MA52RmSnDh5wrRb1y87Q3Spq7YDf5 2EmoD2OIk4JOQGosZ0wfaxw9PTnWBRLHqSQ== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefvddrtddtgddugeekheejucetufdoteggodetrf dotffvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdggtfgfnhhsuhgsshgtrhhisggv pdfurfetoffkrfgpnffqhgenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpih gvnhhtshculddquddttddmnecujfgurhepofggfffhvfevkfgjfhfutgesrgdtreerredt jeenucfhrhhomhepfdftohgsucfnrghnuggvrhhsfdcuoehrohgssegsohhtthhlvggurd gtohguvghsqeenucggtffrrghtthgvrhhnpeeiueethedvvdefjefhgfeiheelheehtdfh feekjefflefgvedvkeduteejjedttdenucevlhhushhtvghrufhiiigvpedtnecurfgrrh grmhepmhgrihhlfhhrohhmpehrohgssegsohhtthhlvggurdgtohguvghspdhnsggprhgt phhtthhopedvpdhmohguvgepshhmthhpohhuthdprhgtphhtthhopegsohgsfigvihelse hhohhtmhgrihhlrdgtohhmpdhrtghpthhtohepihhnthgvrhhnrghlsheslhhishhtshdr phhhphdrnhgvth X-ME-Proxy: Feedback-ID: ifab94697:Fastmail Received: by mailuser.phl.internal (Postfix, from userid 501) id B6654780069; Thu, 20 Mar 2025 11:28:21 -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 X-ThreadId: Tb82dc1343eb6237f Date: Thu, 20 Mar 2025 16:28:01 +0100 To: "Bob Weinand" Cc: "internals@lists.php.net" Message-ID: <9c4ac301-dfb2-49da-90e5-37a2824fc4e3@app.fastmail.com> In-Reply-To: References: <3e4ba7ea-a154-452d-abfc-05ef1322fade@app.fastmail.com> <782d76d9-711a-4cee-ae0e-fe0d69973f53@app.fastmail.com> <48dce917-d147-456b-9f03-c7e23411adff@app.fastmail.com> <8a16b81c-7dab-4523-a352-76ba0cb4e771@app.fastmail.com> Subject: Re: [PHP-DEV] RFC: short and inner classes Content-Type: multipart/alternative; boundary=584d882e697e448cb1aa0f923d5d2025 From: rob@bottled.codes ("Rob Landers") --584d882e697e448cb1aa0f923d5d2025 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On Thu, Mar 20, 2025, at 16:12, Bob Weinand wrote: >=20 >> Am 20.03.2025 um 15:51 schrieb Rob Landers : >> =EF=BB=BF >>=20 >>=20 >> On Wed, Mar 19, 2025, at 21:09, Bob Weinand wrote: >>>=20 >>>=20 >>> On 19.3.2025 16:04:06, Rob Landers wrote: >>>> On Tue, Mar 18, 2025, at 03:37, Bob Weinand wrote: >>>>> Okay, I see the point with LSP. I'm not sure whether we need to pr= eserve LSP for that specific scenario, but neither can I say that we sho= uld ignore it. >>>>>=20 >>>>> (Effectively implementing LSP would mean that there's an implicit = interface matching all public method signatures of the parent class, for= child classes - which is doable, but possibly too much for the initial = RFC.) >>>>>=20 >>>>> I would however ask, should we not implement LSP compatible inner = classes, to enforce that no child class may name a class the same than a= ny non-private inner class declared by any of its parents, until we reso= lve this question (in possibly a future version of PHP). >>>>> I do not think we should bar ourselves from allowing this in the f= uture. >>>>=20 >>>> I'm not sure I understand what you are asking. But I think you are = saying the following should be illegal? >>>>=20 >>>> class ParentOuter { >>>> class ParentInner {} >>>> } >>>>=20 >>>> class ChildOuter extends ParentOuter { >>>> class ParentInner {} // not allowed >>>> } >>> Precisely. >>>=20 >>>>> And not pretending starts with using a different symbol than a bac= kslash. >>>>=20 >>>> I have been thinking about this for a couple of days now... When th= inking through the ramifications of my decision to use :> over ::, this = will also affect generics, most likely -- whenever that happens. This is= because if this RFC passes, generics will want to be consistent with wh= atever exists currently. >>>>=20 >>>> If we were to use :>, then generics would probably look something l= ike this to be consistent: >>>>=20 >>>> class Box { >>>> public function add(self:>T $item) {} >>>> } >>>>=20 >>>> The same thing would also probably apply to :: >>>>=20 >>>> class Box { >>>> public function add(self::T $item) {} >>>> } >>>>=20 >>>> With `\`, it nearly follows exactly what you would expect-ish: >>>>=20 >>>> use \Box\T as T; >>>>=20 >>>> class Box { >>>> public function add(T $item) {} >>>>=20 >>>> // or without use >>>> public function add(Box\T $item) {} >>>> } >>>>=20 >>>> With `\`, we can also just automatically check the current class as= part of namespace resolution when compiling: >>>>=20 >>>> class Box { >>>> public function add(T $item) {} >>>> } >>>>=20 >>>> This would also make it easier to user inner classes: >>>>=20 >>>> class Outer { >>>> public class Inner {} >>>> public function foo(Inner $bar) {} >>>> } >>>>=20 >>>> The other syntax options do not allow this; at least, I don't think= so. I'm very heavily leaning towards `\` as the separator. >>>>=20 >>>> =E2=80=94 Rob >>> I'm failing to understand why you'd think this would be related at a= ll? >>>=20 >>> If we get generics, >>>=20 >>> class Box { >>> public function add(T $item) {} >>> } >>>=20 >>> would just work, without any use or such. There will not be a symbol= Box::T or Box\T, just all mentions of T within the Box class will be ta= ken as "this is the generic placeholder" and the compiler takes care. >>> It's not like that T will be directly accessible from outside of the= class or actually a proper type, unlike inner classes. >>>=20 >>> A generic is not an inner class nor will it look like it. Also, ther= e's no accessing of a parents generic - you write class Child extends= ParentClass - or something along these lines, getting the T availabl= e for your class. >>>=20 >>> Bob >>=20 >> Yes, that is the question right? It might not affect anything there, = but there would probably be an argument to keep it consistent with inner= classes. In PHP, a class is a type; thus an inner class is an inner typ= e, and generic types are also an inner type that only exist in the scope= of their enclosing class, just like private inner classes. >>=20 >> If my logic is incorrect, let me know. >>=20 >> =E2=80=94 Rob >=20 > The difference is that inner classes are a backed type; there's actual= ly a class/interface/enum/... behind it. >=20 > Generic placeholders are placeholders for another type, which is stric= tly local to the compilation of the class. >=20 > Bob If that were the case, then this would be an error: function add(T $item) { if ($item instanceof T) {} } because T isn't a backed type. I don't think they are the same thing, bu= t during runtime, T is most definitely a backed-type; not an empty box. = You still have to refer to T in some way, and I'm of the opinion that se= lf:>T is not ideal (I think we can probably all agree on that?). Even in= inner classes, it seems to make more sense to just treat it like you wo= uld any other type in the current namespace. I think Rowan makes a good argument about other languages, where naming = collisions are not an issue. Ilija has also made some good arguments. I = have some time next week to implement this and see how it feels. =E2=80=94 Rob --584d882e697e448cb1aa0f923d5d2025 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable

=
On Thu, Mar 20, 2025, at 16:12, Bob Weinand wrote:

<= /div>
Am 20.03.2025 um 15= :51 schrieb Rob Landers <rob@bottled.codes>:
=EF=BB=BF


On Wed, Mar 19, 2025, at 21:09, Bob= Weinand wrote:


On 19.3.2025 16:04:06= , Rob Landers wrote:
On Tue, Mar 18, = 2025, at 03:37, Bob Weinand wrote:

Okay, I see the point with LSP. I'm not sure= whether we need to preserve LSP for that specific scenario, but neither= can I say that we should ignore it.

(Effectively implementing= LSP would mean that there's an implicit interface matching all public m= ethod signatures of the parent class, for child classes - which is doabl= e, but possibly too much for the initial RFC.)

I would howev= er ask, should we not implement LSP compatible inner classes, to enforce= that no child class may name a class the same than any non-private inne= r class declared by any of its parents, until we resolve this question (= in possibly a future version=0A of PHP).
I do not think we= should bar ourselves from allowing this in the future.

I'm not sure I understand what you are asking.= But I think you are saying the following should be illegal?

class ParentOuter {
  class ParentI= nner {}
}

class ChildOuter ex= tends ParentOuter {
  class ParentInner {} // not all= owed
}

Precisely.

A= nd not pretending starts with using a different symbol than a backslash.=

I have been thinking about th= is for a couple of days now... When thinking through the ramifications o= f my decision to use :> over ::, this will also affect generics, most= likely -- whenever that happens. This is because if this RFC passes, ge= nerics will=0A want to be consistent with whatever exists currently.
=

If we were to use :>, then generics would p= robably look something like this to be consistent:

class Box<T> {
  public function add(se= lf:>T $item) {}
}

The same= thing would also probably apply to ::

clas= s Box<T> {
  public function add(self::T $item)= {}
}

With `\`, it nearly fol= lows exactly what you would expect-ish:

use= \Box\T as T;

class Box<T> {
  public function add(T $item) {}

// or without use
  public function add(Box\T $item= ) {}
}

With `\`, we can also = just automatically check the current class as part of namespace resoluti= on when compiling:

class Box<T> {
=
  public function add(T $item) {}
}

This would also make it easier to user inner clas= ses:

class Outer {
  pub= lic class Inner {}
  public function foo(Inner $bar) = {}
}

The other syntax options= do not allow this; at least, I don't think so. I'm very heavily leaning= towards `\` as the separator.

=E2=80=94 Rob

I'm failing to unde= rstand why you'd think this would be related at all?

If we get= generics,

class Box<T> {
  public = function add(T $item) {}
}

wo= uld just work, without any use or such. There will not be a symbol Box::= T or Box\T, just all mentions of T within the Box class will be taken as= "this is the generic placeholder" and the compiler takes care.
It's not like that T will be directly accessible from outside of t= he class or actually a proper type, unlike inner classes.
=
A generic is not an inner class nor will it look like it.= Also, there's no accessing of a parents generic - you write class Child= <T> extends ParentClass<T> - or something along these lines,= getting the T available for your class.

Bo= b

Yes, that is the question ri= ght? It might not affect anything there, but there would probably be an = argument to keep it consistent with inner classes. In PHP, a class is a = type; thus an inner class is an inner type, and generic types are also a= n inner=0A type that only exist in the scope of their enclosing class, j= ust like private inner classes.

If my logic= is incorrect, let me know.

=E2=80=94 Rob

Th= e difference is that inner classes are a backed type; there's actually a= class/interface/enum/... behind it.

Generi= c placeholders are placeholders for another type, which is strictly loca= l to the compilation of the class.

Bob
<= /div>

If that were the case, then this w= ould be an error:

function add(T $item) {
  if ($item instanceof T) {}
}
=

because T isn't a backed type. I don't think they ar= e the same thing, but during runtime, T is most definitely a backed-type= ; not an empty box. You still have to refer to T in some way, and I'm of= the opinion that self:>T is not ideal (I think we can probably all a= gree on that?). Even in inner classes, it seems to make more sense to ju= st treat it like you would any other type in the current namespace.
<= /div>

I think Rowan makes a good argument about other= languages, where naming collisions are not an issue. Ilija has als= o made some good arguments. I have some time next week to implement this= and see how it feels.

= =E2=80=94 Rob
--584d882e697e448cb1aa0f923d5d2025--