# coerce() function

- Thread: https://externals.io/message/129578
- Original archive: https://news-web.php.net/php.internals/129578
- Started by Dmitry Derepko on 2025-12-10T07:42:27+00:00
- Messages: 6
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #129578 — Dmitry Derepko — 2025-12-10T07:42:27+00:00

URL: https://externals.io/message/129578#129578

Hello, 

From time to time I need to write a few lines of code that usually look ridiculous:

$var = $input === ‘yes’ ? ‘yes’ : ’no’
$var = $input !== ‘yes’ ? ’no’ : $yes
$var = $input > 10 ? 10 : $input
$var = max(-10, min($input, 10)

and many other variations.
In Kotlin, I can use `coerceIn()` extension function with strings / numbers / comparables, which allows me to write such lines more readable. 

I suggest to add such function to PHP. The examples above may look like the following

$var = coerce($input, variants: [“yes”, “no”], default: “yes”);
$var = coerce($input, min: 0, max: 10, default: 5);
$var = coerce($input, min: 0, max: 10, default: 5);

For sure, that could be different functions not to introduce another overloading function. Or range arguments could be replaced with `range(0, 10)` function.

This letter is an intent to start discussion of any possible ways of developing this idea.
If we agree that the function has enough value to be bundled I’ll create RFC to push the idea further.

So what do you think?

----------

Best regards,
Dmitrii Derepko.
@xepozz

---

## #129581 — Rowan Tommins [IMSoP] — 2025-12-10T14:00:27+00:00

URL: https://externals.io/message/129578#129581 · In reply to: #129578

Hi Dmitry,



>I suggest to add such function to PHP. The examples above may look like the following
>
>$var = coerce($input, variants: [“yes”, “no”], default: “yes”);
>$var = coerce($input, min: 0, max: 10, default: 5);
>$var = coerce($input, min: 0, max: 10, default: 5);
>
>For sure, that could be different functions not to introduce another overloading function. Or range arguments could be replaced with `range(0, 10)` function.

My first thought was that the min/max variant would be covered by the recently-accepted `clamp()` function: https://wiki.php.net/rfc/clamp_v2 Looking closer, I see that you want to default to a specific value, not the nearest, so it's not quite the same.

I think combining both tasks into one function is definitely the wrong approach. PHP doesn't have function overloading, and although you can partially stimulate it with nullable and optional parameters, the whole thing ends up very messy compared to just having separate functions. 

Using `range()` to pass in an array would be less efficient than min and max, but maybe good enough for small ranges. Perhaps in future we will have a separate "lazy range" type, which could then be handled as a special case.

In general, I don't think it's a function that I'd use often, but it seems a reasonable enough addition to the language.

Thanks,

Rowan Tommins
[IMSoP]

---

## #129591 — Dmitry Derepko — 2025-12-12T07:23:40+00:00

URL: https://externals.io/message/129578#129591 · In reply to: #129581

> 
> 
> Hi Dmitry,
> 
> 
> 
> > […]
> 
> My first thought was that the min/max variant would be covered by the recently-accepted `clamp()` function: https://wiki.php.net/rfc/clamp_v2 Looking closer, I see that you want to default to a specific value, not the nearest, so it's not quite the same.
> 
> I think combining both tasks into one function is definitely the wrong approach. PHP doesn't have function overloading, and although you can partially stimulate it with nullable and optional parameters, the whole thing ends up very messy compared to just having separate functions. 
> 
> Using `range()` to pass in an array would be less efficient than min and max, but maybe good enough for small ranges. Perhaps in future we will have a separate "lazy range" type, which could then be handled as a special case.
> 
> In general, I don't think it's a function that I'd use often, but it seems a reasonable enough addition to the language.
> 
> Thanks,
> 
> Rowan Tommins
> [IMSoP]


Thanks for your thoughts.

I agree that it’s better to have a few separate functions for different use cases.

Regarding the lazy ranges, basically, it’s kind of `iterable`, but with bounds. 
I think it could be done as the others are: new IntRangeIterator(start: 0, end: 10, inclusive: true) / or as a new function range_iterator / or as a new flag argument in the original range function.
So, there are could be a function with:
- manual range bounds
— strings
— ints
— enums?
- iterator range bounds
— IntRangeIterator(start: 0, end: 10, inclusive: true)
— CharRangeIterator(start: ‘A', end: ‘D', inclusive: true)
— Any other `iterable`, including Generators and regular arrays

Actually, looks quite reasonable to re-use iterables. Nice catch, I really like it.

----------

Best regards,
Dmitrii Derepko.
@xepozz

---

## #129596 — Hans Henrik Bergan — 2025-12-12T17:26:51+00:00

URL: https://externals.io/message/129578#129596 · In reply to: #129591

trivial to make in userland.
how about making a composer coerce package first,
give it some time, check if it becomes popular,
 and if it does catch on, reconsider adding it to core?

---

## #129597 — Hans Henrik Bergan — 2025-12-12T17:46:46+00:00

URL: https://externals.io/message/129578#129597 · In reply to: #129578

> Hello,
>
> From time to time I need to write a few lines of code that usually look
> ridiculous:
>
> $var = $input === ‘yes’ ? ‘yes’ : ’no’
> $var = $input !== ‘yes’ ? ’no’ : $yes
> $var = $input > 10 ? 10 : $input
> $var = max(-10, min($input, 10)
>
> and many other variations.
> In Kotlin, I can use `coerceIn()` extension function with strings /
> numbers / comparables, which allows me to write such lines more readable.
>
> I suggest to add such function to PHP. The examples above may look like
> the following
>
> $var = coerce($input, variants: [“yes”, “no”], default: “yes”);
> $var = coerce($input, min: 0, max: 10, default: 5);
> $var = coerce($input, min: 0, max: 10, default: 5);
>
>
btw many of these are already covered by filter_var,

$var = $input === ‘yes’ ? ‘yes’ : ’no’
$var = $input !== ‘yes’ ? ’no’ : $yes
$var = coerce($input, variants: [“yes”, “no”], default: “yes”);
$var = coerce($input, min: 0, max: 10, default: 5);

is very close to
$var = filter_var($input,FILTER_VALIDATE_BOOL);
$var = !filter_var($input,FILTER_VALIDATE_BOOL);
$var =  filter_var($input,FILTER_VALIDATE_BOOL,
['options'=>['default'=>true]]);
$var = filter_var($input, FILTER_VALIDATE_INT, ['options'=>['min_range'=>0,
'max_range'=>10, 'default'=>5]]);

but if your syntax idea cover stuff like
$var = coerce($input, variants: [“yes”, “no”, "maybe"], default: “yes”);

then filter_var does not cover it (well, you could get creative with
FILTER_VALIDATE_CALLBACK, but that would be crazy, array_search would be
better lel)

but even so, your proposed syntax is certainly prettier than filter_var.

---

## #129601 — Dmitry Derepko — 2025-12-13T14:34:32+00:00

URL: https://externals.io/message/129578#129601 · In reply to: #129596

> 
> 
> trivial to make in userland.

Sure, almost everything is trivial to make in userland and re-use as a function.

> how about making a composer coerce package first, 
> give it some time, check if it becomes popular,
>  and if it does catch on, reconsider adding it to core?

I don’t think so. There’s no node-js world with left-pad function. 
People prefer to write plain php instead of re-using external function that’s needed to be downloaded and correctly loaded with autoload. Too much effort to re-use.

Moreover, event if a function is quite popular, it doesn’t mean it should be bundled: `dd` / `dump` / `u` / any Laravel global functions that’s users think it’s bundled.

I think it’s better to grep the world with structural search and find some cases:

- condition($a) ? $a : expr()
- if (condition($a)) { $a = expr() }

With more or less popular use-cases:
- $a == ‘desc’ ? ‘desc’ : ‘asc’
- $a == ’true’ ? ’true' : ‘false’
- $a > 10 ? 10 : ($a < 0 ? 0 : $a)
- max(0, min($a, 10)
- in_array($key, $values) ? $key : $default
- array_key_exist($key, $values) ? $values[$key] : $default
- isset($values[$key]) ? $values[$key] : $default
- any similar

It could be done if I prepare RFC and it will be necessary. Firstly, I’d like to discuss the idea itself.

----------

Best regards,
Dmitrii Derepko.
@xepozz
