Re: Callable arguments cannot have default value
| From: | Claude Pache | Date: | Tue, 28 Nov 2023 09:54:58 +0000 |
| Subject: | Re: Callable arguments cannot have default value | ||
| References: | 1 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-121820@lists.php.net to get a copy of this message | ||
> Le 28 nov. 2023 à 00:59, Sergii Shymko <sergey@shymko.net> a écrit :
>
> Hi,
>
> Wanted to bring up an inconsistent behavior of callable arguments compared to arguments of
> other types.
> Callable argument cannot have a default value (tested string or array types - both are not
> permitted).
> The same exact value works perfectly fine when passed dynamically, it just cannot be specified
> as a default.
> The workaround is to remove the type annotation which is obviously undesirable.
>
> Here’s an example:
> declare(strict_types=1);
> function test(callable $idGenerator = 'session_create_id') {
> $id = $idGenerator();
> // ...
> }
>
> The function/method declaration above produces the following error on all PHP versions:
> Fatal error: Cannot use string as default value for parameter $idGenerator of type callable in
> /tmp/preview on line 4
>
> Note that the exact same string argument can be passed without any issue:
> function test(callable $idGenerator) {…}
> test('session_create_id’);
>
> Is there a specific architectural limitation causing this that's hard/impossible to
> overcome?
>
> I’m aware that class properties cannot be annotated with callable - another unfortunate
> limitation.
> Callable is not a real type like other primitive types which causes all these inconsistencies,
> correct?
> Callable properties (separate topic) may be a challenge, but can at least argument defaults be
> supported?
>
> Regards,
> Sergii Shymko
Hi Sergii,
The big problem with the
callable type, is that it can be check only at runtime. For
instance:
```php
function foo(callable $x) { }
foo('strlen'); // ok
foo('i_dont_exist'); // throws a TypeError
```
Another complication, is that a value of the form [ $class, $protected_or_private_method
] may or may not be callable depending on whether the method is visible from the current
scope.
In other words, contrarily to all other types, callable depends both on runtime state
and on context.
Therefore, an argument of type callable cannot have a default value, because it is not
known in advance whether the default value will be valid when used.
For the case of class properties, see https://wiki.php.net/rfc/typed_properties_v2#supported_types
—Claude