On 31 October 2025 12:04:29 GMT, "Tim Düsterhus" <[email protected]> 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]

Reply via email to