Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:122706 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 700B71AD8F6 for ; Thu, 21 Mar 2024 15:02:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1711033377; bh=8RrdaJCt2RE0Y/4rOmLwLCp5kf/LT03iMcmS1BnS0So=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=W+3pTc/HXNZZiejcwTDx/3QdN0eX0zZUrCNOfAT8hH6uI4H/6r7y0fxKzYyFPnIe6 OPAq2L+esWL+afPZyDJpK7hp6H+IsZhcCMzzuoX6ESNavr1VZxdazdqXFWw1yJ9wJd lGoeGIGxsbUh2IEdgN6+d11yZpBB+SXZaGuPgedM9Sna3wwIe6TXfwMgUYhhv/MSvG BAZyVSpKLn59b7xY+t2kmPKqVScy9trfVN7uB68BLpO5CCMjioZ98dkcCDsXq2vMPa IK+ZliCsSrXwWrJGSZdeuIYoW4iOGR2sp+ebW7XJphQIayIrsuvfUga71pMS+wi4Rt SBJ9gceYKmkLw== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id D5FBB180041 for ; Thu, 21 Mar 2024 15:02:56 +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_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: No X-Envelope-From: Received: from mail-oo1-f43.google.com (mail-oo1-f43.google.com [209.85.161.43]) (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, 21 Mar 2024 15:02:56 +0000 (UTC) Received: by mail-oo1-f43.google.com with SMTP id 006d021491bc7-5a4f7a648dbso553621eaf.3 for ; Thu, 21 Mar 2024 08:02:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1711033354; x=1711638154; 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=H5ZHbXZMmBGActVyG5yhfI4qMWcKqr8he/iktGsiacM=; b=HuTMrFChjkUCVsaRCkCOx4UfhYXO45KjMymMj47ewv9CVr9QdsG6Bddo/y0k16bG0S eOE8incR/uKY4W/NlQu94fSWcHTh4fCzOgdp9aoAqu8NqR36BWgKN0clcD2INZu5jneb P7JUa1uMeiok1vfjFtj3A9FihzUo6I0z0pS14UJ/2k57qMiTwTQHradjS+FnimkyUgDc Y69aflEcMbEXGANWDluoAlGL2YWtZ0rSyusX8Z3y3ILdO6poj1xfbDK5UsOQ+uV+NwE7 ahT2st9rg6Ys5DwRbn4pNXs1LhtLKiJCrwMwK5AAefqfrK9J3it9XxappfzzZkSbbh6N yf7g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1711033354; x=1711638154; 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=H5ZHbXZMmBGActVyG5yhfI4qMWcKqr8he/iktGsiacM=; b=DwBLcrZuWCGYOBhQTgi8bw7yFxxyMv0a1ZWyh74JGNl9YXRfU/BViUY+DjW4R3yL7l OjWKLqq647BecUK6BtBkMeLOg9r1ir9UmXECK0o/o/W0sB3F1QEVGf3Qt3XA3dZgKHov Bvwj8cSkXBDAtj55oPnEbwKOWLKworeUxFxXgGv4UxxWiBoi3PO/zh8b894wAFP907JR PJ8p0GLMFlaXLPM/A+7IzvS+a2dSEoriCmRThkWU/+AOxR+EDbJizLawRMXymMJc9mHH DdK8dBTOrCUmhx42NJQQOT/VXTU9SwPXqyFnzCcIi1i6FsCdpDza6HuNDUvdOD7e8GEc HRjw== X-Gm-Message-State: AOJu0YzQR8ZijKhhB65vs/Wb2sCOAViHdAhRZzCMdUzk2l+UqEv5+tyB x4UzumYBdSruzpy5dG5d5WCbTjNHAcuZzEaEBLz/AFeDOk3wTchxXOqTQxgO9PSiXUt883NhTdt Yh+T9z6ERXHK/Mcmv9YeQpqkOLjs= X-Google-Smtp-Source: AGHT+IFyDvnh0MMTbimmeGFSQX1geYffoV0kvb93e11rK5358ggumcePClB8ifvBKBNPhiUjU5iY2feR2kztNKrSXCw= X-Received: by 2002:a05:6820:1e03:b0:5a1:d84c:cf79 with SMTP id dh3-20020a0568201e0300b005a1d84ccf79mr2476548oob.3.1711033353843; Thu, 21 Mar 2024 08:02:33 -0700 (PDT) Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net MIME-Version: 1.0 References: <3F78A125-1946-42E2-A4F5-A2B282BE2107@rwec.co.uk> <2d7ec203-6e80-445c-94f4-d29ef58743b1@rwec.co.uk> In-Reply-To: <2d7ec203-6e80-445c-94f4-d29ef58743b1@rwec.co.uk> Date: Thu, 21 Mar 2024 16:02:22 +0100 Message-ID: Subject: Re: [PHP-DEV] Proposal: AS assertions 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 Thu, Mar 21, 2024 at 12:45=E2=80=AFPM Rowan Tommins [IMSoP] wrote: > > On 20/03/2024 23:05, Robert Landers wrote: > > In other > words, I can't think of a case where you'd actually want a Type|null > and you wouldn't have to check for null anyway. > > > It's not about having to check for null; it's about being able to disting= uish between "a null value, which was one of the expected types" and "a val= ue of an unexpected type". > > That's a distinction which is made everywhere else in the language: param= eter types, return types, property types, will all throw an error if you pa= ss a Foo when a ?Bar was expected, they won't silently coerce it to null. > > > > If you think about it, in this proposal, you could use it in a match: > > // $a is TypeA|TypeB|null > > match (true) { > $a as ?TypeA =3D> 'a', > $a as ?TypeB =3D> 'b', > $a =3D=3D=3D null =3D> 'null', > } > > > That won't work, because match performs a strict comparison, and the as e= xpression won't return a boolean true. You would have to do this: > > match (true) { > (bool)($a as ?TypeA) =3D> 'a', > (bool)($a as ?TypeB) =3D> 'b', > $a =3D=3D=3D null =3D> 'null', > } > > Or this: > > match (true) { > ($a as ?TypeA) !=3D=3D null =3D> 'a', > ($a as ?TypeB) !=3D=3D null =3D> 'b', > $a =3D=3D=3D null =3D> 'null', > } > > > Neither of which is particularly readable. What you're really looking for= in that case is an "is" operator: > > match (true) { > $a is TypeA =3D> 'a', > $a is TypeB =3D> 'b', > $a =3D=3D=3D null =3D> 'null', > } > > Which in the draft pattern matching RFC Ilija linked to can be abbreviate= d to: > > match ($a) is { > TypeA =3D> 'a', > TypeB =3D> 'b', > null =3D> 'null', > } > > > Of course, in simple cases, you can use "instanceof" in place of "is" alr= eady: > > match (true) { > $a instanceof TypeA =3D> 'a', > $a instanceof TypeB =3D> 'b', > $a =3D=3D=3D null =3D> 'null', > } > > > > Including `null` in that type > seems to be that you would get null if no other type matches, since > any variable can be `null`. > > > I can't think of any sense in which "any variable can be null" that is no= t true of any other type you might put in the union. We could interpret Foo= |false as meaning "use false as the fallback"; or Foo|int as "use zero as t= he fallback"; but I don't think that would be sensible. > > In other words, the "or null on failure" part is an option to the "as" ex= pression, it's not part of the type you're checking against. If we only wan= ted to support "null on failure", we could have a different keyword, like "= ?as": > > $bar =3D new Bar; > $bar as ?Foo; // Error > $bar ?as Foo; // null (as fallback) > > $null =3D null; > $null as ?Foo; // null (because it's an accepted value) > $null ?as Foo; // null (as fallback) > > A similar suggestion was made in a previous discussion around nullable ca= sts - to distinguish between (?int)$foo as "cast to nullable int" and (int?= )$foo as "cast to int, with null on error". > > > Note however that combining ?as with ?? is not enough to support "chosen = value on failure": > > $bar =3D new Bar; > $bar ?as ?Foo ?? Foo::createDefault(); // creates default object > > $null =3D null; > $null ?as ?Foo ?? Foo::createDefault(); // also creates default object, e= ven though null is an expected value > > That's why my earlier suggestion was to specify the fallback explicitly: > > $bar =3D new Bar; > $bar as ?Foo else null; // null > $bar as ?Foo else Foo::createDefault(); // default object > > $null =3D null; > $nulll as ?Foo else null; // null > $null as ?Foo else Foo::createDefault(); // also null, because it's an ac= cepted value, so the fallback is not evaluated > > Probably, it should then be an error if the fallback value doesn't meet t= he constraint: > > $bar =3D new Bar; > $bar as Foo else null; // error: fallback value null is not of type Foo > $bar as ?Foo else 42; // error: fallback value 42 is not of type ?Foo > > > > Regards, > -- > Rowan Tommins > [IMSoP] I don't think you are getting what I am saying. $a as int|float would be an int, float, or thrown exception. $a as int|float|null would be an int, float, or null. Robert Landers Software Engineer Utrecht NL