Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:122732 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 00B2A1A009C for ; Fri, 22 Mar 2024 18:48:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1711133302; bh=vFTy5AgvG/kdHXqSyK6xo9cIdU5vRbSsbpllN/1f7fA=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=DoQFqv+0wNCADhcaImzLufFaiG0tX1pG+nT1dTTgnVTGluIWvCnXb8IBWr+AorY6O EaIXeEaPyVLxGJ+M00oPUflZi7uB4l0vcaufF21mHJ8pacjDEXxXPl1MiRPjrYy6XI ewrSjd75jexUKgOvLDNzI8Wt3efBBAvw9mlodZI/zPJhlFLICOV3jO2TzNXCla5/L1 v/E/6YwnwXKkBRXbMA+ATPVqAjliQHB2ztYD7ItZYnhANPM6P7+WKyfgFo29cc5kw2 1d5WrGy/6150km7m0VyQQcLr45N4rJHX4xPxUHyxfhtqcKWkOzYlsK8bHtcNXvA+PL V9TDtqxYC2Cpg== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id A298118007E for ; Fri, 22 Mar 2024 18:48:21 +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-f51.google.com (mail-oo1-f51.google.com [209.85.161.51]) (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, 22 Mar 2024 18:48:21 +0000 (UTC) Received: by mail-oo1-f51.google.com with SMTP id 006d021491bc7-5a51c063f99so423467eaf.0 for ; Fri, 22 Mar 2024 11:47:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1711133278; x=1711738078; 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=+bL3Pkm9tlyW54KKwx6efJuw6dEFzAo2oyQVi9LpXxg=; b=mUwTYlevSeCg0bog0NmKW8s/YtGqrCNnEHF4aPlsedPwtb28sx06yDyJP53s83D8Ze V/CpI60fBLf/MxdXwHSvYci4P5mB/JGHC90oRiYpY34yRhYKpj8FaySVLaTh03jzwt27 ZhznKspTe+jnIaHBxT0scQWElblhmjxnewHoxm7VJwo69hYaCqWm3OjleSVoFdhMfb5w Qpj4YmScCIdWi4afdNtII7U3iJndao+2S4MRHDtN24Bb54vRiNtwRyowXqcxv8YrUNS+ ztIHu/iit1i6tACxDhxajrpd6QH7VFXAe2GEockueVbxoGwbiwocmwmNkVwA8MhfMWlj Yh3Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1711133278; x=1711738078; 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=+bL3Pkm9tlyW54KKwx6efJuw6dEFzAo2oyQVi9LpXxg=; b=kNnS0BUwhewzzhBjoJg5jIJbyE2jvE7p+C+4lfRoGqcSPxqYvG2HBNlZzwAr2NaeUT nhSePEhP1JXPECKEKAmkbhVeht9av1qaZZ1JyAa1i8SQRyypOVbcByMXIL4ob8sqfT++ aXG9vPoEwNNuSXyMYsueMCjXjbPGu1GCHwfkY2RE1eJ63/Pju0Y6ZSDcmRE8P/7sHsC4 UiK8JPrCUCkW0kJb1tdOxaugmm6PxWrPR8H8WsO5SDEKODLxe08hAtwblmw1spoz4ULC MxCewfjDqgtYnyLioXLo//1RhU8x11IgnJ4MXR8GR68s6ckeUpSVh5Noxc0pOWilTOXH casQ== X-Gm-Message-State: AOJu0YwJ0DpBT2oiuTpN4PbrZGGn6CnJzIzOkVUQtqQ2yonCgdhdLQp2 p5Qe4MGtYz8J1P/n2whOdMrHwdBR7y21Oi6+ii13IhwLZY84QWJpkObeV/AH4LdqK/uwKUv+kl1 KqWORiRfnbSNhcCYo8wDQoZs2cfPxPIe7kYU= X-Google-Smtp-Source: AGHT+IHIzcpn0apr+2vsqM5uBL+48z9mWYYTE7eK7HGqGqHRBE2DLAF+VaryLqpbC5dWM4u4rtx57MbbYTlVa8MDm6g= X-Received: by 2002:a05:6820:3096:b0:5a1:1e5e:1fd0 with SMTP id eu22-20020a056820309600b005a11e5e1fd0mr479148oob.2.1711133277719; Fri, 22 Mar 2024 11:47:57 -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> <7d53f2e4-46f3-46f1-89b0-6e1d3b0b2e32@app.fastmail.com> In-Reply-To: Date: Fri, 22 Mar 2024 19:47:45 +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 Fri, Mar 22, 2024 at 5:51=E2=80=AFPM Rowan Tommins [IMSoP] wrote: > > On Fri, 22 Mar 2024, at 12:58, Robert Landers wrote: > > > >> $optionalExpiryDateTime =3D $expiry as ?DateTimeInterface else new Dat= eTimeImmutable($expiry); > > I'm not sure I can grok what this does... > > > > $optionalExpiryDateTime =3D ($expiry =3D=3D=3D null || $expiry instance= of > > DateTimeInterface) ? $expiry : new DateTimeImmutable($expiry) > > Trying to write it as a one-liner is going to make for ugly code - that's= why I'd love to have a new way to write it! But yes, that's the right logi= c. > > With the "is" operator from the Pattern Matching draft, it would be: > > $optionalExpiryDateTime =3D ($expiry is ?DateTimeInterface) ? $expiry : n= ew DateTimeImmutable($expiry); > > But with a clearer assertion that the variable will end up with the right= type in all cases: > > $optionalExpiryDateTime =3D $expiry as ?DateTimeInterface else some_other= _function($expiry); > assert($optionalExpiryDateTime is ?DateTimeInterface); // cannot fail, al= ready asserted by the "as" > > > > Maybe? What would be the usefulness of this in real life code? I've > > never written anything like it in my life. > > I already explained the scenario: the parameter is optional, so you want = to preserve nulls; but if it *is* present, you want to make sure it's the c= orrect type before proceeding. Another example: > // some library function that only supports strings and nulls > function bar(?string $name) { > if ( $string !=3D=3D null ) ... > else ... > } > // a function you're writing that supports various alternative formats > function foo(string|Stringable|int|null $name =3D null) { > // we don't want to do anything special with nulls here, just pass th= em along > // but we do want to convert other types to string, so that bar() doe= sn't reject them > bar($name as ?string else (string)$name); > } This breaks my brain; in a good way I think. As you pointed out, people could now write this: function (int|string|null $value) { foo($value as int|null else (int)$value); } Which would pass int or null down to foo. Especially because I see something like this too often (especially with strict types): function (int|string|null $value) { foo((int) $value); } And foo() gets a 0 when $value is null and "undefined" things start happeni= ng. This isn't really possible with any of the other syntaxes I proposed. Now, if we are dealing with function returns: ($x as MyType else null)?->doSomething(); I don't hate it. It's a bit wordy, but still better than the alternative. > > To put it another way, it's no different from any other union type: at so= me point, you will probably want to handle the different types separately, = but at this point in the program, either type is fine. In this case, the ty= pes that are fine are DateTimeInterface and null; or in the example above, = string and null. > > > > $optionalExpiryDateTime =3D $expiry =3D=3D null ? $expiry : $expiry as > > DateTimeInterface ?? new DateTimeImmutable($expiry as string ?? "now") > > If you think that's "readable" then we might as well end the conversation= here. If that was presented to me in a code review, I'd probably just writ= e "WTF?!" Hahaha, yeah, I wrote that before reading my own example! > > I have no idea looking at that what type I can assume for $optionalExpiry= DateTime after that line, which was surely the whole point of using "as" in= the first place? > > Regards, > -- > Rowan Tommins > [IMSoP]