2025-08-23 at 12:06, Rob Landers <rob@bottled.codes> wrote:

>
> On Fri, Aug 22, 2025, at 22:09, Larry Garfield wrote:
>
> On Fri, Aug 22, 2025, at 12:45 PM, Kyle Katarn wrote:
>
> > About "What determines comparability", it follows the usual rules of
> > PHP: https://www.php.net/manual/en/language.operators.comparison.php
> >
> > So it's equivalent to ($value < $min) ? $min : (($value > $max) ? $max
> > : $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
> > return $value, like when doing ($value < $min) ? $min : (($value >
> > $max) ? $max : $value) we could add a test for such case, but I think
> > that for consistency, whatever currently works in min() should work in
> > clamp()
> >
> > Following the link of the implementation, there is also a link to the
> > documentation where I already explained the comparison rules following
> > the example of what was done in the documentation for min() and max():
> > https://github.com/php/doc-en/pull/4814
>
> Please make sure the above is captured in the RFC.
>
> Though apparently what PHP currently does with Point comparisons in
> min/max is... weird.  I don't even know what the logic here is. :)
>
> https://3v4l.org/pTmiV
>
> (No need to change it in this RFC, just note explicitly that the expected
> behavior is identical to that min(max()) construct, regardless of type.)
>
> --Larry Garfield
>
>
> It only compares the first property, and if there is a conflict, it moves
> on to the next property. That is why some of us have been advocating for
> operator overrides: because this default isn’t always appropriate, as your
> Point example illustrates. In some cases, you would want to compare
> magnitude or something else entirely, not just the x value.
>
> What is even trickier is that this process completely ignores computed
> 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 you use
> json_encode(), the computed value is included.
>
> To complicate things further, the current behaviour for objects is
> actually “undefined” and it isn’t documented. There are examples that show
> how objects are compared, but they don’t explicitly mention that the object
> is being cast to an array (see the above paragraph on why that matters).
> Because this relies on implementation details rather than documented
> behaviour, it could change between PHP versions without 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 whenever
> 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’ve
> never quite understood.
>
> — Rob
>

I would not be against operator overrides, though it starts becoming quite
complex when dealing with comparing 2 objects of different classes. Anyway
I will add a note on the RFC about objects to warn about unexpected
behavior, but this is probably out of scope, the same concerns apply to
min() and max() and that's why I added the same warning in the
documentation: "Be careful when passing arguments of different types
because clamp can produce unpredictable results." Adding a specific note
about objects in the documentation could make sense. Then it would probably
be nice if it were also added to min() and max().

Reply via email to