This is a general comment so not replying to anyone in particular hence the top-posting (but with some bottom-posts in particular reply below.)
The RFC — which I am neither pro nor con for — proposes allowing default to be an expression, and while many like and support the RFC others are (not quite) demanding that it must be limited to its own subset of expressions, because, concerns.
It seems to me the "concerns" fall into two categories:
1. Some expressions make no sense so we should disallow them, and
2. Allowing default to be an expression makes it part of the published API.
Speaking only to #1 for the moment, there are many different places in PHP where certain expressions make no sense either, yet I do not see those objecting calling the question for those other scenarios, and I ask myself "Why not?"
One obvious answer is "because those are status quo and this is not" but I also maybe because the many non-sensical things that can be done elsewhere are, in practice, not a problem as nobody ever does them. And why not? Because...they are nonsensical. Given this the arguments against feel to me to be rather bikesheddy. But I will come back to #1.
Moving on to #2 I respect the argument in theory. But as we are constantly told the RFC author's burden is to prove the necessity, it seems only reasonable and fair to expect that — when many people see the utility of and support an RFC — that those who object to it should provide some concrete examples of how their concerns would manifest problems rather than just say "it might allow something bad."
I have looked for but yet not seen any examples of how effectively publishing a default value could actually cause a significant problem — and this is the important part — in a real-world scenario and not just a contrived one.
Sure if I have `foo(int $index=1)`, a developer calls with `foo(default*3)`, and then the author of foo changes the signature to `foo(int $index=0)` that might cause problems, but what is a real world scenario where a developer would actually do that, the author then change it, and then is causes a non-trivial problem?
Given how much support this RFC appears to have, I think it is incumbent on those against it to give valid real-world examples where their fears would materialize and cause more than a trivial problem. Again, while I am not pro or con on this RFC I do think the pro arguments have been better conceived than the con arguments, regardless of the underlying merit of the RFC, hence why I comment.
On Aug 25, 2024, at 4:40 PM, Larry Garfield <larry@garfieldtech.com> wrote:
To the extent possible, the language and compiler should prevent you from doing stupid things, or at least make doing stupid things harder.
...
This is the design philosophy behind all type systems: Make illogical or dangerous or "we know it can't work" code paths a compile error, or even impossible to express at all.
Good design makes the easy path the safe path.
In concept, I am in violent agreement with you.
Rob has shown some possible, hypothetical uses for some of the seemingly silly possible combinations, which may or may not carry weight with people. But there are others that are still unjustified, so for now, I would still put "default != 5" into the "stupid things" category, for example.
I think you imply that there is a dichotomy or at least a 1-dimensional spectrum?
I think however there is at least a two (2) other dimensions, and they include:
2. "How trivial vs. damaging is a thing" and
3. "How likely are people to accidentally do that stupid thing?"
If the damage is trivial and/or the thing they is very unlikely for them to do — maybe because it is non-sensical — then do we really need extra guard rails? Passing `default != 5` to an int parameter is (IMO) both unlikely and not particularly damaging (if type-hinted, an error will be thrown.)
But if you disallow `default!=5`, then you (likely?) also disallow `default!=5 ? default : 0` and any other *sensical* expression with that sub-expression. Do we really want to flesh out all the potential nonsensical expressions for a given use-case and build a custom parser for this one RFC?
I could see having a context-based expression parser getting an RFC in its own right, but IMO doing so would be wildly out-of-scope for this RFC. And if such as RFC were pursued, I think in the vast majority of cases it should be employed by the userland developer and not in PHP core. But I digress.
So please provide examples where nonsensical expressions cause real-world problems. If you can, then maybe everyone supportive of the RFC will see use-cases where the RFC is problematic. But without good examples illustrating serious problems, is there really anything to worry about here?
BTW, you argue about unintended consequences that could not be foreseen hence why complex features need to be fully fleshed out — and I agree — but this RFC does not appear to be complex so finding problematic expressions should be relatively easy, if those examples do indeed exist.
On Aug 25, 2024, at 4:32 PM, John Coggeshall <john@coggeshall.org> wrote:
but I just can't get behind the idea that (default)->foobar() is a valid expression in this context or a good idea for the language.
Let me propose this example and see if you still hold firm to your option that the following expression would not be valid and that it still would not be a good idea for the language:
class MyDependency {...}
function doSomething(MyDependency $dep= new MyDependency) {...}
doSomething((default)->WithLogger(new Logger));
On Aug 25, 2024, at 12:23 PM, John Coggeshall <john@coggeshall.org> wrote:
I won't vote for this RFC if the above code is valid, FWIW. Unlike include , default is a special-case with a very specific purpose -- one that is reaching into someone else's API in a way the developer of that library doesn't explicitly permit.
Ok, so if a developer of the API currently wants to indicate that other developers CAN explicitly reach in then how would they do that, currently?
Your argument seems to be it should implicitly be disallowed, but I do not see any way in which you are proposing a developer could explicitly empower a developer to allow it. At least not without a ton of boilerplate which, for each default value, turns into a lot of extra code to create and then maintain.
It seems one-sided to argue against allowing something that "has not been explicitly allowed" if there is no way to explicitly allow it. And I get you may say "well that's not my job" to which —if you did — I would ask "Do you really only want to be the one who brings the problem but not the solution?"
On Aug 25, 2024, at 12:21 PM, Rowan Tommins [IMSoP] <imsop.php@rwec.co.uk> wrote:
The Reflection API is a bit like the Advanced Settings panel in a piece of software, it comes with a big "Proceed with Caution" warning. You only move something from that Advanced Settings panel to the main UI when it's going to be commonly used, and generally safe to use. I don't think allowing arbitrary operations on a value that's declared as the default of some other function passes that test.
You analogy is faulty. You are conflating a complex API — Reflection — with one use-case of that API which — per the RFC — has well-defined syntax and semantics and purely due to its simplicity is more likely to be used than the Reflection API and far less likely to be used incorrectly than the Reflection API.
On Aug 25, 2024, at 11:31 AM, Rowan Tommins [IMSoP] <imsop.php@rwec.co.uk> wrote:
A few rules that seem logical to me:
All those rules were "these are the things we should not do" but few "here is why these might be a problem" but no examples, and no "here is why developers are *likely* to do those things that are actually problematic, with examples."
Or said more colloquially, "If a language has a foot-gun but no developer ever pulls that foot-gun's trigger, is it really a foot-gun?"
library authors ...now also need to question whether someone is relying on "default + 1" having some specific effect?
Can you give a specific example from code we are likely to find in a production application — vs. a forum debate — where someone is likely to use `default+1` AND where it would be problematic for the author?
There may well be one but I cannot currently envision it, which is why I ask.
Beyond that, I'm struggling to think of meaningful uses: "whatever the function sets as its default, do the opposite"; "whatever number the function sets as default, raise it to the power of 3"; etc. Again, they can easily be added in later versions, if a use case is pointed out.
Being pedantic, but how is `default^3` the "opposite" of `default`?
On Aug 25, 2024, at 4:29 PM, John Bafford <jbafford@zort.net> wrote:
is because PHP doesn't currently allow default values to be computed at runtime. (Maybe it should.)
(Amen.)
Summary:
After writing this response I am currently leaning into the pro column for this RFC because I think the arguments for the pro are stronger than the arguments for the con. But if better con arguments emerge my opinion could change.
Where I would see this functionality to be most useful would be:
1. Modifying a default bitmapped argument to add or remove one or more bits.
2. Creating a class instance based on the default — with Wither methods() — where I need to modify a few properties but want to keep all the rest of the default value.
Not saying there are not other use-cases, but those other use-cases have not (yet?) occurred to me.
-Mike