On Wed, Aug 31, 2022, at 4:26 PM, Tim Düsterhus wrote:
> Hi
>
> On 8/31/22 22:43, Larry Garfield wrote:
>> ## References make everything worse
>>
>> […]
>>
>> That problem wouldn't happen if all we're changing is visibility, however.
>> That means in the C# style, we would need to differentiate whether the block
>> on the right is intended to disable references or not. Ilija has proposed
>> `raw` to indicate that. That would mean:
>>
>> ```php
>> class Test
>> {
>> public $a { private set; }
>> public $b { private raw; }
>>
>> public function inScope()
>> {
>> echo $this->a; // echo $this->getA();
>> $this->a = 'a'; // $this->setA('a');
>>
>> echo $this->b; // echo $this->b;
>> $this->b = 'b'; // $this->b = 'b';
>> }
>> }
>>
>> $test = new Test();
>>
>> echo $test->a; // echo $test->getA();
>> $test->a = 'a'; // Error, set operation not accessible
>>
>> echo $test->b; // echo $test->getB();
>> $test->b = 'b'; // Error, set operation not accessible
>> ```
>>
>> The take-away for the asymmetric visibility only case is that we would need
>> to use `raw` instead of `set`, in order to avoid confusion later with
>> accessor hooks and whether or not to disable references.
>>
>> The Swift-style syntax, as it does not require any hook-like syntax to just
>> control visibility, does not have this problem. There is no ambiguity to
>> resolve, so no need for a `raw` keyword.
>>
>
> I've read through that explanation three times, but don't understand why
> the C#-style syntax would require to differentiate between `set` and
> `raw`. Isn't the difference between "visibility only" and "accessor" not
> clear [1] by having either '{' or ';' after the 'set'?
>
> [1] Read: Clear to the engine, not talking about the human reader here.
Yeah, it's complicated, and Ilija had to explain it to me several times. :-)
The tricky part is that there's *three* different toggles involved here.
1. Asymmetric visibility.
2. Accessor hooks.
3. Disabling references on properties.
Invoking 2 necessarily implies also doing 3, for reasons given above. However,
we also want people to be able to enable 3 on its own, so that IF they enable
accessor hooks later, it is transparent and doesn't imply breaking references
unexpectedly. (Viz, you could have a value object full of `public string $foo
{}` type properties, which disables references, and then slip in a get/set hook
later and no one notices.)
So we need a way to indicate "I'm using a-viz, and disabling references" as
well as "I'm using a-viz, and not disabling references."
With the Swift style syntax, that's super straightforward.
public string $foo; // No a-viz, references work.
public string $foo {} // No a-viz, references disabled.
public private(set) string $foo; // a-viz, references work.
public private(set) string $foo {} // a-viz, references disabled.
And the {} makes a convenient marker because you'd be adding it in the future
anyway if you add hooks, which would force disabling of references. So it's a
natural flow from one option to the next.
With the C# style, a-viz means you're *always* putting braces on the right, so
we cannot do that. Instead, you need
public string $foo; // No a-viz, references work.
public string $foo {} // No a-viz, references disabled.
public string $foo { private raw; } // a-viz, references work.
public string $foo { private set; } // a-viz, references disabled.
So then the toggle for disabling references is "there's a set or get keyword
inside the braces", but we then need a different keyword for "I'm *just* doing
a-viz, and I don't want to disable references." Hence, "raw".
(I'm assuming in the above that Ilija is able to make omitting the "get; set;"
if there's no body for them. He's reasonably sure we can but hasn't confirmed
it.)
Is that clearer?
--Larry Garfield
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php