Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:123766 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 72F5D1A009C for ; Sun, 23 Jun 2024 18:30:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1719167523; bh=s/hC+VAgZym3H2x1HCwxLtbiiwx9Dfmli3NDvJ/mt/w=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=NwcPiViFrYPKHrRzTr8nj8Cpz72OIzSEkKTnC7IICefn+P1n9MkLi7QZDsUGo4Yxo WvFpJ+OyNw471nW2JKcFnux8CLOSz43A+9kf3cgyHHsh/wT16Z2kulPYCmgS6MVIOU aUJcNP/m/Z/1+ZQ3xySoqgFexLn/A7jjGMsUQ+unf7ly51onjRbtA1c7gxFeP8oZuE FFvH+gf8GQLamo1XwhSqzmbss5iPqGtxlaC+OmsLABlMa5IVD/e7hpUV5x7K2+n/5t /LgwjDQL8exZ7yE8nQ/hDLpsfCkSACdUUiCxxqBIs5ipOlZreAWJhg6Td3Nca0BKE1 4NmdAK/JI+RDw== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 298C618005F for ; Sun, 23 Jun 2024 18:32:02 +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.6 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: Error (Cannot connect to unix socket '/var/run/clamav/clamd.ctl': connect: Connection refused) X-Envelope-From: Received: from mail-lf1-f50.google.com (mail-lf1-f50.google.com [209.85.167.50]) (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 ; Sun, 23 Jun 2024 18:32:01 +0000 (UTC) Received: by mail-lf1-f50.google.com with SMTP id 2adb3069b0e04-52cd717ec07so2469498e87.0 for ; Sun, 23 Jun 2024 11:30:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1719167444; x=1719772244; darn=lists.php.net; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=vFV1wf9xqFG8bHsrEhzrCRFnp00cWI3OXdyvt+t3NtI=; b=SLS5umkCdooE4Q0EtaoWT750Pwt3XWy6bQVmDnUrHJ/NAfVbRQsd5g/f+SsLg5u1vV Xt/fRQqlh7NDVeNFKvXOxCNVufm/5piHGl6nWQ3/M/M/zgub3ywSwXp74a83tm2POdYh D6MGRrorV6wA9bQFgo+95TmnOsq56AWIjg0Xnt6EqAkjn1KraSOSf9Z6XjRb658yVdEm RK5Vfy6E3QW955RMtNnrsQK992YkyCjcvEN9DHpRJh6GKY7q6Eq7AvafMJT42MsZKyx+ RfF7USjSGb8RGRiHxvuEP4eUlglei39nDSXgB1nS3Vg3irafIjNvCDxYw+yaFerq8KXQ VRXA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719167444; x=1719772244; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=vFV1wf9xqFG8bHsrEhzrCRFnp00cWI3OXdyvt+t3NtI=; b=bPcgRjHeQM5cFgSpmM3pfPLQR6dSl6xi+QNpqQwDyMSqvb/OntHayH6gbiDwgTa/ZI cIblrdM4kyuMiAXLJj9tIFrLi8brTOSlygoX/wl4sbWYEzeBpwZxdQkUqYPH14KFA+TP fTV9JgVHq3ElwMFmRnSt+UsNa5qbXMcqgbh3RukEo+3PemECbssG6B1MJiezEAb+AsPk cUe2fCgbSHrhrmPgXEAWMtZTQoTOmgzG/EKAWpVPN79epdh6xQkRrO1LXO0KWC7zZ8m+ +kwGavAHjgW458yYKrJwxvRjvaopGUivOrt6AgHaz/M+k6bBVhy1UdidMA2ITNNvTfbi 7clA== X-Gm-Message-State: AOJu0YxLDjm6xjmS5U4ljfR6XXI6mLrx2HiN2qsaUjNI8Ee69npekPWg UTe3zbn+uH1cIyO7I3RE13lglnF3RYKg0ISoVkeMA1YXQ9g0wfFtqD842g9Ym9uoK59nG55mVTC +wB68J5/DzD+40M2tQIFb7a1eFidHzTp+0Ow= X-Google-Smtp-Source: AGHT+IFAoSkcY8am3GmHA4nIovvnVASX0KcDCu47FS6sAvyATbYEKY5wZZ2teqjmI0dKjEx6PsM8pcYuUy2jU/FX8fQ= X-Received: by 2002:ac2:5ded:0:b0:52c:8b72:3cdd with SMTP id 2adb3069b0e04-52ce185d01cmr1697965e87.47.1719167443872; Sun, 23 Jun 2024 11:30:43 -0700 (PDT) Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net MIME-Version: 1.0 References: <2a6b92eb-d5e9-4a1a-9548-a068ac42ebd2@app.fastmail.com> <978b7177-8a22-41c0-94ce-d5539a2468c5@app.fastmail.com> <642D9E7C-0328-4F30-8B09-3DB4AF42914C@rwec.co.uk> In-Reply-To: <642D9E7C-0328-4F30-8B09-3DB4AF42914C@rwec.co.uk> Date: Sun, 23 Jun 2024 20:30:32 +0200 Message-ID: Subject: Re: [PHP-DEV] [Early Feedback] Pattern matching To: "Rowan Tommins [IMSoP]" Cc: internals@lists.php.net Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable From: landers.robert@gmail.com (Robert Landers) On Sun, Jun 23, 2024 at 2:19=E2=80=AFPM Rowan Tommins [IMSoP] wrote: > > > > On 22 June 2024 22:57:24 BST, Robert Landers w= rote: > >In general, you assign the result of the operation so that the output > >is useful. Here's how that might look in PHP with the C# rules: > > > >function foo(BarInterface $bar) { > > $baz =3D $bar as Baz; > > $baz?->thing(); > > $bar->otherThing(); > >} > > > The difference is that in C#, there is an actual difference between the m= ethods available on $bar and $baz. The "as" is performing a conversion, so = the English word makes sense. > Ah, I see what you mean. Yeah, PHP doesn't understand type casts too well (as in class/interface-types) but they are there, just clunky to deal with. Here's some real-ish code with a bunch of things stripped out: abstract class Event {} interface HasInnerEvent { public function getInnerEvent(): Event; } interface DelayedEvent { public function getDelay(): int; } class ScheduleTask extends Event implements HasInnerEvent, DelayedEvent { .= .. } class Signal extends Event { ... } Then when receiving an event: function storeEventLocally(DelayedEvent $event): void; function handleInnerEvent(HasInnerEvent $event): void; /** @var Event $event */ foreach ($events as $event) { if ($event instanceof DelayedEvent) { storeEventLocally($event); continue; } if ($event instanceof HasInnerEvent) { handleInnerEvent($event); } } With only "is" it doesn't change much (if at all, structurally), but with the C# rules, I only need a few changes, and it becomes much more readable (IMHO): function storeEventLocally(DelayedEvent|null $event): void; function handleInnerEvent(HasInnerEvent|null $event): void; /** @var Event $event */ foreach ($events as $event) { storeEventLocally($shouldContinue =3D $event as DelayedEvent); if ($shouldContinue) continue; $mainEvent =3D handleInnerEvent($event as HasInnerEvent); } > In PHP, all we could do is have a one-off runtime check, then return the = value unchanged. So written out in full, that would be: > > function foo(BarInterface $bar) { > $baz =3D null; > if ( $bar is Baz ) $baz =3D $bar; > $baz?->thing(); > $bar->otherThing(); > } > > Or: > > function foo(BarInterface $bar) { > $baz =3D $bar; > if ( ! $bar is Baz ) $baz =3D null; > $baz?->thing(); > $bar->otherThing(); > } > > > I can see some use in a shorthand for that, but it doesn't have much in c= ommon with casts, or any meaning of "as" that I can think of, so I don't th= ink that would be the right name for it. > "as" is just fancy casting (usually), but PHP doesn't have any real casts other than scalars so it makes the feature itself hard to grok, and tossing in errors makes the entire example I showed completely pointless because it would fail. In fact, I am not sure what the case is for an "as" that throws now that I've written it out a few times. > > > >With fibers/async, "as" is actually more important than "is" (at least > >as far as crashing goes): > > > >class Foo { > > public BarInterface $bar; > > > > public function doStuff() { > > $baz =3D $this->bar as Baz; > > // some stuff with $baz > > callComplexThing(); // suspends current fiber, > > // $this->bar is no longer the same object > > // or concrete type when we return > > $baz->something(); > > } > >} > > > The thing that's stopping this crashing is not the "as", it's that you're= backing up the old value of $this->bar into a local variable. Nothing abou= t $baz will "remember" that you made some type or pattern check against it = just before/after you assigned it. I was pointing out issues with the inherent patterns they propose, but you're not wrong. :) > > > > >However, it becomes far more useful to dealing with > >scalar casts: > > > >function foo(int $type) {} > > > >foo(123.456 as int); // crashes > >foo(null as int); // crashes > > > Yes, those are actually casts/conversions in PHP, and I've repeatedly sai= d I'd like to have those, on top of the "never fail" casts we have now. Whe= ther that's with an "as" operator, a "cast" function, or some extension of = the existing cast syntax, is an open question. > > Crucially, though, I don't think most *patterns* would be relevant in tha= t context, as I pointed out in a previous message. > > > Regards, > Rowan Tommins > [IMSoP]