On 26 August 2024 05:44:44 BST, Mike Schinkel <[email protected]> wrote:
>> 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.
You are misunderstanding the analogy. The analogy is that the Reflection API as a whole is like the
Advanced Settings page, with its big "Proceed with Caution" sign. Accessing the default
value of someone else's function is like a setting which you can only currently access on that
advanced setting screen, but people are proposing we move to a big tempting tickbox on the main UI.
I was responding to someone justifying anything and everything the proposal allows, because
Reflection already allows it. If the feature was "first class syntax to access private methods
of a class", I don't think it would be controversial to challenge it. Saying
"Reflection can already do it" would be a poor defence, because part of Reflection's
job is to break the normal rules of the language.
>> On Aug 25, 2024, at 11:31 AM, Rowan Tommins [IMSoP] <[email protected]> wrote:
>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?
The overriding rule, in my head, is that the caller shouldn't need to know, and shouldn't
be able to find out, what a particular implementation has chosen as the default. So the particularly
problematic operations are things like this:
foo($whatWasTheDefault=default)
foo(logAndReturn(default))
foo(doSomethingUnrelated(default) && false?: default)
I can see people inventing use cases for these as soon as they're available, but by doing so
they will be completely changing the meaning of default parameters, which currently mean "I
trust the implementation to substitute something valid here, and have no interest in what it
is".
Note that under inheritance, the default value may even change type:
class A { public function foo(int $bar=42) { ... } }
class B extends A { public function foo(int|string $bar='hello') { ... } }
Perhaps that would be more obvious if the declaration happened to look like this:
function foo(optional int $bar) {
default for $bar is 42;
// ...
}
As far as I can see, nobody has actually justified reading values out in this way, only said
it's a side-effect of the current implementation.
You ask how a library can provide access to that default, and the answer is generally pretty
trivial: define a public constant, and refer to it in the parameter definition. I sometimes do that
with private constants anyway, just to make the value more easily documented, or use it in a couple
of different contexts.
The only exception I think is "new in initializer", where you would have to provide a
function/method instead of a constant, and couldn't currently reuse it in the actual signature.
Aside: one of those examples brings up an interesting question: is the value pulled out by
"default" calculated only once, or each time it's mentioned? In other words, would
this create 3 pointers to the same object, or 3 different objects?
foo(array|Something $x=new Something);
foo([default, default, default]);
Rowan Tommins
[IMSoP]