Re: [RFC] Default expression

From: Date: Mon, 26 Aug 2024 04:44:44 +0000
Subject: Re: [RFC] Default expression
References: 1 2  Groups: php.internals 
Request: Send a blank email to [email protected] to get a copy of this message
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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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] <[email protected]> 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] <[email protected]> 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 <[email protected]> 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


Thread (101 messages)

« previous php.internals (#125252) next »