Hello,
I took a look at thinkverse https://github.com/thinkverse work on
https://wiki.php.net/rfc/clamp and on the open issues (handling NAN
and
other comparable values not being integer nor float).
This new implementation should resolve those issues:
https://github.com/php/php-src/pull/19434
If you allow me, I would update the RFC to add this new implementation
listed on it, remove the "Open issues" section if you don't see any with
the new implementation and would change the status of this RFC to draft to
reflect the fact that there is again an open PR for it.
Thanks,
Hi
Am 2025-08-19 09:32, schrieb Kyle Katarn:
If you allow me, I would update the RFC to add this new implementation
listed on it, remove the "Open issues" section if you don't see any
with
the new implementation and would change the status of this RFC to draft
to
reflect the fact that there is again an open PR for it.
Please see
https://wiki.php.net/rfc/howto#external_resources#rfcs_belong_to_a_single_author
(the "RFCs 'belong' to a single author") section. The existing RFC may
only be adjusted with the original author’s consent. It might be easiest
for you to create a “clamp function v2” RFC instead.
Best regards
Tim Düsterhus
Hi
2025-08-19 14:59, Tim Düsterhus tim@bastelstu.be wrote :
Hi
Am 2025-08-19 09:32, schrieb Kyle Katarn:
If you allow me, I would update the RFC to add this new implementation
listed on it, remove the "Open issues" section if you don't see any
with
the new implementation and would change the status of this RFC to draft
to
reflect the fact that there is again an open PR for it.Please see
https://wiki.php.net/rfc/howto#external_resources#rfcs_belong_to_a_single_author
(the "RFCs 'belong' to a single author") section. The existing RFC may
only be adjusted with the original author’s consent. It might be easiest
for you to create a “clamp function v2” RFC instead.Best regards
Tim Düsterhus
Thanks, when I go to https://wiki.php.net/RFC/clamp-v2 and click "Edit the
page", it says:
"Sorry, you don't have enough rights to continue."
Can you grant me this permission? Thanks.
2025-08-19 14:59, Tim Düsterhus tim@bastelstu.be wrote :>>>
https://wiki.php.net/rfc/howto#external_resources#rfcs_belong_to_a_single_author(the "RFCs 'belong' to a single author") section. The existing RFC may
only be adjusted with the original author’s consent. It might be easiest
for you to create a “clamp function v2” RFC instead.Thanks, when I go to https://wiki.php.net/RFC/clamp-v2 and click "Edit the
page", it says:
"Sorry, you don't have enough rights to continue."Can you grant me this permission? Thanks.
I've granted RFC karma to the kylekatarnls account; there is also a
kylek account, though? Can that be removed?
Christoph
2025-08-20 at 14:28, Christoph M. Becker cmbecker69@gmx.de wrote :
2025-08-19 14:59, Tim Düsterhus tim@bastelstu.be wrote :>>>
https://wiki.php.net/rfc/howto#external_resources#rfcs_belong_to_a_single_author
(the "RFCs 'belong' to a single author") section. The existing RFC may
only be adjusted with the original author’s consent. It might be easiest
for you to create a “clamp function v2” RFC instead.Thanks, when I go to https://wiki.php.net/RFC/clamp-v2 and click "Edit
the
page", it says:
"Sorry, you don't have enough rights to continue."Can you grant me this permission? Thanks.
I've granted RFC karma to the kylekatarnls account; there is also a
kylek account, though? Can that be removed?Christoph
Thanks, yes "kylek" account can be removed.
I created https://wiki.php.net/rfc/clamp_v2 (re-using most of the info from
https://wiki.php.net/rfc/clamp).
Thanks for you
From: Kyle Katarn kylekatarnls@gmail.com
Sent: Friday, August 22, 2025 11:02 AM
To: Christoph M. Becker cmbecker69@gmx.de
Cc: Tim Düsterhus tim@bastelstu.be; PHP Internals internals@lists.php.net
Subject: Re: [PHP-DEV] [RFC] Add clamp function
I created https://wiki.php.net/rfc/clamp_v2 (re-using most of the info from https://wiki.php.net/rfc/clamp).
Hey,
I’m not against adding such a function, but I noticed that the RFC says
some of which use min https://www.php.net/manual/en/function.min.php and max https://www.php.net/manual/en/function.max.php to check the bound, which is costly and slow when called often
What makes them slow? If we can create a significantly faster clamp
, can we use the same optimizations to improve min and max?
BR,
Juris
2025-08-22 at 13:30, Juris Evertovskis juris@glaive.pro wrote:
From: Kyle Katarn kylekatarnls@gmail.com
Sent: Friday, August 22, 2025 11:02 AM
To: Christoph M. Becker cmbecker69@gmx.de
Cc: Tim Düsterhus tim@bastelstu.be; PHP Internals <
internals@lists.php.net>
Subject: Re: [PHP-DEV] [RFC] Add clamp functionI created https://wiki.php.net/rfc/clamp_v2 (re-using most of the info
from https://wiki.php.net/rfc/clamp).Hey,
I’m not against adding such a function, but I noticed that the RFC says
some of which use min https://www.php.net/manual/en/function.min.php
and max https://www.php.net/manual/en/function.max.php to check the
bound, which is costly and slow when called oftenWhat makes them slow? If we can create a significantly faster
clamp
, can
we use the same optimizations to improve min and max?BR,
Juris
I taked it from https://wiki.php.net/rfc/clamp and from what I understand
reading the code: min and max support variadic array of parameters, or a
single array value, so min($max, max($min, $value)) will result in 2 loops,
plus if-else paths depending on the type. While the current implementation
of clamp accepts only 1 value, 1 min and 1 max, so it just does $value <
$min ? $min : $value > $max ? $max : $value, which is way less work.
Also from my point of view, min($max, max($min, $value)) has a
counter-intuitive reading when used to clamp a value.
Also from my point of view, min($max, max($min, $value)) has a counter-
intuitive reading when used to clamp a value.
Well, that's trivial to deal with:
min(max($min, $value), $max));
2025-08-22 at 22:29, Morgan Weedpacket@varteg.nz wrote:
Also from my point of view, min($max, max($min, $value)) has a counter-
intuitive reading when used to clamp a value.Well, that's trivial to deal with:
min(max($min, $value), $max));
It's not just about the order of parameters, it's still not intuitive to
call max()
with $min and min()
with $max, you still have to think about
what it does step by step to make sense out of it, while clamp($value, min:
$min, $max) or clamp(min: $min, value: $value, max: $max) will provide a
syntax that immediately make sense for next reader.
Like the author of the RFC v1 also mentioned, min(max()) is inefficient
(see the inner complexity of those functions).
2025-08-20 at 14:28, Christoph M. Becker cmbecker69@gmx.de wrote :
2025-08-19 14:59, Tim Düsterhus tim@bastelstu.be wrote :>>>
https://wiki.php.net/rfc/howto#external_resources#rfcs_belong_to_a_single_author https://wiki.php.net/rfc/howto#external_resources%23rfcs_belong_to_a_single_author(the "RFCs 'belong' to a single author") section. The existing RFC may
only be adjusted with the original author’s consent. It might be easiest
for you to create a “clamp function v2” RFC instead.Thanks, when I go to https://wiki.php.net/RFC/clamp-v2 and click "Edit the
page", it says:
"Sorry, you don't have enough rights to continue."Can you grant me this permission? Thanks.
I've granted RFC karma to the kylekatarnls account; there is also a
kylek account, though? Can that be removed?Christoph
Thanks, yes "kylek" account can be removed.
I created https://wiki.php.net/rfc/clamp_v2 (re-using most of the info
from https://wiki.php.net/rfc/clamp).Thanks for you
The grammar in this one sentence is very clumsy:
clamp takes three arguments, a $num, $min and $max, checks if $num is within the bounds of $min and $max, if in range, returns the value of $num, otherwise, returns the nearest bound value, i.e. if $num > $max return $max, if $num < $min return $min.
Please break it up into multiple sentences so it's easier to follow. I think I follow it, but it's clunky enough that I am not certain of it. :-)
Also, the text says $num but the code example says $value.
What determines comparability? What happens if you try to clamp values that are not comparable? Eg:
clamp(new Point(1, 2), new Point(0, 0), new Point(5, 5));
I assume that will fail somehow, but the failure should be described explicitly.
--Larry Garfield
2025-08-22 at 18:09, Larry Garfield larry@garfieldtech.com wrote:
2025-08-20 at 14:28, Christoph M. Becker cmbecker69@gmx.de wrote :
2025-08-19 14:59, Tim Düsterhus tim@bastelstu.be wrote :>>>
https://wiki.php.net/rfc/howto#external_resources#rfcs_belong_to_a_single_author
<
https://wiki.php.net/rfc/howto#external_resources%23rfcs_belong_to_a_single_author(the "RFCs 'belong' to a single author") section. The existing RFC
may
only be adjusted with the original author’s consent. It might be
easiest
for you to create a “clamp function v2” RFC instead.Thanks, when I go to https://wiki.php.net/RFC/clamp-v2 and click
"Edit the
page", it says:
"Sorry, you don't have enough rights to continue."Can you grant me this permission? Thanks.
I've granted RFC karma to the kylekatarnls account; there is also a
kylek account, though? Can that be removed?Christoph
Thanks, yes "kylek" account can be removed.
I created https://wiki.php.net/rfc/clamp_v2 (re-using most of the info
from https://wiki.php.net/rfc/clamp).Thanks for you
The grammar in this one sentence is very clumsy:
clamp takes three arguments, a $num, $min and $max, checks if $num is
within the bounds of $min and $max, if in range, returns the value of $num,
otherwise, returns the nearest bound value, i.e. if $num > $max return
$max, if $num < $min return $min.Please break it up into multiple sentences so it's easier to follow. I
think I follow it, but it's clunky enough that I am not certain of it. :-)Also, the text says $num but the code example says $value.
What determines comparability? What happens if you try to clamp values
that are not comparable? Eg:clamp(new Point(1, 2), new Point(0, 0), new Point(5, 5));
I assume that will fail somehow, but the failure should be described
explicitly.--Larry Garfield
Ah true, $num was v1 when it accepted only int|float, I switched to $value
since it's now mixed.
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
About "What determines comparability", it follows the usual rules of
PHP: https://www.php.net/manual/en/language.operators.comparison.phpSo 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 inmin()
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 formin()
andmax()
:
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. :)
(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
Though apparently what PHP currently does with Point comparisons in min/max is... weird. I don't even know what the logic here is. :)
That's the usual PHP object/array comparison [1]: 10 > 2, and 5 < 10.
The $y member isn't even checked. See
https://www.php.net/manual/en/language.operators.comparison.php#example-167.
Christoph
About "What determines comparability", it follows the usual rules of
PHP: https://www.php.net/manual/en/language.operators.comparison.phpSo 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 inmin()
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 formin()
andmax()
:
https://github.com/php/doc-en/pull/4814Please 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. :)
(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
2025-08-23 at 12:06, Rob Landers rob@bottled.codes wrote:
About "What determines comparability", it follows the usual rules of
PHP: https://www.php.net/manual/en/language.operators.comparison.phpSo 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 inmin()
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 formin()
andmax()
:
https://github.com/php/doc-en/pull/4814Please 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. :)(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()
.
2025-08-20 at 14:28, Christoph M. Becker cmbecker69@gmx.de wrote :
I've granted RFC karma to the kylekatarnls account; there is also a
kylek account, though? Can that be removed?Thanks, yes "kylek" account can be removed.
Done. :)