Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:129117 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 lists.php.net (Postfix) with ESMTPS id 543DA1A00BC for ; Thu, 6 Nov 2025 16:17:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1762445879; bh=+8aJ4h/8dCZaYLEi5pGb3778SsQ9yNbX8wi+czTxhEA=; h=Date:From:To:In-Reply-To:References:Subject:From; b=VCX4TIl67R/Hxu5CMkuxPPwwRMtAOpZPje3WsLAinZLHecfqnb4K6BJFyzhvsMvj6 2utJpar3Mae4f/92V6ljzh3ECFyb6jZDSA4SkNsDWY/nsz+D8/OeckYnzFT/oYSNN/ TMcjfgbazArXboQGWwZmjD2SQJbSCCqUfaLrL74Z21JaW6Nk6XlebuAWtZuMaLJ5G1 YdR+jy0Tz/0eKqWSneY6OnxmcoDcZ5i3es7NAmWm8KwSWjIAvjRHt3vBYMHg1Hfi4I SrFEoJVST5MN1HY0lyv7uS9eUwznnglz/jU85Vq93i8Xv5wdyEKKYAFZDaP4r+S8Mh +gS6wACzpH7ZQ== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 294C518006E for ; Thu, 6 Nov 2025 16:17:59 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-0.9 required=5.0 tests=BAYES_20,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_MISSING,RCVD_IN_DNSWL_LOW, SPF_HELO_PASS,SPF_NONE autolearn=no autolearn_force=no version=4.0.1 X-Spam-Virus: No X-Envelope-From: Received: from fout-b2-smtp.messagingengine.com (fout-b2-smtp.messagingengine.com [202.12.124.145]) (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, 6 Nov 2025 16:17:58 +0000 (UTC) Received: from phl-compute-04.internal (phl-compute-04.internal [10.202.2.44]) by mailfout.stl.internal (Postfix) with ESMTP id 278521D000E0 for ; Thu, 6 Nov 2025 11:17:53 -0500 (EST) Received: from phl-imap-02 ([10.202.2.81]) by phl-compute-04.internal (MEProxy); Thu, 06 Nov 2025 11:17:53 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= garfieldtech.com; h=cc:content-transfer-encoding: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=fm3; t=1762445873; x=1762532273; bh=v6zh4ahkdq2hc7OdK+7Sj zlDfwRX9DMFezVhg6NvN0k=; b=VTvBhqFuUim+obxc7GyjbRONBWv56pET8f/eA TaJ45YuJwrPULfaGer6PiQl75G+qyR0J9menl5TU9uOKZBO1Z0U1oWxaIkWF0d0H Q6kdO+RH+P4MzGq6yQ2oD9zOMAV8ivNwFZLIi04SYEJLR6ZTea0Tg62O9UfUwosE MXnVyOhxGwiF2hbSAU1y+L7HJjLH8/TTEnqAClyh6eyoBE8UZRGef0szAoIQrzu2 PWdGkATMjN83MOxaJViVnUFRSPtoCjeowlup745IwqxGM4n371l/jrLtdK4W+AN2 zcgQSaSLiafIC/ug0NRNjxJr4MkdaljmrS1mJSRDrClWv40kw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding: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=fm3; t=1762445873; x=1762532273; bh=v 6zh4ahkdq2hc7OdK+7SjzlDfwRX9DMFezVhg6NvN0k=; b=qW22Yy8wD0sLXka6V z/xmuXTnWAhLQX231QDucSqUhHjKrOMrx/ch6H0OynFdgwyJKbsxGx6W5IfkTSuy 22Up7eQej59nsThll2WWw1gbLbIQFovQgmYtrANNdLDjFqDA2ZLzvkJfc73uoXXv WRGvjex9EgiqwzrTwm1TnuiHQW9r6DruwIFvWvEpHizCfcxU/tgrMoKUzGV/bhTM 19+he3J1la2IJQcn6e9hxnejB+El7+OOkHKkiT48WwPwuDZLT7Ji0SljnJb1GmLy f1eT9z00u/f3W4WUN8YW12Aw8+281Zzu3B2j0ZPty0k6C5K1oK5FWJIdYVrXyXfQ kMMKw== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeeffedrtdeggddukeejvdegucetufdoteggodetrf dotffvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfurfetoffkrfgpnffqhgenuceu rghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujf gurhepofggfffhvffkjghfufgtgfesthhqredtredtjeenucfhrhhomhepfdfnrghrrhih ucfirghrfhhivghlugdfuceolhgrrhhrhiesghgrrhhfihgvlhguthgvtghhrdgtohhmqe enucggtffrrghtthgvrhhnpeehieffudduleffjefhteetveekjeevleduhfevteffvdek veejkeevleetudegffenucffohhmrghinhepphhhphdrnhgvthdpvgigthgvrhhnrghlsh drihhonecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomhep lhgrrhhrhiesghgrrhhfihgvlhguthgvtghhrdgtohhmpdhnsggprhgtphhtthhopedupd hmohguvgepshhmthhpohhuthdprhgtphhtthhopehinhhtvghrnhgrlhhssehlihhsthhs rdhphhhprdhnvght X-ME-Proxy: Feedback-ID: i8414410d:Fastmail Received: by mailuser.phl.internal (Postfix, from userid 501) id 8EA5C700063; Thu, 6 Nov 2025 11:17:52 -0500 (EST) X-Mailer: MessagingEngine.com Webmail Interface Precedence: list list-help: list-unsubscribe: list-post: List-Id: x-ms-reactions: disallow MIME-Version: 1.0 X-ThreadId: ABHhpBt0-nOZ Date: Thu, 06 Nov 2025 10:17:32 -0600 To: "php internals" Message-ID: <5ee6282f-3775-4408-b6e1-44166fbd8d1c@app.fastmail.com> In-Reply-To: <2529fb76-6b6c-4304-98b9-1ffa034e1e1f@rwec.co.uk> References: <9BE876E9-93BE-44C5-9C12-8E2C6FF0766F@rwec.co.uk> <2529fb76-6b6c-4304-98b9-1ffa034e1e1f@rwec.co.uk> Subject: Re: [PHP-DEV] [RFC] Nullable and non-nullable cast operators Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable From: larry@garfieldtech.com ("Larry Garfield") On Wed, Nov 5, 2025, at 4:48 PM, Rowan Tommins [IMSoP] wrote: > On 05/11/2025 08:38, Alexandre Daubois wrote: >> What we propose is to align these new operators to already existing >> rules applied to function arguments. This is, indeed, stricter than >> current cast operators. But I wouldn't say it has*nothing to do* with >> the title of the RFC. >> Maybe it's not perfectly accurate. If the naming is a problem and >> should be changed, I'd be happy to hear suggestions and update >> accordingly with a better name. > > Let's imagine how someone would describe these two expressions if this=20 > RFC passed: > > (int)$foo > (!int)$foo > > Here are the differences I see: > > 1) The first casts any non-numeric input to zero; the second throws=20 > TypeError. > 2) Certain values, such as "123foo" are considered numeric by one, but=20 > not by the other. > > That's it. There's no need to mention null specifically, it's just one=20 > of many non-numeric values. > > In fact, people might forget to mention point 2, because the=C2=A0diff= erence=20 > between "always returns an integer" and "may cause your entire program=20 > to exit if fed unvalidated input" is far more important. > > So, if you want a name, I suggest something to do with "throw" or "err= or". > > > But the problem I see with the RFC is deeper than that: there's no=20 > actual discussion of *why* throwing a TypeError is better, or *when*=20 > this completely new form of cast would be used. > > As I've tried to argue in previous messages, exception-handling is *no= t*=20 > convenient for tasks like handling user input. It is maybe useful for=20 > deeper code, where you expect the value to already be validated. So I=20 > think we should be looking at more than one type of new cast; or at=20 > least a choice of syntax that anticipates that. > > > As for the other part of the RFC, looking at these two expressions: > > (int)$foo > (?int)$foo > > I would expect the *only* differences to be to do with null input, and=20 > maybe null output. > > But in the proposal, using the new operator will *crash my application= *=20 > for values where the other returned zero, and even for values where th= e=20 > other returned non-zero integers. > > If that part of the proposal goes to a vote as currently written, I wi= ll=20 > vote No. > > > --=20 > Rowan Tommins > [IMSoP] I very much appreciate the goal here, but at the same time I share Rowan= and other's concerns that it's too one-off and non-obvious. The general case here is "I have a variable of type X, and I want to los= slessly convert it t type Y if that's possible, and do this other thing = if not." Where "the other thing" could be "return null", "Warning", "Ex= ception", "default value", etc. =20 This is in contrast to the current casting logic, which allows a lossy c= onversion with no communication that a loss has happened. Lossy and lossless conversion are sufficiently different that the syntax= should not be so similar. =20 My first thought is some kind of language construct pseudo-function, lik= e: cast($var, int); // Weak mode rules conversion to int, or error cast($var, ?int); // Weak mode rules conversion to int, allowing null, o= r error cast($var, int|string|null); // Weak mode rules conversion to int if pos= sible, string if not, allow null, or error (This may or may not be ideal.) But at this point, it feels an awful lot like filter_var() (https://www.= php.net/filter_var). And of course there's the question of how to signal an incompatibility. = Returning null defeats the purpose of allowing null, an exception is to= o heavy and inappropriate, and... we have nothing else. I feel compelled to mention my error handling proposal from earlier this= year: https://externals.io/message/127188 I'm in favor of better type conversion tools that follow the same weak-r= ules as functions. But I agree that just sticking a ? in the existing s= yntax and calling it a day is not the right approach, even if it feels e= asy at first blush. --Larry Garfield