Re: [RFC] Nullable and non-nullable cast operators
On 31 October 2025 12:04:29 GMT, "Tim Düsterhus" <tim@bastelstu.be> wrote:
>Given that the proposed semantics matches that of function calls, I share Rowan's
>suggestion of using “function-call style” casts:
>
> function string_internal(string $input): string { return $input; }
> function string(mixed $input, bool $passNull = false): string {
> if ($passNull && $input === null) return null;
>
> return string_internal($input);
> }
>
> $input = 123;
> $str = string($input);
> var_dump($str);
>
>In fact this is already valid PHP as of now and would allow polyfilling the new operators: https://3v4l.org/ldvFb and it nicely circumsteps all the backwards
>compatibility and ecosystem impact as well as the precedence issue. The only issue I'm seeing
>is possible confusion with the existing strval() and friends. But perhaps this is not
>relevant in practice.
The ability to polyfill is very tempting, but I think this would be a dead end. There's no
natural way to express nullable types, and no way at all to allow arbitrary union types. It would be
like having "string_function foo() {}" instead of "function foo(): string {}"
That's why both of my example syntaxes had the type as some sort of *parameter*. I don't
think there's any way around introducing new syntax for that, because you can't "pass
a type" to a normal function.
There's also no obvious reason why int($foo) and intval($foo) should do different things, and
neither is inherently "better".
The new int() would cover the "assertion" case (where an invalid value is a surprise that
should abort processing), and (int) or intval() would cover the "sanitisation" case (where
you want to substitute an empty or chosen value for invalid input), but the names don't tell
you which is which.
And neither is useful for the "validation" case (where you want to efficiently test user
input).
Rowan Tommins
[IMSoP]
Thread (18 messages)