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

Reply via email to