Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:125174 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 DDB711A00BD for ; Fri, 23 Aug 2024 21:55:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1724450238; bh=J7n+uUnOag1SAg+aRc69rRqwDCSXUh7cUntksHSpwoc=; h=Date:From:To:In-Reply-To:References:Subject:From; b=J2Q17liHhAvK1wjvqeSkgnvwOlezs8IFRPxY15k/tFUiet24F/uW1oK8L1Sz7+RiG mdh4IUhtRIN+RXiLkCfd58zoHKb5Z8lSZiBDSpKHuHBD/hg7680uVag9nU66BUsOAp Rcds9VHjzCeM1mQVo4V/t3k4nJVYQsY5NoPyjNiKrz3Ihuyc4c/VarnyB37wI6om88 dKnvC58okkpDr9OuTT2es6g7UvW4ul0vYTBKCmH3CMtY6yrZGr0m6t/Fy+HtrCSzPx Fl7yfCWnw0VdZHd7d+0Ld+jorWyBcUgWG6HYQqFCmWl9uqbL7W+YJBarhma838NLqT UPeFgCIptG/+Q== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id D69C618038F for ; Fri, 23 Aug 2024 21:57:17 +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=-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,RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,SPF_HELO_PASS, SPF_PASS autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: No X-Envelope-From: Received: from fhigh2-smtp.messagingengine.com (fhigh2-smtp.messagingengine.com [103.168.172.153]) (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 ; Fri, 23 Aug 2024 21:57:17 +0000 (UTC) Received: from phl-compute-03.internal (phl-compute-03.nyi.internal [10.202.2.43]) by mailfhigh.nyi.internal (Postfix) with ESMTP id BC9ED11501AE for ; Fri, 23 Aug 2024 17:55:25 -0400 (EDT) Received: from phl-imap-09 ([10.202.2.99]) by phl-compute-03.internal (MEProxy); Fri, 23 Aug 2024 17:55:25 -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=1724450125; x=1724536525; bh=Tq9+R1HqGa m39rIfSHVFMxNJhk+IQnhvq7TKCjXrSgA=; b=K4Ms3dOrpg0TSZUZdtvM2M2vRD nJ4TKQjK66Ij5pvYRPmGL+SpGE9o0AxWoxTJl/o5BM3nLjpHp/BcMH4qgzeZ+tKh B2QpbG0sfGNP0OHhKmJh3bXaXAy5GUexDMNyKpk6skGpkZM2h+X35P5fzGkpSlIE HfMw25vDOkzHQqXrYrwYSkGE4cod1OL+zuGtE5xQs8Im2eO/dHcEIwYfqI3YRjxU //zXjfKwLXWKSLBiOVjrT2T2AvnrfAxmwPxm+y8XIlp5YcmNiyhkXvMnDngTpBRU 7dgEzKcAKlI2Rcwt44mVffGWk6oEtwOwixIlo/OKQTXcRqbkx016d9u5Fv4g== 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-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; t=1724450125; x=1724536525; bh=Tq9+R1HqGam39rIfSHVFMxNJhk+I Qnhvq7TKCjXrSgA=; b=AGOyQzOB/JAv/hWfsTOJbwNC7LYKqPt2gev4RLv/aMHZ +JA8sMlP23BpJPyI0ysSyGTa8IJ9D3IwnXehPTGcmM50PfBh7+gYh7fIH7rtTSZ9 wAmpYOmxoeJqkDwzJQLu++FoEPwIS4D8/XhurYFNtZs6EmXxP962YwEnQmc/Jf8N TAZaM9A/R887mO8ogfHo284JC+QKZmKiRQmW5ZvySegDtE0CMf7fD4tOVZeCXGIz RtgQp9RUDO47DjjPpE9abaoqBFfIb7Lv9PVpMQ9xgNWQiw5QkhWmTmD5p5nUcFdk pXysEG2VAqCLXxRAqFpTi2QJ/rCrQaKhflWG2L3UaA== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeeftddruddvfedgtdefucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdggtfgfnhhsuhgsshgtrhhisggvpdfu rfetoffkrfgpnffqhgenuceurghilhhouhhtmecufedttdenucgoufhushhpvggtthffoh hmrghinhculdegledmnecujfgurhepofggfffhvffkjghfufgtsegrtderreertdejnecu hfhrohhmpedftfhosgcunfgrnhguvghrshdfuceorhhosgessghothhtlhgvugdrtghoug gvsheqnecuggftrfgrthhtvghrnheptdeitddvvdevhfdufffhgeelffetgeffveekheek feeluedutdeiveekvdetjedvnecuffhomhgrihhnpeefvheglhdrohhrghenucevlhhush htvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehrohgssegsohhtthhl vggurdgtohguvghspdhnsggprhgtphhtthhopedupdhmohguvgepshhmthhpohhuthdprh gtphhtthhopehinhhtvghrnhgrlhhssehlihhsthhsrdhphhhprdhnvght X-ME-Proxy: Feedback-ID: ifab94697:Fastmail Received: by mailuser.nyi.internal (Postfix, from userid 501) id 65D65780065; Fri, 23 Aug 2024 17:55:25 -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: Fri, 23 Aug 2024 23:55:04 +0200 To: internals@lists.php.net Message-ID: <0a8ada40-9784-42c8-8eda-e33a08a3bff3@app.fastmail.com> In-Reply-To: <7c617909-c019-4a3d-bee9-8e4b0f949acf@app.fastmail.com> References: <1b59392a-68cb-36eb-0fef-977ac7113520@php.net> <7c617909-c019-4a3d-bee9-8e4b0f949acf@app.fastmail.com> Subject: Re: [PHP-DEV] State of Generics and Collections Content-Type: multipart/alternative; boundary=a0dff17cc9bd46dd8fcabc98f40bd393 From: rob@bottled.codes ("Rob Landers") --a0dff17cc9bd46dd8fcabc98f40bd393 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On Fri, Aug 23, 2024, at 23:06, Larry Garfield wrote: > On Fri, Aug 23, 2024, at 1:38 PM, Rob Landers wrote: > > On Fri, Aug 23, 2024, at 20:27, Bruce Weirdan wrote: > >> On Fri, Aug 23, 2024 at 4:27=E2=80=AFPM Larry Garfield wrote: > >>> Moving those definitions to attributes is certainly possible, thou= gh AFAIK both the PHPStan and Psalm devs have expressed zero interest in= it. > >>> Part of the challenge is that such an approach will either still i= nvolve string parsing, > >>=20 > >> That's not really a challenge and would help somewhat with the curr= ent status quo where we have to guess where the type ends and the textua= l part of the comment begins. But it gets ugly for any type that has to = include quotes (literal strings, array keys, etc). Technically one can u= se nowdocs, but it's not much better: https://3v4l.org/4hpte > >> =20 > >>> or will involve a lot of deeply nested attribute classes.=20 > >>=20 > >> Yeah, that would look like Lisp's S-exprs, but much worse - which, = in my opinion, would harm adoption. > >>=20 > >> All in all, in my opinion attribute-based solutions are less ergono= mic than what we already have now in docblocks. > >>=20 > >> -- > >> Best regards, > >> Bruce Weirdan mailto:weir= dan@gmail.com > > > > Thank you Larry for expressing some of the problems. Is there any=20 > > reason nesting has to be supported out of the gate? Think about type=20 > > hints. It started with some basic functionality and then grew over=20 > > time. There is no reason we have to have a new kitchen sink, oven,=20 > > dishwasher and stove when all we want is a new refrigerator.=20 > > > > =E2=80=94 Rob >=20 > While I understand the temptation to "just do part of it", which comes= up very often, I must reiterate once again that can backfire badly. Th= at is only sensible when: >=20 > 1. There's a very clear picture to get from A->Z. > 2. The implementation of C and D cannot interfere with the design or i= mplementation of J or K. > 3. The steps along the way offer clear self-contained benefits, such t= hat if nothing else happens, it's still a "complete" system and a win. > 4. The part being put off to later isn't just putting off the "hard pa= rt". >=20 > In practice, the level at which you get all four is quite coarse, much= coarser than it seems most people on this list think. I wasn't intending to just say "just do it," but rather, is it "good eno= ugh." As I mentioned in another email on this topic, right now there is = only one person in the world who can work on the problem. Sure, we can l= eave drive-by comments and our own experiences/opinions here and on gith= ub, but ultimately, the knowledge of how it works and how it can be impr= oved exists solely within one (or thereabouts) person's brain; on the en= tire planet. This is sort-of how when we write software, we try to keep small PRs. Sm= all PRs can be reviewed quickly and merged. Other developers on the team= can start interacting with the code, even if the feature that it pertai= ns to is incomplete. From that point forward, other developers can impro= ve that code, separately from the person who is working on the feature. = The knowledge of how it works is shared and people with different perspe= ctives and experiences can make it better. >=20 > Examples of where we have done that: >=20 > * Enums. The initial Enum RFC is part one of at least 3 steps. Step = 2 is pattern matching, Step 3 is ADTs/tagged unions. Those are still co= ming, but all three were spec'ed out in advance (1), we're fairly confid= ent that the enum design will play nice with tagged unions (2), and enum= s step 1 has very clearly been hugely positive for the language (3, 4). >=20 > * Property hooks and aviz. These were designed together. They were o= riginally a single planning document, way back in Nikita's original RFC.= After effectively doing all the design work of both together, we split= up the implementations to make them easier. Hooks was still a large RF= C, but that was after we split things up. That meant we had a clear pic= ture of how the two would fit together (1, 2), either RFC on its own wou= ld have been beneficial to the language even if they're better together = (2, 3), and both were substantial tasks in themselves (4). >=20 > * Gina's ongoing campaign to make PHP's type juggling have some passin= g resemblance to logic. >=20 > With generics, the syntax isn't the hard part. The hard part is type = inference, or accepting that generic-using code will just be extraordina= rily verbose and clumsy. There is (as I understand from Arnaud, who aga= in can correct me if I'm wrong) not a huge amount of difference in effor= t between supporting only Foo and supporting Foo>. The ne= sting isn't the hard part. The hard part is not having to type Foo= 4 times across 2 files every time you do something with generics. If t= hat can be resolved satisfactorily (and performantly), then the road map= to reified generics is reasonably visible. Ok. But wasn't there something about nesting causing super-linear perfor= mance issues? So, disable nesting and don't worry about inference. Obvio= usly, people will want these things. I do remember a time in PHP where y= ou had to type out function() use (stuff) {} for every little anonymous = function call. It was super annoying. However, I don't think PHP would h= ave ever even existed if someone didn't say "it is good enough for now." Maybe Arnaud can solve inference, all by themselves with whatever resour= ces can be thrown at them, but what if it comes to people actually using= it ... and they hate inference? PHP is a verbose language, so it isn't = that unthinkable. But seriously, that would be quite a waste of time and= effort. Instead of striving for perfection from the beginning, strive for gettin= g something working that people are actually asking for (generics=E2=80=94= nobody is asking for inference) and gather feedback. Maybe nobody actual= ly wants inference, or they want a type of inference that only makes sen= se once you start using it that you can't even guess about right now. >=20 > So for any intermediate generics implementation, it would need to have= a very clear picture to get from that initial state to the final state = (without the landmines that something like readonly gave us), we'd need = to be confident we're not adding any landmines, each step would need to = be useful in its own right, and it would have to be breaking up the "har= d work" into reasonable chunks, not just punting the hard work for later. >=20 > Leaving out nested generics doesn't achieve those. See above. But if the actual issue is inference, then leave that out. >=20 > This is also why the dedicated collections work that Derick and I were= looking into has been on pause, because adding a dedicated collections = syntax, and then getting full reified generics later, would lead to a ve= ry ugly mess of inconsistency. Better to wait and try to get full gener= ics first, or confirm once and for all that it's impossible. >=20 > Strategies that MIGHT make sense in that framework, and the ones on wh= ich we are specifically requesting feedback, include: >=20 > * Type-erased generics, with the expectation that they would become en= forced at some point in the future. (Though this could lead to lots of = "working" code suddenly not working once the enforcement was turned on.) Personally, this would be interesting because you'd have go-like semanti= cs. It wouldn't actually have to implement the interface, just have the = same methods/properties. It also leads to interesting thoughts in that you don't even need to do = type-checking at function/method boundaries, only when/if it is used. Bu= t that would probably require some pretty big changes to zvals/type jugg= ling. I don't work here, so all I can give is advice and a little bit of= time. But, I suspect that if someone wanted to, type checking/juggling = could be 5-10x faster than it currently is. > * No type inference. Generics are just very verbose, deal with it. T= ype inference could, potentially, be added later. (Maybe; it's not guar= anteed that it could be done effectively, as the writeup discusses). IIRC, typescript didn't have proper inference until years later. For exa= mple, initially, it could only infer primitive types (similar to PHP, re= ally). > * Only allow generics over simple types, not union/intersection types.= Unlike nested generics, union types do increase the cost of determinin= g compatibility considerably, so making them performant is a much bigger= challenge. Maybe that challenge could be punted for later? (And if la= ter turns into never, or 10 years from now, is that still an acceptable = end-state?) Ah, this is what I was thinking of. Thank you. Yeah, instead of "nesting= " prior, I was referring to union types. >=20 > The acceptability of each of these strategies is what we were hoping t= o determine in feedback to the writeup. >=20 > --Larry Garfield >=20 =E2=80=94 Rob --a0dff17cc9bd46dd8fcabc98f40bd393 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable
On Fri, Aug 23,= 2024, at 23:06, Larry Garfield wrote:
On Fri, Aug 23, 2024, at 1:38 PM, Rob Lander= s wrote:
> On Fri, Aug 23, 2024, at 20:27, Bruce Weirda= n wrote:
>> On Fri, Aug 23, 2024 at 4:27=E2=80=AFPM = Larry Garfield <larry@garfi= eldtech.com> wrote:
>>> Moving those defin= itions to attributes is certainly possible, though AFAIK both the PHPSta= n and Psalm devs have expressed zero interest in it.
>&= gt;> Part of the challenge is that such an approach will either still= involve string parsing,
>> 
>= > That's not really a challenge and would help somewhat with the curr= ent status quo where we have to guess where the type ends and the textua= l part of the comment begins. But it gets ugly for any type that has to = include quotes (literal strings, array keys, etc). Technically one can u= se nowdocs, but it's not much better:  https://3v4l.org/4hpte
>>  = ;
>>> or will involve a lot of deeply nested attr= ibute classes. 
>> 
>>= Yeah, that would look like Lisp's S-exprs, but much worse - which, in m= y opinion, would harm adoption.
>> 
>> All in all, in my opinion attribute-based solutions are less= ergonomic than what we already have now in docblocks.
>= ;> 
>> --
>>  = Best regards,
>>      = ; Bruce Weirdan         &nb= sp;           &nb= sp;           &nb= sp;   mailto:weirdan@gmai= l.com
>
> Thank you Larry for expr= essing some of the problems. Is there any 
> reaso= n nesting has to be supported out of the gate? Think about type 
> hints. It started with some basic functionality and the= n grew over 
> time. There is no reason we have to= have a new kitchen sink, oven, 
> dishwasher and = stove when all we want is a new refrigerator. 
>
> =E2=80=94 Rob

While I und= erstand the temptation to "just do part of it", which comes up very ofte= n, I must reiterate once again that can backfire badly.  That is on= ly sensible when:

1. There's a very clear p= icture to get from A->Z.
2. The implementation of C and= D cannot interfere with the design or implementation of J or K.
3. The steps along the way offer clear self-contained benefits, s= uch that if nothing else happens, it's still a "complete" system and a w= in.
4. The part being put off to later isn't just putting = off the "hard part".

In practice, the level= at which you get all four is quite coarse, much coarser than it seems m= ost people on this list think.

I wasn't intending to just say "just do it," but rather, is it "good en= ough." As I mentioned in another email on this topic, right now there is= only one person in the world who can work on the problem. Sure, we can = leave drive-by comments and our own experiences/opinions here and on git= hub, but ultimately, the knowledge of how it works and how it can be imp= roved exists solely within one (or thereabouts) person's brain; on the e= ntire planet.

This is sort-of how when we w= rite software, we try to keep small PRs. Small PRs can be reviewed quick= ly and merged. Other developers on the team can start interacting with t= he code, even if the feature that it pertains to is incomplete. From tha= t point forward, other developers can improve that code, separately from= the person who is working on the feature. The knowledge of how it works= is shared and people with different perspectives and experiences can ma= ke it better.


Examples of where we have done that:

* Enums.  The initial Enum RFC is part one o= f at least 3 steps.  Step 2 is pattern matching, Step 3 is ADTs/tag= ged unions.  Those are still coming, but all three were spec'ed out= in advance (1), we're fairly confident that the enum design will play n= ice with tagged unions (2), and enums step 1 has very clearly been hugel= y positive for the language (3, 4).

* Prope= rty hooks and aviz.  These were designed together.  They were = originally a single planning document, way back in Nikita's original RFC= .  After effectively doing all the design work of both together, we= split up the implementations to make them easier.  Hooks was still= a large RFC, but that was after we split things up.  That meant we= had a clear picture of how the two would fit together (1, 2), either RF= C on its own would have been beneficial to the language even if they're = better together (2, 3), and both were substantial tasks in themselves (4= ).

* Gina's ongoing campaign to make PHP's = type juggling have some passing resemblance to logic.

=
With generics, the syntax isn't the hard part.  The hard= part is type inference, or accepting that generic-using code will just = be extraordinarily verbose and clumsy.  There is (as I understand f= rom Arnaud, who again can correct me if I'm wrong) not a huge amount of = difference in effort between supporting only Foo<Bar> and supporti= ng Foo<Bar<Baz>>.  The nesting isn't the hard part.&nbs= p; The hard part is not having to type Foo<Bar> 4 times across 2 f= iles every time you do something with generics.  If that can be res= olved satisfactorily (and performantly), then the road map to reified ge= nerics is reasonably visible.

= Ok. But wasn't there something about nesting causing super-linear perfor= mance issues? So, disable nesting and don't worry about inference. Obvio= usly, people will want these things. I do remember a time in PHP where y= ou had to type out function() use (stuff) {} for every little anonymous = function call. It was super annoying. However, I don't think PHP would h= ave ever even existed if someone didn't say "it is good enough for now."=

Maybe Arnaud can solve inference, all by t= hemselves with whatever resources can be thrown at them, but what if it = comes to people actually using it ... and they hate inference? PHP is a = verbose language, so it isn't that unthinkable. But seriously, that woul= d be quite a waste of time and effort.

Inst= ead of striving for perfection from the beginning, strive for getting so= mething working that people are actually asking for (generics=E2=80=94no= body is asking for inference) and gather feedback. Maybe nobody actually= wants inference, or they want a type of inference that only makes sense= once you start using it that you can't even guess about right now.


=
So for any intermediate generics implementation, it would nee= d to have a very clear picture to get from that initial state to the fin= al state (without the landmines that something like readonly gave us), w= e'd need to be confident we're not adding any landmines, each step would= need to be useful in its own right, and it would have to be breaking up= the "hard work" into reasonable chunks, not just punting the hard work = for later.

Leaving out nested generics does= n't achieve those.

See above. = But if the actual issue is inference, then leave that out.

This is also why the dedicated collections work that Derick and I were= looking into has been on pause, because adding a dedicated collections = syntax, and then getting full reified generics later, would lead to a ve= ry ugly mess of inconsistency.  Better to wait and try to get full = generics first, or confirm once and for all that it's impossible.

Strategies that MIGHT make sense in that framewor= k, and the ones on which we are specifically requesting feedback, includ= e:

* Type-erased generics, with the expecta= tion that they would become enforced at some point in the future.  = (Though this could lead to lots of "working" code suddenly not working o= nce the enforcement was turned on.)

Personally, this would be interesting because you'd have go-like s= emantics. It wouldn't actually have to implement the interface, just hav= e the same methods/properties.

It also lead= s to interesting thoughts in that you don't even need to do type-checkin= g at function/method boundaries, only when/if it is used. But that would= probably require some pretty big changes to zvals/type juggling. I don'= t work here, so all I can give is advice and a little bit of time. But, = I suspect that if someone wanted to, type checking/juggling could be 5-1= 0x faster than it currently is.

* No type inference.  Generics are = just very verbose, deal with it.  Type inference could, potentially= , be added later.  (Maybe; it's not guaranteed that it could be don= e effectively, as the writeup discusses).
IIRC, typescript didn't have proper inference until years la= ter. For example, initially, it could only infer primitive types (simila= r to PHP, really).

* Only allow generics over simple types, not union/= intersection types.  Unlike nested generics, union types do increas= e the cost of determining compatibility considerably, so making them per= formant is a much bigger challenge.  Maybe that challenge could be = punted for later?  (And if later turns into never, or 10 years from= now, is that still an acceptable end-state?)

Ah, this is what I was thinking of. Thank you. Yeah, ins= tead of "nesting" prior, I was referring to union types.

<= /div>

= The acceptability of each of these strategies is what we were hoping to = determine in feedback to the writeup.

--Lar= ry Garfield


=E2=80=94 Rob
--a0dff17cc9bd46dd8fcabc98f40bd393--