On Mon, Jun 10, 2024, at 19:51, Rodrigo Vieira wrote:
> I didn't like the `Prefix-style` syntax. I prefer the `Hook-embedded-style` 
> syntax. First let's look at the counterpoints of the `Prefix-style` syntax:
> 
> ## 1) "`Prefix-style` is more visually scannable"
> > The set visibility is 10 lines away from the get visibility!
> 
> Solution:
> ```php
> class HookEmbeddedStyle
> {
>     public string $phone {
>         private set {
>             $this->phone = implode('', array_filter(fn($c) => is_numeric($c), 
> explode($value)))
>         }
>         get {
>             if (!$this->phone) {
>                 return '';
>             }
>             if ($this->phone[0] === 1) {
>                 return 'US ' . $this->phone;
>             }
>             return 'Intl +' . $this->phone;
>         }
>     }
> }
> ```
> The set visibility is not 10 lines away from the get visibility if you put it 
> at the top. For me this is about code convention, not about syntactic 
> structure:
> only put the hook with explicit visibility at the top, when some of the hooks 
> do not have explicit visibility!
> 
> ## 2) "`Prefix-style` is shorter"
> ```php
> public private(set) string $name;
> 
> public string $name { private set; }
> ```
> 
> Irrelevant to consider 1-2 characters.
> If you break the lines needed for the hook block, the line (the horizontal 
> size) is smaller when using `Hook-embedded-style` and in my opinion it is 
> more readable because there is less information per line:
> ```php
> public private(set) string $name;
> 
> public string $name {
>    private set;
> }
> ```
> 
> ## 3) "`Prefix-style` doesn't presume a connection with hooks"
> > As noted above in "Interaction with hooks", visibility controls exist 
> > independently of hooks.
> 
> I agree, but with Property Hooks, this should now define the overall 
> visibility only. Like a bigger gate that you open, and there are other doors 
> defining the visibility of the operations get, set (hooks).
> 
> > In fact, as implemented, they don't interact at all. Using hook syntax for 
> > visibility controls is therefore surprising and confusing.
> 
> Why "surprising and confusing"? I see hooks as a different kind of 
> function/method. 
> Property Hooks RFC shouldn't pass without requiring hook parentheses, for any 
> hook when the property is not abstract. The `$value` in the `set` hook seems 
> to come out of nowhere to some people (the exception is for hooks declared on 
> an abstract property which you can define without parameters and thus you are 
> free to define whatever parameters you want on the concrete property).
> 
> When you define a method in PHP, it should be possible to omit the 
> "function", but the parameters should be required because that's the nature 
> of a function/method: to have parameters.
> 
> ## 4) "It's non-obvious in `Hook-embedded-style` what hook behavior should be 
> implied"
> 
> > ...So “arrays with hooks can do less” is already an established fact of the 
> > language. However, if the hook-style syntax is used for visibility:
> 
> ```php
> class A
> {
>     public array $arr { protected set; }
> }
>  
> class B extends A
> {
>     public function add(int $val)
>     {
>         // Should this be legal?
>         $this->arr[] = $val;
>     }
> }
>  
> $b = new B();
>  
> $b->add(5);
> ```
> First of all: non-abstract property hook must have a body.
> Second: when asymmetric visibility is explicit, it means that symmetric 
> visibility is implicit: a declared hook that does not have declared 
> visibility has the same general visibility as the property, in this case: 
> public.
> 
> Third:
> There's another limitation on hooks here that makes things a bit confusing: 
> there's a missing hook for a specific operation because you can clearly 
> separate the `set` from the `push` operation...
> 
> Solution:
> ```php
> abstract class A
> {
>     abstract public array $arr {
>         push; // Hook available only for "array" type properties only; public 
> visibility
>         private set;
>     }
> }
> 
> class B extends A
> {
>     public array $arr {
>         push ($value) { // `public push ...` here is redundant
>             // Mandatory to implement logic here.
>         }
>         private set ($value) {
>             // Mandatory to Implement logic here.
>         }
>     }
> 
>     public function __construct ()
>     {
>         // Legal ✅ (set hook is protected)
>         $this->arr = [1]; // call set hook
>     }
>     public function add(int $value)
>     {
>         // Legal ✅ (push hook is public)
>         $this->arr[] = $value; // call push hook
>     }
> }
> 
> $b = new B();
> 
> $b->add(5);
> $b->arr; // Legal ✅ (Inherited from the general visibility that is public) 
> $b->arr = [1, 2, 3]; // Fatal error ❌ - access to set hook is private only
> $b->arr[] = 4; // Legal ✅ - call public push hook
> ```
> 
> My point: `Prefix-style` is not future-proof
> ## 1) The `Prefix-style` is not compatible with new hooks
> If more hooks are added in the future, such as the `push` hook for arrays or 
> even a hook that is compatible with all types such as `init`, 
> `Hook-embedded-style` will become compatible, but `Prefix-style` not.
> 
> ## 2) Hook overloading
> If hook overloading is added in the future, `Prefix-style` would not be 
> supported to have this granular visibility into operations. For example, it 
> might be possible to add a public hook and a protected hook for the same 
> operation, where one would be triggered if the operation occurred from 
> outside the class, and the other if the operation occurred from inside the 
> class.
> Em 10 de jun. de 2024 13:15 -0300, Tiffany <tiffany.k.tay...@gmail.com> 
> escreveu:
>> 
>> On Wed, May 29, 2024, 2:16 PM Larry Garfield <la...@garfieldtech.com> wrote:
>>> As promised, Ilija and I offer this revised version of asymmetric 
>>> visibility. 
>>> 
>>> https://wiki.php.net/rfc/asymmetric-visibility-v2
>>> 
>>> It's still essentially the same as last year's version, but with a few 
>>> adjustments and changes:
>>> 
>>> * readonly properties are now supported in a logical fashion.
>>> * We've brought back the abbreviated form, as public-read, something else 
>>> set is the most common use case.
>>> * The section on magic methods has been greatly simplified.  The 
>>> implementation itself hasn't changed, but the explanation is a lot less 
>>> confusing now.
>>> * We've explained how aviz interacts with hooks (they don't, really) and 
>>> with interface properties (in the obvious way), which didn't exist at the 
>>> time of the last draft.
>>> * We've added a section with examples of how aviz is a concrete 
>>> improvement, even in a world with readonly and hooks.
>>> * We've added a section discussing why the prefix-style syntax was chosen.
>>> 
>>> *dons flame retardant suit*
>>> 
>>> --
>>>   Larry Garfield
>>>   la...@garfieldtech.com
>> 
>> Sending an email to quickly enable a new mailing list subscriber to engage 
>> in the conversation.

I’m also not a fan of the prefix style, but for different reasons. My main 
reason is that it increases the minimum line-length, potentially forcing you to 
chop things down into awkward looking lines:

public
private(set)
string $longvarname {
 get;
 set;
}

I find that extremely hard to scan, but maybe others do not. The more natural 
looking syntax is easier to scan and reason about (IMHO):

public
string $longvarname {
 get;
 private set;
}

If I’m having to read the code, I prefer to have everything near where it is 
used so I don’t have to scroll up to the top and see its visibility. Granted, I 
haven’t used property hooks and I have no idea how IDEs will help here; maybe 
it is a non-issue — but I guess people still have to do code reviews which very 
rarely comes with IDE powers.

— Rob

Reply via email to