Re: [PHP-DEV] [RFC] Property write visibility

  110781
June 29, 2020 15:16 david.proweb@gmail.com (David Rodrigues)
With all possibilities maybe we have:

- public set:private unset:private isset:private get:private

set:private could be readed like "set is private".

Where:

- public is "general visibility" for set, unset, isset and get;
- set: affects write visibility;
- unset: affects unset() visibility;
- isset: affects isset() visibility;
- get: affects read visibility;

In this case, maybe we should think on possibility of usage like:

class A {
    get:public $x;
}

That determines that $x is private, except by get.

In counterpart, I do not know if it makes sense for isset mode, because if
we have get:public, and $x is accessible, so it is isset by nature.


Atenciosamente,
David Rodrigues


Em seg., 29 de jun. de 2020 às 12:03, Deleu <deleugyn@gmail.com> escreveu:

> As a user, I would prefer the original proposed syntax `public:private` or > the Swift syntax `public private(set)` than the alternative syntax `public > int $x {protected set; protected unset;}`. > > On Mon, Jun 29, 2020 at 4:22 PM Mark Randall <marandall@php.net> wrote: > > > On 29/06/2020 15:13, André Rømcke wrote: > > > Would something closer to Swift be better? If so I expanded the RFC > with > > > that syntax option as well: > > > > Borrowing from the various accessors RFCs: > > > > public int $x { > > protected set; > > protected unset; > > } > > > > Then a future RFC can build upon it by adding the override functions > > while keeping the same base syntax. > > > > Mark Randall > > > > > > -- > > PHP Internals - PHP Runtime Development Mailing List > > To unsubscribe, visit: https://www.php.net/unsub.php > > > > > > -- > Marco Aurélio Deleu >
  110789
June 29, 2020 21:15 larry@garfieldtech.com ("Larry Garfield")
On Mon, Jun 29, 2020, at 10:16 AM, David Rodrigues wrote:
> With all possibilities maybe we have: > > - public set:private unset:private isset:private get:private > > set:private could be readed like "set is private". > > Where: > > - public is "general visibility" for set, unset, isset and get; > - set: affects write visibility; > - unset: affects unset() visibility; > - isset: affects isset() visibility; > - get: affects read visibility; > > In this case, maybe we should think on possibility of usage like: > > class A { > get:public $x; > } > > That determines that $x is private, except by get. > > In counterpart, I do not know if it makes sense for isset mode, because if > we have get:public, and $x is accessible, so it is isset by nature. > > > Atenciosamente, > David Rodrigues > > > Em seg., 29 de jun. de 2020 às 12:03, Deleu <deleugyn@gmail.com> escreveu: > > > As a user, I would prefer the original proposed syntax `public:private` or > > the Swift syntax `public private(set)` than the alternative syntax `public > > int $x {protected set; protected unset;}`. > > > > On Mon, Jun 29, 2020 at 4:22 PM Mark Randall <marandall@php.net> wrote: > > > > > On 29/06/2020 15:13, André Rømcke wrote: > > > > Would something closer to Swift be better? If so I expanded the RFC > > with > > > > that syntax option as well: > > > > > > Borrowing from the various accessors RFCs: > > > > > > public int $x { > > > protected set; > > > protected unset; > > > } > > > > > > Then a future RFC can build upon it by adding the override functions > > > while keeping the same base syntax. > > > > > > Mark Randall
Andre, thank you for this RFC. I'm really glad to see asymmetric visibility getting more attention as I think it's a good example of a small change with huge functionality potential. This reply is me thinking aloud, so I apologize if it isn't quite linear. For reference, I wrote about asymmetric visibility a few months back in my Object Ergonomics article: https://peakd.com/php/@crell/improving-php-s-object-ergonomics To recap what I said there: * Yes please. This change has a really good syntax-to-functionality ratio, and effectively solves the same problem as write-once or immutable properties in a much more flexible and PHP-ish way. * Any syntax should absolutely be designed with future extension to property accessors in mind. Not because we are guaranteed to ever have them, but because they're hard enough as is to implement (which is why we don't have them yet) so no sense adding more syntactic noise to make them even harder. To that, I would also add: * We should keep in mind that between constructor promotion and annotations, property syntax is starting to get potentially rather busy. * Self-documenting syntax is good syntax. Off the bat, therefore, I prefer get:public set:private. It's nicely self-documenting, order doesn't matter, and we can ignore isset/unset for now but if we do find a need for them later the pattern is cleanly extensible to that. Which would lead to the following possible code in PHP 8: class Point { public function __construct( @@Positive get:public set:private int $x, @@Positive get:public set:private int $y, @@Positive get:public set:private int $z, ) {} } Which is honestly pretty nice, especially compared to what it would be in 7.4. However, now expand that to include accessors in a hypothetical future (these are pointless accessor methods but just to keep the example consistent): class Point { public function __construct( @@Positive get:public {return $this->x; } set:private(int $x) { $this->x = $x; } int $x, @@Positive get:public {return $this->y; } set:private(int $y) { $this->y = $y; } int $y, @@Positive get:public {return $this->z; } set:private(int $x) { $this->z = $z; } int $z, ) {} } Now it's getting weird, primarily because the methods all come before the variable declaration. That may be comfortable for German speakers but not for the rest of us. ;-) It's also much worse if the accessor methods are multi-line. That's why the previous accessor RFC settled on putting methods in a block after the variable definition. One possible solution to that is, were an accessor RFC to be introduced in the future, that it would repeat the get/set keyword only: class Point { get:public set:private int $x { get { return $this->x; } set ($x) { $this->x = $x; } } get:public set:private int $y { get { return $this->y; } set ($y) { $this->y = $y; } } get:public set:private int $z { get { return $this->z; } set ($z) { $this->z = $z; } } public function construct(...) {} } That's a bit redundant, but... I think probably acceptable. So, I think I'd favor get:X set:Y as modifiers, with the assumption that 1) Should accessors ever happen they'd be expected to NOT duplicate the visibility, either with the option above or something similar. 2) isset and unset can be skipped for now but the RFC can explicitly state that should they ever be needed, they'd be added in the same way. Here endeth my analysis. Thanks again, Andre! --Larry Garfield