On Sun, Aug 25, 2024, at 15:35, Larry Garfield wrote:
On Sat, Aug 24, 2024, at 11:49 AM, Bilge wrote:
Hi gang,
New RFC just dropped: https://wiki.php.net/rfc/default_expression. I
think some of you might enjoy this one. Hit me with any feedback.
This one already comes complete with working implementation that I’ve
been cooking for a little while. Considering I don’t know C or PHP
internals, one might think implementing this feature would be
prohibitively difficult, but considering the amount of help and guidance
I received from Ilija, Bob and others, it would be truer to say it would
have been more difficult to fail! Huge thanks to them.
Cheers,
Bilge
I am still not fully sold on this, but I like it a lot better than the previous attempt at a default keyword. It’s good that you mention named arguments, as those do replace like 95% of the use cases for “put default here” in potential function calls, and the ones it doesn’t, you call out explicitly as the justification for this RFC.
The approach here seems reasonable overall. The mental model I have from the RFC is “yoink the default value out of the function, drop it into this expression embedded in the function call, and let the chips fall where they may.” Is that about accurate?
My main holdup is the need. I… can’t recall ever having a situation where this is something I needed. Some of the examples show valid use cases (eg, the “default plus this binary flag” example), but again, I’ve never actually run into that myself in practice.
Potentially the most useful place would be in attributes. Take crell\serde (:p) for instance:
#[SequenceField(implodeOn: default . ’ ', joinOn: ’ ’ . default . ’ ')]
Where you may just want it to be a little more readable, but aren’t interested in the default implosion. In attributes, it has to be a static expression and I think this passes that test? At least that is one place I would find most useful.
Then there are things like the example I gave before, where you need to call some library code as library code and pass through the intentions. It also gets us one step closer to something like these shenanigans:
function configureSerializer(Serde $serializer = new SerdeCommon(formatters: default as $formatters));
Where we can call configureSerializer(formatters: new JsonStreamFormatter()).
Some pretty interesting stuff.
My other concern is the list of supported expression types. I understand how the implementation would naturally make all of those syntactically valid, but it seems many of them, if not most, are semantically nonsensical. Eg, default > 1
would take a presumably numeric default value and output a boolean, which should really never be type compatible with the function being called. (A param type of int|bool is a code smell at best, and a fatal waiting to happen at worst.) In practice, I think a majority of those expressions would be logically nonsensical, so I wonder if it would be better to only allow a few reasonable ones and block the others, to keep people from thinking nonsensical code would do something useful.
I’m reasonably certain you can write nonsensical PHP without this feature. I don’t think we should be the nanny of developers.
— Rob