Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:128540 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 C2A091A00BC for ; Sat, 23 Aug 2025 10:03:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1755943298; bh=/usOVZwTkf5JRjOBZxRPDR8LZWy8uIS5k8U26abwJR4=; h=Date:From:To:In-Reply-To:References:Subject:From; b=K8yQkzuLYAfAWxNHubxziD2SSCNj0f5clfCh5RaiOk5Nq4S7inoKzrm8oCw/HLT9M vaZ8U7BnMi6k7TJrtpZN50Ix+lTL097N14i/SuNiQ9TXtWkpLfBUnSe8+Pdv90Djlv zh1Ti64zXQaJedHDSdTna1d1APxaQOSY5jdc1o089B4yk3K0JEvVlHwBeke0VN34cl 78oez7fdzyzufWZhAY0xVSE/oSXQg8YSStjYkzBG++ey9QDqCipuu1q4hdX/ayxB/K Ug3nsHlgMgIQFo/kJW+c8Kv2WTrmxGp5h4BsZa/S8ubu/8tnnPWdPWwLf8Yy0YZ9wP n7sQAokauEcjQ== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 48B4D1801ED for ; Sat, 23 Aug 2025 10:01:37 +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=-2.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_MISSING,HTML_MESSAGE, RCVD_IN_DNSWL_LOW,SPF_HELO_PASS,SPF_PASS autolearn=no autolearn_force=no version=4.0.1 X-Spam-Virus: No X-Envelope-From: Received: from fout-b3-smtp.messagingengine.com (fout-b3-smtp.messagingengine.com [202.12.124.146]) (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 ; Sat, 23 Aug 2025 10:01:37 +0000 (UTC) Received: from phl-compute-05.internal (phl-compute-05.internal [10.202.2.45]) by mailfout.stl.internal (Postfix) with ESMTP id 2CC6D1D00071 for ; Sat, 23 Aug 2025 06:03:10 -0400 (EDT) Received: from phl-imap-05 ([10.202.2.95]) by phl-compute-05.internal (MEProxy); Sat, 23 Aug 2025 06:03:10 -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=fm1; t=1755943390; x=1756029790; bh=XWV36cEdnZ XxrJuThslHOfECAjAaCeVmzChhhxO8I/s=; b=BJvk9q8sUkC7W/HBtTPVwIjOg9 gDN1to7CKtj7Xi2icYwma9zEi0SlKfhhH71PPuNtttEpAKW5SNSaljW9nRUv+kGS WtSzO5xBQ2oqgq0FS21sd+Fi6NRd0wzKWGNA3qNA0B0Ev9RZ0gTNQ4q5/QMWv8Ij GnGrSZkn6/pqCw8H6bGNGsMzA5dKe4D7hLG+6kaV/ioGwSHQASdbENMqzz31HxBC J8W2uCFe6JH6NLiysdGB4rwV5UdyiBbX6UD/kgx6WPPBQgwFf1IM6Bbbzid6Ej9d SxIEyhVpa7Bn6P1gFw+EF2j+pgOpi5pkyDhMyy7sYtedz1OZYmlCypydbjlw== 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-sender:x-me-sender:x-sasl-enc; s=fm3; t= 1755943390; x=1756029790; bh=XWV36cEdnZXxrJuThslHOfECAjAaCeVmzCh hhxO8I/s=; b=EMcZVXjXirPslwYnxUK5IOJJRx9Apbrs0Pep1wO7s3Tx/3cWqTn 7MpRdzlcIYHM8bktRW9ABhz73m9v15COdvD8SEr5n31oHXOzbvg9hsC0gS9cOJf9 PPo/5KD87UDpzGfPHuEcNSBvr4/NtwXTU1rlznQLhFnZdhTuTjmC9tkCMUGfPb4u bhjExkpBbs1dyVT2nUtOU1DOLaKKPn2V/qGW80KgAoj/QqZ7m0qknxFZi/RBsUH+ UQ0xEgBRx24j/V4siOvRb1wxpD/zaSfN8rBvkZTZ3lFTjW0yk8seWKidQqdAJOIo dqJYmGJ+Wf6efBCFi479dCnYzbGz8G5OGMQ== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeeffedrtdefgdduieeifeehucetufdoteggodetrf dotffvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfurfetoffkrfgpnffqhgenuceu rghilhhouhhtmecufedttdenucgoufhushhpvggtthffohhmrghinhculdegledmnecujf gurhepofggfffhvffkjghfufgtsegrtderreertdejnecuhfhrohhmpedftfhosgcunfgr nhguvghrshdfuceorhhosgessghothhtlhgvugdrtghouggvsheqnecuggftrfgrthhtvg hrnhepleefueeikedvieehkeetlefgfedutdekveehieeuheeljeetkeeikeeiheeukedu necuffhomhgrihhnpehphhhprdhnvghtpdhgihhthhhusgdrtghomhdpfehvgehlrdhorh hgnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomheprhho sgessghothhtlhgvugdrtghouggvshdpnhgspghrtghpthhtohepuddpmhhouggvpehsmh htphhouhhtpdhrtghpthhtohepihhnthgvrhhnrghlsheslhhishhtshdrphhhphdrnhgv th X-ME-Proxy: Feedback-ID: ifab94697:Fastmail Received: by mailuser.phl.internal (Postfix, from userid 501) id 9E3631820074; Sat, 23 Aug 2025 06:03:09 -0400 (EDT) X-Mailer: MessagingEngine.com Webmail Interface Precedence: list list-help: list-post: List-Id: x-ms-reactions: disallow MIME-Version: 1.0 X-ThreadId: AQaB7tSdQxac Date: Sat, 23 Aug 2025 12:02:48 +0200 To: internals@lists.php.net Message-ID: In-Reply-To: References: <0027ab13-89fb-40b4-991b-2f88a35c2f31@gmx.de> <272c241b-3145-4069-8a6a-9ea877f936c0@app.fastmail.com> Subject: Re: [PHP-DEV] [RFC] Add clamp function Content-Type: multipart/alternative; boundary=8d6d3b394a384e3e86851de375f96952 From: rob@bottled.codes ("Rob Landers") --8d6d3b394a384e3e86851de375f96952 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On Fri, Aug 22, 2025, at 22:09, Larry Garfield wrote: > On Fri, Aug 22, 2025, at 12:45 PM, Kyle Katarn wrote: >=20 > > About "What determines comparability", it follows the usual rules of=20 > > PHP: https://www.php.net/manual/en/language.operators.comparison.php > > > > So it's equivalent to ($value < $min) ? $min : (($value > $max) ? $m= ax=20 > > : $value) and also equivalent to min($max, max($min, $value)) > > > > About clamp(new Point(1, 2), new Point(0, 0), new Point(5, 5)); > > > > If Point is a comparable value (simple DTO for example), it should=20 > > return $value, like when doing ($value < $min) ? $min : (($value >=20 > > $max) ? $max : $value) we could add a test for such case, but I thin= k=20 > > that for consistency, whatever currently works in min() should work = in=20 > > clamp() > > > > Following the link of the implementation, there is also a link to th= e=20 > > documentation where I already explained the comparison rules followi= ng=20 > > the example of what was done in the documentation for min() and max(= ):=20 > > https://github.com/php/doc-en/pull/4814 >=20 > Please make sure the above is captured in the RFC. >=20 > Though apparently what PHP currently does with Point comparisons in mi= n/max is... weird. I don't even know what the logic here is. :) >=20 > https://3v4l.org/pTmiV >=20 > (No need to change it in this RFC, just note explicitly that the expec= ted behavior is identical to that min(max()) construct, regardless of ty= pe.) >=20 > --Larry Garfield >=20 It only compares the first property, and if there is a conflict, it move= s on to the next property. That is why some of us have been advocating f= or operator overrides: because this default isn=E2=80=99t always appropr= iate, as your Point example illustrates. In some cases, you would want t= o compare magnitude or something else entirely, not just the x value. What is even trickier is that this process completely ignores computed h= ooks. So, if you add a hook as the first property (for example, returnin= g the magnitude), it is simply ignored. As a weird side note: if you cas= t the object to an array, the computed hook disappears, but if you use `= json_encode()`, the computed value is included. To complicate things further, the current behaviour for objects is actua= lly =E2=80=9Cundefined=E2=80=9D and it isn=E2=80=99t documented. There a= re examples that show how objects are compared, but they don=E2=80=99t e= xplicitly mention that the object is being cast to an array (see the abo= ve paragraph on why that matters). Because this relies on implementation= details rather than documented behaviour, it could change between PHP v= ersions without an RFC. That makes relying on it a bit risky. Adding operator overrides would help by making this behaviour explicit a= nd consistent across versions, or just defining it in general. But whene= ver someone tries to define this more clearly (as I started to do with R= ecords), it tends to run into resistance on this list for reasons I=E2=80= =99ve never quite understood. =E2=80=94 Rob --8d6d3b394a384e3e86851de375f96952 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable


On Fri, Aug 22, 2025, at 22:09, Larry Garfield wrote:<= /div>
On Fri, Aug 22,= 2025, at 12:45 PM, Kyle Katarn wrote:

> Abo= ut "What determines comparability", it follows the usual rules of <= /div>
>
> So it's equivalen= t to ($value < $min) ? $min : (($value > $max) ? $max 
<= div>> : $value) and also equivalent to min($max, max($min, $value))
>
> About clamp(new Point(1, 2), new Point(0, 0= ), new Point(5, 5));
>
> If Point is a compara= ble value (simple DTO for example), it should 
> retur= n $value, like when doing ($value < $min) ? $min : (($value > = ;
> $max) ? $max : $value) we could add a test for such cas= e, but I think 
> that for consistency, whatever curre= ntly works in min() should work in 
> clamp()
>
> Following the link of the implementation, there is= also a link to the 
> documentation where I already e= xplained the comparison rules following 
> the example= of what was done in the documentation for min() and max(): 
<= div>> https:= //github.com/php/doc-en/pull/4814

Please ma= ke sure the above is captured in the RFC.

Thoug= h apparently what PHP currently does with Point comparisons in min/max i= s... weird.  I don't even know what the logic here is. :)


(No need to change it in this RFC, just n= ote explicitly that the expected behavior is identical to that min(max()= ) construct, regardless of type.)

--Larry Garfi= eld


It only compare= s the first property, and if there is a conflict, it moves on to the nex= t property. That is why some of us have been advocating for operator ove= rrides: because this default isn=E2=80=99t always appropriate, as your P= oint example illustrates. In some cases, you would want to compare magni= tude or something else entirely, not just the x value.

What is even trickier is that this process completely ignores co= mputed hooks. So, if you add a hook as the first property (for example, = returning the magnitude), it is simply ignored. As a weird side note: if= you cast the object to an array, the computed hook disappears, but if y= ou use json_encode(), the computed value is included.

To complica= te things further, the current behaviour for objects is actually =E2=80=9C= undefined=E2=80=9D and it isn=E2=80=99t documented. There are examples t= hat show how objects are compared, but they don=E2=80=99t explicitly men= tion that the object is being cast to an array (see the above paragraph = on why that matters). Because this relies on implementation details rath= er than documented behaviour, it could change between PHP versions witho= ut an RFC. That makes relying on it a bit risky.

Adding operator overrides would help by making this behaviour explicit= and consistent across versions, or just defining it in general. But whe= never someone tries to define this more clearly (as I started to do with= Records), it tends to run into resistance on this list for reasons I=E2= =80=99ve never quite understood.

=E2=80=94 Rob<= br>
--8d6d3b394a384e3e86851de375f96952--