Hi Internals,
New RFC idea just dropped. When writing a function, we can specify
defaults for its parameters, and when calling a function we can leverage
those defaults /implicitly/ by not specifying those arguments or by
"jumping over" some of them using named parameters. However, we cannot
/explicitly/ use the defaults. But why would we want to?
Sometimes we want to effectively /inherit/ the defaults of a function
we're essentially just proxying. One way to do that is copy and paste
the entire method signature, but if the defaults of the proxied method
change, we're now overriding them with our own, which is not what we
wanted to do. It is possible, in a roundabout way, to avoid specifying
the optional parameters by filtering them out (as shown in the next
example). The final possibility is to use reflection and literally query
the default value for each optional parameter, which is the most awkward
and verbose way to inherit defaults.
Let's use a concrete example for clarity.
function query(string $sql, int $limit = PHP_INT_MAX, int $offset = 0);
function myQuery(string $sql, ?int $limit = null, ?int $offset = null) {
query(...array_filter(func_get_args(), fn ($arg) => $arg !== null));
}
In this way we are able to filter out the null arguments to inherit the
callee defaults, but this code is quite ugly. Moreover, it makes the
(sometimes invalid) assumption that we're able to use `null` for all the
optional arguments.
In my new proposal for /explicit /callee defaults, it would be possible
to use the `default` keyword to expressly use the default value of the
callee in that argument position. For example, the above implementation
for myQuery() could be simplified to the following.
function myQuery(string $sql, ?int $limit = null, ?int $offset = null) {
query($sql, $limit ?? default, $offset ?? default);
}
Furthermore, it would also be possible to "jump over" optional
parameters /without/ using named parameters.
json_decode($json, true, default, JSON_THROW_ON_ERROR);
This proposal is built on the assumption that it is possible to specify
that PHP should only accept the `default` expression in method and
function call contexts. For example, it would not be valid to return
`default` from a function and substitute it that way; my proposal is to
only permit `default` in literal function calling contexts. My knowledge
of internals is insufficient (read: non-existent) to know whether or not
this restriction is possible to implement, but if it is, I think this is
a good idea. What do you think?
Cheers,
Bilge