Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-06-11 Thread Lanre
Yeah i know im just one irrelevant person with crazy ideas (stable engine
etc). I never said PHP needs me, I simply decided to no longer be a part of
this shithole. I mean i brought up valid points about the engine, yet here
you are with a retarded cheeky response when you could've just ignored me.

Cheers,
Lanre

On Tue, Jun 11, 2024 at 1:44 AM Lynn  wrote:

>
>
> On Tue, Jun 11, 2024 at 3:15 AM Lanre  wrote:
>
>> Why invest time in crafting yet another pull request or RFC when it's
>> glaringly obvious that you guys have no clue what you're doing? First,
>> there's the questionable decision to implement JIT in 8.0, followed by the
>> introduction of an entirely new library (IR) to a language that's
>> predominantly request-based, boasting nothing more than a rudimentary AST,
>> plagued with inconsistencies, clinging to CGI, and practically useless
>> without a framework. And now, after greenlighting a dubious property hooks
>> RFC, the same individuals are embroiled in a debate over Asymmetric
>> Visibility? If you can't think up ways to make the engine "more rubust and
>> sturdy" as a paid member of the foundation then maybe it is also time to
>> start reconsidering my donations.
>>
>> On Mon, Jun 10, 2024 at 3:42 PM Derick Rethans  wrote:
>>
>>> On 10 June 2024 21:17:38 BST, Lanre  wrote:
>>> >You guys are killing PHP. There is a lot of work to be done on the
>>> engine
>>> >to modernize it and make it more robust and sturdy. Shit like this just
>>> >adds more complexity to PHP in the name of convenience. I think this is
>>> my
>>> >cue to explore other languages for handling requests
>>>
>>>
>>> Please moderate your language.
>>>
>>> Posts like this do nothing except a higher chance for people to ignore
>>> you, when you've actual points to make, such as credible suggestions as to
>>> how to make PHP "more rubust and sturdy".
>>>
>>> Looking forwards to your RFCs and patches.
>>>
>>> cheers
>>> Derick
>>>
>>
> Sometimes people grow in a different direction than a project and that's
> okay, you should do what you feel is best for you. Even if that means you
> will no longer be enriching us with your presence, I think the PHP project
> will eventually recover from such great loss.
>


Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-06-11 Thread Larry Garfield
On Tue, Jun 11, 2024, at 1:48 PM, Rob Landers wrote:
> On Tue, Jun 11, 2024, at 15:36, Larry Garfield wrote:
>> On Tue, Jun 11, 2024, at 6:47 AM, Rob Landers wrote:
>> 
>> > 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
>> 
>> I have never in my life seen someone split the visibility to a separate line 
>> from the type and variable name in PHP.  I don't know why anyone would start 
>> now, especially not because of hooks or aviz.  I just checked and PER-CS 
>> very directly states "All keywords MUST be on a single line, and MUST be 
>> separated by a single space."  So splitting it like shown above would be 
>> against standard coding conventions anyway.
>> 
>> This is really a strawman argument.
>> 
>> --Larry Garfield
>> 
>
> I’m willing to concede that it might be a straw man, though I did not 
> intend it as such. I was being serious in my pointing out of it 
> increasing the minimum line length and PER isn’t the only coding 
> standard. It may result in some ugly code, as in my example.
>
> — Rob

I didn't think it was deliberate.  But in practice:

public string $foo; // 13 chars, excluding variable.
public readonly string $foo; // 21 chars, excluding variable.
private(set) string $foo;// 18 chars, excluding variable.
protected(set) string $foo;   // 19 chars, excluding variable.
public private(set) string $foo  // 24 chars, excluding variable.
public protected(set) readonly string $foo; // 29 chars, excluding variable.

Even in the most pathologically long case, where you include every possible 
modifier, we're up to 29 characters.  Typical coding guidelines say to use 
either 80 or 120 character lines.  So even factoring in indentation, you're 
still going to need a 50+ character variable name before line length becomes an 
issue.  At that point, the issue is your silly variable name, not the modifiers.

The far more common cases would be `private(set) string $foo` and 
`protected(set) string $foo`, both of which are... shorter than `public 
readonly string $foo`, which we already have.

In comparison, using hook-embedded style without hook implementations, we get:

public string $foo { private set; } // 29 characters excluding variable

So the base case with hook-embedded style is about 50% more characters than the 
prefix-style.

The only way that it wouldn't be is to structure it like so:

public string $foo {
  private set;
}

At which point I'd argue that's worse in every regard, especially with how many 
properties are now defined in constructor promotion.  That would be vastly 
uglier in constructor promotion than the inline style, with either syntax.

To whatever extent we care about line length and conciseness, prefix-style wins 
over hook-embedded, unquestionably.

--Larry Garfield


Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-06-11 Thread Rob Landers
On Tue, Jun 11, 2024, at 15:36, Larry Garfield wrote:
> On Tue, Jun 11, 2024, at 6:47 AM, Rob Landers wrote:
> 
> > 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
> 
> I have never in my life seen someone split the visibility to a separate line 
> from the type and variable name in PHP.  I don't know why anyone would start 
> now, especially not because of hooks or aviz.  I just checked and PER-CS very 
> directly states "All keywords MUST be on a single line, and MUST be separated 
> by a single space."  So splitting it like shown above would be against 
> standard coding conventions anyway.
> 
> This is really a strawman argument.
> 
> --Larry Garfield
> 

I’m willing to concede that it might be a straw man, though I did not intend it 
as such. I was being serious in my pointing out of it increasing the minimum 
line length and PER isn’t the only coding standard. It may result in some ugly 
code, as in my example.

— Rob

Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-06-11 Thread Larry Garfield
On Tue, Jun 11, 2024, at 6:47 AM, Rob Landers wrote:

> 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

I have never in my life seen someone split the visibility to a separate line 
from the type and variable name in PHP.  I don't know why anyone would start 
now, especially not because of hooks or aviz.  I just checked and PER-CS very 
directly states "All keywords MUST be on a single line, and MUST be separated 
by a single space."  So splitting it like shown above would be against standard 
coding conventions anyway.

This is really a strawman argument.

--Larry Garfield


Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-06-11 Thread Lynn
On Tue, Jun 11, 2024 at 3:15 AM Lanre  wrote:

> Why invest time in crafting yet another pull request or RFC when it's
> glaringly obvious that you guys have no clue what you're doing? First,
> there's the questionable decision to implement JIT in 8.0, followed by the
> introduction of an entirely new library (IR) to a language that's
> predominantly request-based, boasting nothing more than a rudimentary AST,
> plagued with inconsistencies, clinging to CGI, and practically useless
> without a framework. And now, after greenlighting a dubious property hooks
> RFC, the same individuals are embroiled in a debate over Asymmetric
> Visibility? If you can't think up ways to make the engine "more rubust and
> sturdy" as a paid member of the foundation then maybe it is also time to
> start reconsidering my donations.
>
> On Mon, Jun 10, 2024 at 3:42 PM Derick Rethans  wrote:
>
>> On 10 June 2024 21:17:38 BST, Lanre  wrote:
>> >You guys are killing PHP. There is a lot of work to be done on the engine
>> >to modernize it and make it more robust and sturdy. Shit like this just
>> >adds more complexity to PHP in the name of convenience. I think this is
>> my
>> >cue to explore other languages for handling requests
>>
>>
>> Please moderate your language.
>>
>> Posts like this do nothing except a higher chance for people to ignore
>> you, when you've actual points to make, such as credible suggestions as to
>> how to make PHP "more rubust and sturdy".
>>
>> Looking forwards to your RFCs and patches.
>>
>> cheers
>> Derick
>>
>
Sometimes people grow in a different direction than a project and that's
okay, you should do what you feel is best for you. Even if that means you
will no longer be enriching us with your presence, I think the PHP project
will eventually recover from such great loss.


Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-06-11 Thread Rob Landers
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 

Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-06-10 Thread Lanre
Why invest time in crafting yet another pull request or RFC when it's
glaringly obvious that you guys have no clue what you're doing? First,
there's the questionable decision to implement JIT in 8.0, followed by the
introduction of an entirely new library (IR) to a language that's
predominantly request-based, boasting nothing more than a rudimentary AST,
plagued with inconsistencies, clinging to CGI, and practically useless
without a framework. And now, after greenlighting a dubious property hooks
RFC, the same individuals are embroiled in a debate over Asymmetric
Visibility? If you can't think up ways to make the engine "more rubust and
sturdy" as a paid member of the foundation then maybe it is also time to
start reconsidering my donations.

On Mon, Jun 10, 2024 at 3:42 PM Derick Rethans  wrote:

> On 10 June 2024 21:17:38 BST, Lanre  wrote:
> >You guys are killing PHP. There is a lot of work to be done on the engine
> >to modernize it and make it more robust and sturdy. Shit like this just
> >adds more complexity to PHP in the name of convenience. I think this is my
> >cue to explore other languages for handling requests
>
>
> Please moderate your language.
>
> Posts like this do nothing except a higher chance for people to ignore
> you, when you've actual points to make, such as credible suggestions as to
> how to make PHP "more rubust and sturdy".
>
> Looking forwards to your RFCs and patches.
>
> cheers
> Derick
>


Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-06-10 Thread Derick Rethans
On 10 June 2024 21:17:38 BST, Lanre  wrote:
>You guys are killing PHP. There is a lot of work to be done on the engine
>to modernize it and make it more robust and sturdy. Shit like this just
>adds more complexity to PHP in the name of convenience. I think this is my
>cue to explore other languages for handling requests


Please moderate your language.

Posts like this do nothing except a higher chance for people to ignore you, 
when you've actual points to make, such as credible suggestions as to how to 
make PHP "more rubust and sturdy".

Looking forwards to your RFCs and patches.

cheers
Derick


Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-06-10 Thread Lanre
You guys are killing PHP. There is a lot of work to be done on the engine
to modernize it and make it more robust and sturdy. Shit like this just
adds more complexity to PHP in the name of convenience. I think this is my
cue to explore other languages for handling requests

On Mon, Jun 10, 2024 at 1:18 PM 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, 

Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-06-10 Thread Rodrigo Vieira
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 

Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-06-10 Thread Tiffany
On Wed, May 29, 2024, 2:16 PM Larry Garfield  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.


Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-06-08 Thread Larry Garfield
On Sat, Jun 8, 2024, at 3:49 AM, Arvids Godjuks wrote:
> On Fri, 7 Jun 2024 at 17:30, Larry Garfield  wrote:
>> On Wed, Jun 5, 2024, at 7:55 PM, Arvids Godjuks wrote:
>> > On Wed, 5 Jun 2024 at 19:59, Claude Pache  wrote:
>> > *snip*
>> > Hello everyone,
>> > I've been seeing readonly bashed/blamed/being roadblock, etc, etc as in 
>> > the implementation ended up being sloppy and blocking other things or 
>> > making things hard... 
>> > While I know BC is king and stuff, why not just say "yes, this was 
>> > designed badly and we will redo it" and just do it? While there's not 
>> > yet an absolute boatload of that code out there when it would be 
>> > absolutely massive BC break? Don't repeat the mistakes of the old days 
>> > :D
>> 
>> Well, readonly has been out for 3 years.  There is an absolute boatload of 
>> code out there that we do not want to break. :-)
>> 
>> > Cause the impression I'm getting any significant RFC now has to work 
>> > around the readonly's sloppy implementation and there's a bigger and 
>> > bigger section on that with each next RFC when there's more and more 
>> > advanced features for the OOP part of things.
>> 
>> It's not a sloppy implementation per se.  (I can't actually speak to the 
>> implementation myself.)  It's the design of an implicit private(set) that 
>> works differently from any other private variable.  The issue with "thou 
>> shalt not touch it outside of the constructor" isn't a language bug, it's a 
>> static-analyzer bug that those projects refuse to fix.  Not something we can 
>> really do much about here.  Uninitialized wasn't introduced by readonly but 
>> by property types in 7.4; readonly just inherited it.  For hooks, the issue 
>> is that readonly needs a value to check to see if it's uninitialized, and 
>> with hooks, you don't always have that.
>> 
>> I think at this point, the change discussed above (making it implicit 
>> protected(set)) is the best we could do.  In an ideal world, we would have 
>> never added readonly in the first place and just added aviz back in 8.1, 
>> which would cover nearly all the same use cases with fewer edge cases and 
>> oddities.  Sadly, the world is not ideal.
>> 
>> --Larry Garfield
>
> It does depend on what the fix is - if we are talking removing readonly 
> keyword - that's a yikes and if we go that route, it needs to have an 
> official rector migration thing and it better be officially endorsed 
> and provided :)
> If we are talking about tweaking how readonly works in some cases - 
> while not great, I hold the opinion that it's better to fix it now than 
> 20 years down the line.
>
> I do have to say that I do not see a "==" between aviz and readonly. 
> While I can see how you can implement readonly with aviz, the 
> boilerplate seems not worth it, especially for bigger 
> classes/structures where you just designate the whole class with one 
> "readonly class MyClass { ... }". And constructor promotion with 
> "private readonly Class $class" with DI is basically all my services 
> now - it's convenient and short and I really do not need any more than 
> that from the readonly :) Maybe simplifying readonly is the answer and 
> use aviz for more complicated cases?

That is essentially what we've ended up on.  For *services*, aviz is probably 
not super useful; for that matter readonly is only marginally useful in 
services, but a lot of people (myself included) use it as a matter of course 
anyway.  The only change we're discussing there is that "public readonly" or 
"protected readonly" will now be implicitly "protected(set)" instead of 
implicitly "private(set)".  If you're already using "private readonly", then 
that will actually get a bit stricter as it removes the loophole that exists 
only for readonly.  So this is a very small, focused change.

Aviz is much more useful for data classes: value objects, DTOs, domain models, 
ORM models, and so on.  For that, readonly serves one narrow use case and does 
it well, but falls apart and often gets in the way for anything even slightly 
more complex/interesting.  For that, aviz offers vastly more flexibility and 
robustness in about the same amount of syntax.

--Larry Garfield


Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-06-08 Thread Arvids Godjuks
On Fri, 7 Jun 2024 at 17:30, Larry Garfield  wrote:

> On Wed, Jun 5, 2024, at 7:55 PM, Arvids Godjuks wrote:
> > On Wed, 5 Jun 2024 at 19:59, Claude Pache 
> wrote:
> > *snip*
> > Hello everyone,
> > I've been seeing readonly bashed/blamed/being roadblock, etc, etc as in
> > the implementation ended up being sloppy and blocking other things or
> > making things hard...
> > While I know BC is king and stuff, why not just say "yes, this was
> > designed badly and we will redo it" and just do it? While there's not
> > yet an absolute boatload of that code out there when it would be
> > absolutely massive BC break? Don't repeat the mistakes of the old days
> > :D
>
> Well, readonly has been out for 3 years.  There is an absolute boatload of
> code out there that we do not want to break. :-)
>
> > Cause the impression I'm getting any significant RFC now has to work
> > around the readonly's sloppy implementation and there's a bigger and
> > bigger section on that with each next RFC when there's more and more
> > advanced features for the OOP part of things.
>
> It's not a sloppy implementation per se.  (I can't actually speak to the
> implementation myself.)  It's the design of an implicit private(set) that
> works differently from any other private variable.  The issue with "thou
> shalt not touch it outside of the constructor" isn't a language bug, it's a
> static-analyzer bug that those projects refuse to fix.  Not something we
> can really do much about here.  Uninitialized wasn't introduced by readonly
> but by property types in 7.4; readonly just inherited it.  For hooks, the
> issue is that readonly needs a value to check to see if it's uninitialized,
> and with hooks, you don't always have that.
>
> I think at this point, the change discussed above (making it implicit
> protected(set)) is the best we could do.  In an ideal world, we would have
> never added readonly in the first place and just added aviz back in 8.1,
> which would cover nearly all the same use cases with fewer edge cases and
> oddities.  Sadly, the world is not ideal.
>
> --Larry Garfield
>

It does depend on what the fix is - if we are talking removing readonly
keyword - that's a yikes and if we go that route, it needs to have an
official rector migration thing and it better be officially endorsed and
provided :)
If we are talking about tweaking how readonly works in some cases - while
not great, I hold the opinion that it's better to fix it now than 20 years
down the line.

I do have to say that I do not see a "==" between aviz and readonly. While
I can see how you can implement readonly with aviz, the boilerplate seems
not worth it, especially for bigger classes/structures where you just
designate the whole class with one "readonly class MyClass { ... }". And
constructor promotion with "private readonly Class $class" with DI is
basically all my services now - it's convenient and short and I really do
not need any more than that from the readonly :) Maybe simplifying readonly
is the answer and use aviz for more complicated cases?
-- 

Arvīds Godjuks
+371 26 851 664
arvids.godj...@gmail.com
Telegram: @psihius https://t.me/psihius


Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-06-07 Thread Larry Garfield
On Wed, Jun 5, 2024, at 7:55 PM, Arvids Godjuks wrote:
> On Wed, 5 Jun 2024 at 19:59, Claude Pache  wrote:
>> *snip*
>> Hi Larry and Ilija,
>> 
>> Thanks for your work. Here is my opinion:
>> 
>> First, I do think that `readonly` should integrate with aviz, unless that 
>> implies truly controversial changes on `readonly`. As Theodore Brown 
>> commented in the previous version of the RFC: “Proposal feels unfinished 
>> since it can't be used in conjunction with readonly properties/classes. In 
>> my opinion the issues with this need to be resolved first, to avoid the 
>> language moving towards a messy hodgepodge of features that don't work well 
>> together.”
>> 
>> Second, I think that making `readonly` implicitly `protected(set)` by 
>> default (Option 2) is the way to go:
>> * At first glance it is an expectation change. But, in reality, all readonly 
>> properties can *already* be written to from a child class as of today: it 
>> suffices that the child class in question redeclare those properties: 
>> https://3v4l.org/9AV4r. From the point of view of the child class, the only 
>> thing that will change, is that it will no longer be required to explicitly 
>> opt into that possibility by redeclaring the readonly properties. From the 
>> point of view of the parent class, nothing will change, except false 
>> expectations—and it is a good thing that false expectations are eliminated.
>> * Relatively of Options 3 and 4, Option 2 leaves the language in a more 
>> simple and regular state.

That's a valid point, actually.  The implicit "private(set)" is already untrue 
because of readonly-specific workarounds to enable redeclaration.  Switching it 
to implicit "protected(set)" would remove that special case, and still allow an 
explicit private(set) if desired (which would then imply final).

Since no one else has weighed in, we'll go with that route: readonly on its own 
changes to implicit protected(set), remove any special casing, and then 
readonly and aviz should be safely compatible.  I'll update the RFC and Ilija 
will confirm that there's no implementation gotchas we're not aware of yet.

> Hello everyone,
> I've been seeing readonly bashed/blamed/being roadblock, etc, etc as in 
> the implementation ended up being sloppy and blocking other things or 
> making things hard... 
> While I know BC is king and stuff, why not just say "yes, this was 
> designed badly and we will redo it" and just do it? While there's not 
> yet an absolute boatload of that code out there when it would be 
> absolutely massive BC break? Don't repeat the mistakes of the old days 
> :D

Well, readonly has been out for 3 years.  There is an absolute boatload of code 
out there that we do not want to break. :-)

> Cause the impression I'm getting any significant RFC now has to work 
> around the readonly's sloppy implementation and there's a bigger and 
> bigger section on that with each next RFC when there's more and more 
> advanced features for the OOP part of things.

It's not a sloppy implementation per se.  (I can't actually speak to the 
implementation myself.)  It's the design of an implicit private(set) that works 
differently from any other private variable.  The issue with "thou shalt not 
touch it outside of the constructor" isn't a language bug, it's a 
static-analyzer bug that those projects refuse to fix.  Not something we can 
really do much about here.  Uninitialized wasn't introduced by readonly but by 
property types in 7.4; readonly just inherited it.  For hooks, the issue is 
that readonly needs a value to check to see if it's uninitialized, and with 
hooks, you don't always have that.

I think at this point, the change discussed above (making it implicit 
protected(set)) is the best we could do.  In an ideal world, we would have 
never added readonly in the first place and just added aviz back in 8.1, which 
would cover nearly all the same use cases with fewer edge cases and oddities.  
Sadly, the world is not ideal.

--Larry Garfield


Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-06-05 Thread Ilija Tovilo
Hi Tim

On Tue, Jun 4, 2024 at 7:54 PM Tim Düsterhus  wrote:
>
> One thing that would get pretty wonky would be private-read properties:
> Private property names are currently internally "mangled" to include the
> class name. This allows to define the same private property in multiple
> classes of an inheritance chain, without those classes needing to know
> about the private properties of each other and making the addition and
> removal of a private property not a BC break. For all intents and
> purposes those private properties to not exist, unless you are the class
> itself.
>
> I have no idea what the semantics of a public-write, private-read
> property should be - and this problem is pretty similar to the
> sibling-discussion about making private-set properties implicitly final,
> because otherwise the semantics get wonky.
>
> I believe that the case of making a property public-write, private-read
> is best left to a virtual set-only hook.

Indeed. A private property with a more permissible set operation is
the wrong approach. What we'd want here is a public property with a
restricted get operation. This is not quite expressible with the
current syntax. We'd need something like `public private(get)`, or
`public $prop { private get; }` with the C# equivalent. However, this
is quite an edge case, and since it requires additional syntax I don't
think it's something we should support without a specific use-case.
You can emulate it with a set-only virtual property, if you really
want to.

Ilija


Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-06-05 Thread Arvids Godjuks
On Wed, 5 Jun 2024 at 19:59, Claude Pache  wrote:

> *snip*
> Hi Larry and Ilija,
>
> Thanks for your work. Here is my opinion:
>
> First, I do think that `readonly` should integrate with aviz, unless that
> implies truly controversial changes on `readonly`. As Theodore Brown
> commented in the previous version of the RFC: “Proposal feels unfinished
> since it can't be used in conjunction with readonly properties/classes. In
> my opinion the issues with this need to be resolved first, to avoid the
> language moving towards a messy hodgepodge of features that don't work well
> together.”
>
> Second, I think that making `readonly` implicitly `protected(set)` by
> default (Option 2) is the way to go:
> * At first glance it is an expectation change. But, in reality, all
> readonly properties can *already* be written to from a child class as of
> today: it suffices that the child class in question redeclare those
> properties: https://3v4l.org/9AV4r. From the point of view of the child
> class, the only thing that will change, is that it will no longer be
> required to explicitly opt into that possibility by redeclaring the
> readonly properties. From the point of view of the parent class, nothing
> will change, except false expectations—and it is a good thing that false
> expectations are eliminated.
> * Relatively of Options 3 and 4, Option 2 leaves the language in a more
> simple and regular state.
>
> —Claude
>
>
>
Hello everyone,
I've been seeing readonly bashed/blamed/being roadblock, etc, etc as in the
implementation ended up being sloppy and blocking other things or making
things hard...
While I know BC is king and stuff, why not just say "yes, this was designed
badly and we will redo it" and just do it? While there's not yet an
absolute boatload of that code out there when it would be absolutely
massive BC break? Don't repeat the mistakes of the old days :D

Cause the impression I'm getting any significant RFC now has to work around
the readonly's sloppy implementation and there's a bigger and bigger
section on that with each next RFC when there's more and more advanced
features for the OOP part of things.

-- 

Arvīds Godjuks
+371 26 851 664
arvids.godj...@gmail.com
Telegram: @psihius https://t.me/psihius


Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-06-05 Thread Claude Pache


> Le 5 juin 2024 à 16:28, Larry Garfield  a écrit :
> 
> On Fri, May 31, 2024, at 8:59 PM, Larry Garfield wrote:
>> On Fri, May 31, 2024, at 5:45 PM, Claude Pache wrote:
 Le 31 mai 2024 à 18:08, Larry Garfield  a écrit :
 
 However, this also brings up another interesting issue: readonly 
 properties (in 8.3) DO allow redeclaration, essentially adjusting the 
 property scope (the class that declares it) to make the visibility check 
 pass. That is, the definition of the class it is private to changes, which 
 is different from how inheritance works elsewhere.  When the parent writes 
 to the same property, a special check is needed to verify the two 
 properties are related.  All that special casing effectively means that 
 readonly in 8.4 wouldn't really be "write once + private(set)", but "write 
 once + private(set) - final", which is... just kinda screwy.  That means 
 our options are:
 
 * A BC break on readonly (not allowing it to be overridden)
 * Make readonly an exception to the implicit final.
 * Just don't allow readonly with aviz after all.
>>> 
>>> Another possible option is:
>>> 
>>> * Make readonly be `protected(set)` by default.
>>> 
>>> That would weaken the originally intended semantics of readonly, but in 
>>> a compatible and acceptable way?
>>> 
>>> —Claude
>> 
>> Only sort of compatible.  It would allow readonly props to be 
>> redefined, and wouldn't break any existing code, I think... but it 
>> would mean any time you use readonly, suddenly a child class can come 
>> along and mess with it out from under you.
>> 
>> In practice that's likely not a common concern, but it is a behavior 
>> change.  I think it's possible (I need to confirm with Ilija), if we 
>> want that slight BC break, but I don't know if we do.
>> 
>> --Larry Garfield
> 
> Ilija and I have been discussing this issue over the last few days.  We agree 
> that `private(set)` should imply `final`, as that eliminates a bunch of 
> issues both implementation-wise and expectation-wise.  However, that causes 
> an issue for `readonly`.  
> 
> The root issue is that if we say "`readonly int $x` is really just 
> `private(set) readonly int $x`", that runs into the issue of "whelp, you've 
> just made readonly always final, which is a BC break."  So that's no good.
> 
> We see a couple of ways to resolve this, presented below in our order of 
> preference.
> 
> 1. Disallow readonly with aviz => No BC break, and we don't need to define 
> readonly in terms of private(set).  The only really useful combination anyway 
> would be `readonly protected(set)`, in which case the protected(set) is doing 
> 90% of the work already.  There's few cases where the readonly is truly 
> necessary at that point.  Any other oddball edge cases could be handled by a 
> custom hook.
> 2. Make `readonly` implicitly `protected(set)` unless you explicitly specify 
> `private(set)` => Would have the most consistent result, and this is probably 
> the cleanest in the engine, as `readonly private(set)` would mean exactly 
> what it says on the tin, with no inconsistency of "well it's kinda sorta 
> `private(set)`" as `readonly` has now.  However, this would be an expectation 
> change, as suddenly all readonly properties could be written to from a child 
> class.  That may be good in some cases but it's possible some objects could 
> have unexpected behavior if they didn't expect to be extended.  (No existing 
> code will break, but you could now do things to it in a child class that the 
> author didn't anticipate.)
> 3. You can't mix `readonly` with `private(set)`, but can use other 
> visibilities => No BC break, and we don't need to define readonly in terms of 
> `private(set)`.  However, it means the implicit `private(set)` of `readonly` 
> and an explicit private(set) behave differently (one is final, one is not).  
> It also unclear if a `readonly` property can be overridden with `readonly 
> protected(set)` only, or also `readonly private(set)`.  If the latter, does 
> it become implicitly `final` at that point?
> 4. `readonly` behaves differently for an explicit (final) and implicit 
> (not-final) `private(set)` => No BC break, but it's kinda weird and 
> non-obvious to explain.  It also has the same non-obvious inheritance 
> questions as option 3.
> 
> We consider only the first two to be really viable.  For simplicity, we'd 
> favor doing option 1, and if desired option 2 could be presented in the 
> future as its own RFC as that is technically a behavior change, not just 
> addition, so deserves careful consideration.  However, if there is a clear 
> consensus to go with option 2 now, we're open to that.
> 
> --Larry Garfield

Hi Larry and Ilija,

Thanks for your work. Here is my opinion:

First, I do think that `readonly` should integrate with aviz, unless that 
implies truly controversial changes on `readonly`. As Theodore Brown commented 
in the previous version of the 

Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-06-05 Thread Larry Garfield
On Fri, May 31, 2024, at 8:59 PM, Larry Garfield wrote:
> On Fri, May 31, 2024, at 5:45 PM, Claude Pache wrote:
>>> Le 31 mai 2024 à 18:08, Larry Garfield  a écrit :
>>> 
>>> However, this also brings up another interesting issue: readonly properties 
>>> (in 8.3) DO allow redeclaration, essentially adjusting the property scope 
>>> (the class that declares it) to make the visibility check pass. That is, 
>>> the definition of the class it is private to changes, which is different 
>>> from how inheritance works elsewhere.  When the parent writes to the same 
>>> property, a special check is needed to verify the two properties are 
>>> related.  All that special casing effectively means that readonly in 8.4 
>>> wouldn't really be "write once + private(set)", but "write once + 
>>> private(set) - final", which is... just kinda screwy.  That means our 
>>> options are:
>>> 
>>> * A BC break on readonly (not allowing it to be overridden)
>>> * Make readonly an exception to the implicit final.
>>> * Just don't allow readonly with aviz after all.
>>
>> Another possible option is:
>>
>> * Make readonly be `protected(set)` by default.
>>
>> That would weaken the originally intended semantics of readonly, but in 
>> a compatible and acceptable way?
>>
>> —Claude
>
> Only sort of compatible.  It would allow readonly props to be 
> redefined, and wouldn't break any existing code, I think... but it 
> would mean any time you use readonly, suddenly a child class can come 
> along and mess with it out from under you.
>
> In practice that's likely not a common concern, but it is a behavior 
> change.  I think it's possible (I need to confirm with Ilija), if we 
> want that slight BC break, but I don't know if we do.
>
> --Larry Garfield

Ilija and I have been discussing this issue over the last few days.  We agree 
that `private(set)` should imply `final`, as that eliminates a bunch of issues 
both implementation-wise and expectation-wise.  However, that causes an issue 
for `readonly`.  

The root issue is that if we say "`readonly int $x` is really just 
`private(set) readonly int $x`", that runs into the issue of "whelp, you've 
just made readonly always final, which is a BC break."  So that's no good.

We see a couple of ways to resolve this, presented below in our order of 
preference.

1. Disallow readonly with aviz => No BC break, and we don't need to define 
readonly in terms of private(set).  The only really useful combination anyway 
would be `readonly protected(set)`, in which case the protected(set) is doing 
90% of the work already.  There's few cases where the readonly is truly 
necessary at that point.  Any other oddball edge cases could be handled by a 
custom hook.
2. Make `readonly` implicitly `protected(set)` unless you explicitly specify 
`private(set)` => Would have the most consistent result, and this is probably 
the cleanest in the engine, as `readonly private(set)` would mean exactly what 
it says on the tin, with no inconsistency of "well it's kinda sorta 
`private(set)`" as `readonly` has now.  However, this would be an expectation 
change, as suddenly all readonly properties could be written to from a child 
class.  That may be good in some cases but it's possible some objects could 
have unexpected behavior if they didn't expect to be extended.  (No existing 
code will break, but you could now do things to it in a child class that the 
author didn't anticipate.)
3. You can't mix `readonly` with `private(set)`, but can use other visibilities 
=> No BC break, and we don't need to define readonly in terms of 
`private(set)`.  However, it means the implicit `private(set)` of `readonly` 
and an explicit private(set) behave differently (one is final, one is not).  It 
also unclear if a `readonly` property can be overridden with `readonly 
protected(set)` only, or also `readonly private(set)`.  If the latter, does it 
become implicitly `final` at that point?
4. `readonly` behaves differently for an explicit (final) and implicit 
(not-final) `private(set)` => No BC break, but it's kinda weird and non-obvious 
to explain.  It also has the same non-obvious inheritance questions as option 3.

We consider only the first two to be really viable.  For simplicity, we'd favor 
doing option 1, and if desired option 2 could be presented in the future as its 
own RFC as that is technically a behavior change, not just addition, so 
deserves careful consideration.  However, if there is a clear consensus to go 
with option 2 now, we're open to that.

--Larry Garfield


Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-06-04 Thread Tim Düsterhus

Hi

On 6/4/24 15:30, Larry Garfield wrote:

If enough people felt strongly that it should be allowed, I don't think there's 
any technical reason it couldn't be allowed, other than it would allow some 
rather silly combinations.  (Ilija can tell me if I'm wrong.)  However, also 
note that it is, of course, much easier to allow more combinations in the 
future than to remove them, should we find they cause trouble.


One thing that would get pretty wonky would be private-read properties: 
Private property names are currently internally "mangled" to include the 
class name. This allows to define the same private property in multiple 
classes of an inheritance chain, without those classes needing to know 
about the private properties of each other and making the addition and 
removal of a private property not a BC break. For all intents and 
purposes those private properties to not exist, unless you are the class 
itself.


I have no idea what the semantics of a public-write, private-read 
property should be - and this problem is pretty similar to the 
sibling-discussion about making private-set properties implicitly final, 
because otherwise the semantics get wonky.


I believe that the case of making a property public-write, private-read 
is best left to a virtual set-only hook.


Best regards
Tim Düsterhus


Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-06-04 Thread Larry Garfield
On Tue, Jun 4, 2024, at 5:01 AM, Andreas Heigl wrote:

> There is only one thing that I stumbled upon which struck me as odd:
>
>  > The set visibility, if specified explicitly, MUST be equal to or
>  > lesser than the main (get) visibility. That is, protected public(set)
>  > string $foo is not allowed.
>
> Why?
>
> Why can we not set a property as publicly writable but unreadable?
>
> If that is a technical necessity, then so be it. But if that is a 
> logical limitation, then I'm asking myself: why do we want to explicitly 
> limit possible usecases? Not that I have one right now in my mind but I 
> do know that we used similar settings in Filesystems for letterbox 
> systems where users could copy files into other users letterbox (write 
> only) without being able to later see the files.
>
> Similar possibilities are available here here a property could be 
> publicly writeable but only privately readable as read-access is only 
> granted via a method.
>
> I'm not saying it's the usualy use-case, but why explicitly disallowing it?

It's not a technical requirement.  Mainly, we just cannot think of a reason why 
you'd ever do that, so making some seemingly nonsensical cases illegal seems 
like a good guardrail.

If enough people felt strongly that it should be allowed, I don't think there's 
any technical reason it couldn't be allowed, other than it would allow some 
rather silly combinations.  (Ilija can tell me if I'm wrong.)  However, also 
note that it is, of course, much easier to allow more combinations in the 
future than to remove them, should we find they cause trouble.

--Larry Garfield


Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-06-03 Thread Andreas Heigl

Hey Larry, hey Ilija


Am 29.05.24 um 21:15 schrieb Larry Garfield:

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*


In general I do like the RFC. No need for a flame retardand suit IMO ;-)

There is only one thing that I stumbled upon which struck me as odd:

> The set visibility, if specified explicitly, MUST be equal to or
> lesser than the main (get) visibility. That is, protected public(set)
> string $foo is not allowed.

Why?

Why can we not set a property as publicly writable but unreadable?

If that is a technical necessity, then so be it. But if that is a 
logical limitation, then I'm asking myself: why do we want to explicitly 
limit possible usecases? Not that I have one right now in my mind but I 
do know that we used similar settings in Filesystems for letterbox 
systems where users could copy files into other users letterbox (write 
only) without being able to later see the files.


Similar possibilities are available here here a property could be 
publicly writeable but only privately readable as read-access is only 
granted via a method.


I'm not saying it's the usualy use-case, but why explicitly disallowing it?

Cheers

Andreas

--
  ,,,
 (o o)
+-ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org   |
+-+
| https://hei.gl/appointmentwithandreas   |
+-+
| GPG-Key: https://hei.gl/keyandreasheiglorg  |
+-+


OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-06-03 Thread Alexandru Pătrănescu
On Fri, May 31, 2024 at 7:13 PM Larry Garfield 
wrote:

>
> So we feel the best way forward is to make the following changes:
>
> * private(set) implicitly means "final".  (You can declare it explicitly
> if you want, but it isn't necessary.)
> * Make readonly incompatible with aviz again.
>
> Thoughts?
>

I think making properties `final` when using `private(set)` is a good
solution to this.

I don't think `readonly` needs to be incompatible with aviz. We can have
`readonly` act as `private(set`) but not `final` by default.
But you can define it as `private(set) readonly`, and in this case it will
be `final`, practically the same as `final readonly`.
It would go like this:
- private(set) -> final, private(set)
- final private(set) -> final, private(set)
- readonly -> write-once, private(set)
- final readonly -> final, write-once, private(set)
- private(set) readonly -> final, write-once, private(set)
- protected(set) readonly -> write-once, protected(set)
- public(set) readonly -> write-once, public(set)


>
> Also, Alexandru noted earlier that final properties don't seem to be
> supported in constructor promotion.  That's an oversight from the hooks
> implementation, not a design choice, so Ilija will just fix that as part of
> the hooks PR before it gets fully merged.
>

Maybe we need to have some discussion/considerations about allowing new
modifiers on constructor promoted properties parameters.
Right now there is no `final` modifier for parameters, but this means we
might not be able to allow them in the future.
In other languages (Java), it makes the parameter variable a constant (not
reassignable).

So this decision might have implications so that when we decide to make
variables or parameters not reassignable, we will not be able to use
"final" as a keyword.
Not saying there is a problem, just that we need to be aware of it, as
probably `final` is not a very good choice, and `const` or `readonly` are
probably better options.

Alex


Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-05-31 Thread Erick de Azevedo Lima
> So we feel the best way forward is to make the following changes:
>
> * private(set) implicitly means "final".  (You can declare it explicitly
if you want, but it isn't necessary.)
> * Make readonly incompatible with aviz again.

I'd make readonly incompatible with aviz. Readonly props have its
"peculiarities" that are being (found and) changed on each version.
If you don't want to change your value ever, use readonly.
If you want more flexibility, use aviz.

Making workarounds on the aviz RFC so it can be compatible with readonly is
not worth it, IMO.

Best regards,
Erick

Em sex., 31 de mai. de 2024 às 20:53, Claude Pache 
escreveu:

>
>
> Le 31 mai 2024 à 18:08, Larry Garfield  a écrit :
>
> So we feel the best way forward is to make the following changes:
>
> * private(set) implicitly means "final".  (You can declare it explicitly
> if you want, but it isn't necessary.)
> * Make readonly incompatible with aviz again.
>
> Thoughts?
>
>
>
> After reflection, I don’t think that we need to make readonly incompatible
> with aviz, even with the current semantics of readonly (at least logically;
> no idea about implementationally):
>
> * legacy-readonly properties could keep their own peculiar
> `private-overridable(set)` if they want;
> * aviz-readonly properties have, by definition, one of `public(set)`,
> `protected(set)` or `private(set)` marker; those will work regularly,
> including the implicit `final` attached to `private(set)`;
> * a non-aviz readonly property could not be redeclared in a subclass as
> aviz-readonly, and vice versa.
>
> —Claude
>


Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-05-31 Thread Claude Pache


> Le 31 mai 2024 à 18:08, Larry Garfield  a écrit :
> 
> So we feel the best way forward is to make the following changes:
> 
> * private(set) implicitly means "final".  (You can declare it explicitly if 
> you want, but it isn't necessary.)
> * Make readonly incompatible with aviz again.
> 
> Thoughts?


After reflection, I don’t think that we need to make readonly incompatible with 
aviz, even with the current semantics of readonly (at least logically; no idea 
about implementationally):

* legacy-readonly properties could keep their own peculiar 
`private-overridable(set)` if they want;
* aviz-readonly properties have, by definition, one of `public(set)`, 
`protected(set)` or `private(set)` marker; those will work regularly, including 
the implicit `final` attached to `private(set)`;
* a non-aviz readonly property could not be redeclared in a subclass as 
aviz-readonly, and vice versa.

—Claude

Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-05-31 Thread Robert Landers
On Fri, May 31, 2024 at 9:13 PM Claude Pache  wrote:
>
>
>
> Le 31 mai 2024 à 18:08, Larry Garfield  a écrit :
>
> However, this also brings up another interesting issue: readonly properties 
> (in 8.3) DO allow redeclaration, essentially adjusting the property scope 
> (the class that declares it) to make the visibility check pass. That is, the 
> definition of the class it is private to changes, which is different from how 
> inheritance works elsewhere.  When the parent writes to the same property, a 
> special check is needed to verify the two properties are related.  All that 
> special casing effectively means that readonly in 8.4 wouldn't really be 
> "write once + private(set)", but "write once + private(set) - final", which 
> is... just kinda screwy.  That means our options are:
>
> * A BC break on readonly (not allowing it to be overridden)
> * Make readonly an exception to the implicit final.
> * Just don't allow readonly with aviz after all.
>
>
> Another possible option is:
>
> * Make readonly be `protected(set)` by default.
>
> That would weaken the originally intended semantics of readonly, but in a 
> compatible and acceptable way?
>
> —Claude
>
>

I know this doesn't really contribute to the conversation ... but if I
could ever mash a +1 on a single email, this is the email I'd choose.

"Best elegant solution that happens to delete readonly without
deleting readonly" award.

Robert Landers
Software Engineer
Utrecht NL


Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-05-31 Thread Larry Garfield
On Fri, May 31, 2024, at 5:45 PM, Claude Pache wrote:
>> Le 31 mai 2024 à 18:08, Larry Garfield  a écrit :
>> 
>> However, this also brings up another interesting issue: readonly properties 
>> (in 8.3) DO allow redeclaration, essentially adjusting the property scope 
>> (the class that declares it) to make the visibility check pass. That is, the 
>> definition of the class it is private to changes, which is different from 
>> how inheritance works elsewhere.  When the parent writes to the same 
>> property, a special check is needed to verify the two properties are 
>> related.  All that special casing effectively means that readonly in 8.4 
>> wouldn't really be "write once + private(set)", but "write once + 
>> private(set) - final", which is... just kinda screwy.  That means our 
>> options are:
>> 
>> * A BC break on readonly (not allowing it to be overridden)
>> * Make readonly an exception to the implicit final.
>> * Just don't allow readonly with aviz after all.
>
> Another possible option is:
>
> * Make readonly be `protected(set)` by default.
>
> That would weaken the originally intended semantics of readonly, but in 
> a compatible and acceptable way?
>
> —Claude

Only sort of compatible.  It would allow readonly props to be redefined, and 
wouldn't break any existing code, I think... but it would mean any time you use 
readonly, suddenly a child class can come along and mess with it out from under 
you.

In practice that's likely not a common concern, but it is a behavior change.  I 
think it's possible (I need to confirm with Ilija), if we want that slight BC 
break, but I don't know if we do.

--Larry Garfield


Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-05-31 Thread Claude Pache


> Le 31 mai 2024 à 18:08, Larry Garfield  a écrit :
> 
> However, this also brings up another interesting issue: readonly properties 
> (in 8.3) DO allow redeclaration, essentially adjusting the property scope 
> (the class that declares it) to make the visibility check pass. That is, the 
> definition of the class it is private to changes, which is different from how 
> inheritance works elsewhere.  When the parent writes to the same property, a 
> special check is needed to verify the two properties are related.  All that 
> special casing effectively means that readonly in 8.4 wouldn't really be 
> "write once + private(set)", but "write once + private(set) - final", which 
> is... just kinda screwy.  That means our options are:
> 
> * A BC break on readonly (not allowing it to be overridden)
> * Make readonly an exception to the implicit final.
> * Just don't allow readonly with aviz after all.

Another possible option is:

* Make readonly be `protected(set)` by default.

That would weaken the originally intended semantics of readonly, but in a 
compatible and acceptable way?

—Claude




Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-05-31 Thread Larry Garfield
On Fri, May 31, 2024, at 12:04 PM, Alexandru Pătrănescu wrote:
> On Fri, May 31, 2024 at 10:30 AM Claude Pache  wrote:
>> 
>> 
>>> Le 30 mai 2024 à 17:07, Derick Rethans  a écrit :
>>> 
 
 Now, if I define the property as public private(set) with similar 
 intentions, to make sure that there is no way for external scope or 
 extending classes scope to write to the property, while allowing 
 reading from external scope (or extending classes scope).
 
 But the problem is that an extending class can define the property as 
 public protected(set), and that will easily allow the property that I 
 wanted to make sure it is private for writing to be changed by an 
 extending class to be protected.
>>> 
>>> public private(set) properties aren't really private, so you don't get 
>>> the shadowing, but you do have a point wrt to the expectation that an 
>>> inherited class can't easily override the private(set) part (with 
>>> protected(set) or public(set)).
>> 
>> 
>> Note that the issue already exists today with readonly properties: those are 
>> basically private(set); but if you redeclare a non-private readonly property 
>> in a subclass, you can in fact initialise it from the subclass bypassing the 
>> initial private(set) restriction of the superclass: https://3v4l.org/9AV4r
>
> Yes, thank you; that's a good point.
> Seems like another issue with readonly, but then again, the 
> private(set) part of readonly is not really explicitly designed, I 
> guess.
> 
>> 
>> If you want a property not to be overridable, end of story, you can mark it 
>> as `final` (the final marker for properties was added as part of the hooks 
>> RFC, but it works also with non-hooked properties).
>
> Yes, it seems like a good enough option, and use "final public 
> private(set)" to ensure only the current class will be able to set the 
> value.
> If we all agree, I think this should be documented in the RFC.
>
> There is another small problem, I think, with "final" modifier not 
> being allowed for constructor-promoted properties.
> And maybe we can have this fixed in the current RFC if this ends up 
> being "the correct" way to define public-read private-write properties.
>
> Regards,
> Alex

Mm, yeah, this is an interesting corner case we'd not thought of.  We spent a 
little time looking at how other languages handle this.

Kotlin just disallows using private-set on a non-final property.  (Kotlin 
properties are final by default, unless otherwise specified.)  cf: 
https://kotlinlang.org/spec/inheritance.html#overriding

C# disallows changing property visibility in child classes entirely.  cf: 
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/restricting-accessor-accessibility#access-modifiers-on-overriding-accessors

Swift is... weird.  If you have a public private(set) property, you can 
override it by turning it into a virtual property with only a get hook.  If you 
also define a set hook, though, it just never gets called.  It doesn't appear 
that you can widen the set visibility, I think.

So since we now have final properties (yay, hooks RFC!), we could probably 
mostly solve this by just only allowing private(set) on a final property, like 
Kotlin.  That's probably the easiest approach.  We can also make private(set) 
properties implicitly final to avoid lots of boilerplate.  (Having to always 
type final with private(set) every time is kinda silly.)

It would mean that proxy objects implemented using child classes with hooks 
would only work with a public protected(set) class, not with a private(set), 
but that's probably fine, and since no one is doing that quite yet, obviously, 
there's no existing code to be concerned about.

However, this also brings up another interesting issue: readonly properties (in 
8.3) DO allow redeclaration, essentially adjusting the property scope (the 
class that declares it) to make the visibility check pass. That is, the 
definition of the class it is private to changes, which is different from how 
inheritance works elsewhere.  When the parent writes to the same property, a 
special check is needed to verify the two properties are related.  All that 
special casing effectively means that readonly in 8.4 wouldn't really be "write 
once + private(set)", but "write once + private(set) - final", which is... just 
kinda screwy.  That means our options are:

* A BC break on readonly (not allowing it to be overridden)
* Make readonly an exception to the implicit final.
* Just don't allow readonly with aviz after all.

After some consideration, we believe the third option is best (least bad).  The 
other options add still-more special cases or break existing code, neither of 
which are good.  If a property is declared private(set), then child classes 
simply should not be allowed to change that, period.  Even adding a get hook in 
a child is potentially a problem, as it would change the "round trip" behavior 
in ways the 

Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-05-31 Thread Claude Pache


> Le 30 mai 2024 à 12:16, Vincent de Lau  a écrit :
> 
>> 
>> We went through a bunch of syntax variations last year, including "public
>> private", "public:private", and "public private:set", plus a few others.
>> In an RCV poll, public private(set) was the favorite. (See link at the end
>> of the RFC.)  It also allows for extension to other operations and scopes,
>> and for the short-hand syntax.  Many of the other options did not support
>> those.  Thus we stuck with the known syntax that had the most flexibility
>> and most support.
> 
> Would it make sense to do another RCV poll now that hooks are accepted, after 
> lengthy discussion over its syntax? 
> 

At the time the poll was conducted, it was already known that a hooks RFC was 
in preparation, that could be compatible with either option, syntax-wise. Now, 
we have hooks that are compatible with both options, syntax-wise. I don’t think 
that would change the aesthetic preferences of people.

But now, we have indeed more information, namely detailed technical information 
on how the two features (hooks and aviz) interact effectively with 
references/arrays/readonly. At the time the poll was conducted, I was 
*moderately* in favour of the Swift-style syntax, mostly based on the general 
principle that things that are logically orthogonal should be implemented as 
orthogonal. If the same poll is done today, I will be *strongly* in favour of 
the Swift-style syntax, because I know more precisely how both features 
interact with arrays and readonly.

—Claude



Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-05-31 Thread Alexandru Pătrănescu
On Fri, May 31, 2024 at 10:30 AM Claude Pache 
wrote:

>
>
> Le 30 mai 2024 à 17:07, Derick Rethans  a écrit :
>
>
> Now, if I define the property as public private(set) with similar
> intentions, to make sure that there is no way for external scope or
> extending classes scope to write to the property, while allowing
> reading from external scope (or extending classes scope).
>
> But the problem is that an extending class can define the property as
> public protected(set), and that will easily allow the property that I
> wanted to make sure it is private for writing to be changed by an
> extending class to be protected.
>
>
> public private(set) properties aren't really private, so you don't get
> the shadowing, but you do have a point wrt to the expectation that an
> inherited class can't easily override the private(set) part (with
> protected(set) or public(set)).
>
>
>
> Note that the issue already exists today with readonly properties: those
> are basically private(set); but if you redeclare a non-private readonly
> property in a subclass, you can in fact initialise it from the subclass
> bypassing the initial private(set) restriction of the superclass:
> https://3v4l.org/9AV4r
>

Yes, thank you; that's a good point.
Seems like another issue with readonly, but then again, the private(set)
part of readonly is not really explicitly designed, I guess.


>
> If you want a property not to be overridable, end of story, you can mark
> it as `final` (the final marker for properties was added as part of the
> hooks RFC, but it works also with non-hooked properties).
>

Yes, it seems like a good enough option, and use "final public
private(set)" to ensure only the current class will be able to set the
value.
If we all agree, I think this should be documented in the RFC.

There is another small problem, I think, with "final" modifier not being
allowed for constructor-promoted properties.
And maybe we can have this fixed in the current RFC if this ends up
being "the correct" way to define public-read private-write properties.

Regards,
Alex


Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-05-31 Thread Claude Pache


> Le 30 mai 2024 à 17:07, Derick Rethans  a écrit :
> 
>> 
>> Now, if I define the property as public private(set) with similar 
>> intentions, to make sure that there is no way for external scope or 
>> extending classes scope to write to the property, while allowing 
>> reading from external scope (or extending classes scope).
>> 
>> But the problem is that an extending class can define the property as 
>> public protected(set), and that will easily allow the property that I 
>> wanted to make sure it is private for writing to be changed by an 
>> extending class to be protected.
> 
> public private(set) properties aren't really private, so you don't get 
> the shadowing, but you do have a point wrt to the expectation that an 
> inherited class can't easily override the private(set) part (with 
> protected(set) or public(set)).



Note that the issue already exists today with readonly properties: those are 
basically private(set); but if you redeclare a non-private readonly property in 
a subclass, you can in fact initialise it from the subclass bypassing the 
initial private(set) restriction of the superclass: https://3v4l.org/9AV4r

If you want a property not to be overridable, end of story, you can mark it as 
`final` (the final marker for properties was added as part of the hooks RFC, 
but it works also with non-hooked properties).

—Claude

Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-05-30 Thread Derick Rethans
On Thu, 30 May 2024, Alexandru Pătrănescu wrote:

> On Wed, May 29, 2024 at 10:18 PM Larry Garfield 
> wrote:
> 
> > As promised, Ilija and I offer this revised version of asymmetric
> > visibility.
> >
> > https://wiki.php.net/rfc/asymmetric-visibility-v2
> >
> >
> Hey Larry, Ilija,
> 
> I have one concern so far, and it's related to the inheritance section.
> 
> If in a class I define the property as private,
> I know that there is no way for external scope or extending classes scope
> to read or write to the property.
> (of course, ignoring reading/writing using reflection or re-binded closures)
> 
> If an extending class defines the property with a wider visibility,
> protected or public, it will shadow the initial one and not change its
> visibility.

private and protected differ here already, even without async 
visibility:

https://3v4l.org/8Ynog

A protected property does not create a new bag to store data in, which 
does happen for a private property.

> Now, if I define the property as public private(set) with similar 
> intentions, to make sure that there is no way for external scope or 
> extending classes scope to write to the property, while allowing 
> reading from external scope (or extending classes scope).
> 
> But the problem is that an extending class can define the property as 
> public protected(set), and that will easily allow the property that I 
> wanted to make sure it is private for writing to be changed by an 
> extending class to be protected.

public private(set) properties aren't really private, so you don't get 
the shadowing, but you do have a point wrt to the expectation that an 
inherited class can't easily override the private(set) part (with 
protected(set) or public(set)).

Hopefully Ilija or Larry can explain :-)

cheers,
Derick

RE: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-05-30 Thread Vincent de Lau
> -Original Message-
> From: Larry Garfield 
> Sent: Wednesday, May 29, 2024 10:03 PM
> 
> On Wed, May 29, 2024, at 7:53 PM, Andreas Hennings wrote:
> > Hello Larry,
> > just a quick thought.
> > Is there a reason why we cannot just make it "public private string
> > $x" instead of "public private(set) string $x"?
> > We would define that the second visibility specifier is for write.
> >
> > The current proposal with "public private(set)" is less ambiguous, and
> > it is immediately obvious that this is something new, and not just
> > somebody accidentally added two modifiers.
> > At the same time, it feels a bit alien and cluttered.
> >
> > Other options could be something like "public:private" or "public-
> private".
> >
> > A consequence of such options would be that you always need to specify
> > the read visibility along with the write visibility.
> > But this seems ok to me.
> >
> > This is not a final opinion, just a thought.

> We went through a bunch of syntax variations last year, including "public
> private", "public:private", and "public private:set", plus a few others.
> In an RCV poll, public private(set) was the favorite. (See link at the end
> of the RFC.)  It also allows for extension to other operations and scopes,
> and for the short-hand syntax.  Many of the other options did not support
> those.  Thus we stuck with the known syntax that had the most flexibility
> and most support.

Would it make sense to do another RCV poll now that hooks are accepted, after 
lengthy discussion over its syntax? 

Personally, I would prefer the HookEmbeddedStyle form. I don't think the 
argument that the visibility would potentially be separated from the hook 
definition is very strong, as you would have to scan for the existence of the 
hook anyway. For me, asymmetric visibility and property hooks are mentally more 
related than the RFC technically defines them to be.

Furthermore, I see a lot of reasoning in favour of the prefix syntax in 
relation to limitations of other language constructs like property promotion. 
While I don't think it is fair to expect this RFC should fix those, to me it 
feels we are compounding 'errors'.

Thanks to both you and Ilija for all the hard work on these RFC's, it is much 
appreciated!

--
Vincent de Lau


Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-05-30 Thread Alexandru Pătrănescu
On Wed, May 29, 2024 at 10:18 PM Larry Garfield 
wrote:

> As promised, Ilija and I offer this revised version of asymmetric
> visibility.
>
> https://wiki.php.net/rfc/asymmetric-visibility-v2
>
>
Hey Larry, Ilija,

I have one concern so far, and it's related to the inheritance section.

If in a class I define the property as private,
I know that there is no way for external scope or extending classes scope
to read or write to the property.
(of course, ignoring reading/writing using reflection or re-binded closures)

If an extending class defines the property with a wider visibility,
protected or public, it will shadow the initial one and not change its
visibility.

Now, if I define the property as public private(set) (or protected
private(set)) with similar intentions,
to make sure that there is no way for external scope or extending classes
scope to write to the property,
while allowing reading from external scope (or extending classes scope).

But the problem is that an extending class can define the property as
public protected(set) (or protected protected(set)),
and that will easily allow the property that I wanted to make sure it is
private for writing to be changed by an extending class to be protected.


The main suggestion I can think of, is to now allow widening the write
visibility when it is private.

I mean, in general, to make sure it is not possible for other extending
classes to access private parent class properties/methods we can use two
mechanisms:
- disallowing to change the visibility and making it an error
- shadowing the parent property/method
While shadowing works for symmetric visibility, it doesn't really work for
asymmetric visibility, so disallowing seems to be a good option here.

Also, maybe marking the properties as final could play a role here,
not allowing private visibility for write on properties to be widened or
completely not allowing it to change/redefined.


Regards,
Alex


Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-05-29 Thread Larry Garfield
On Wed, May 29, 2024, at 7:51 PM, Tim Düsterhus wrote:
> Hi
>
> On 5/29/24 21:15, Larry Garfield wrote:
>> * We've brought back the abbreviated form, as public-read, something else 
>> set is the most common use case.
>
> The most common use case is that 'get' and 'set' are symmetric. 

OK, fair, I meant in the most common case where you're using aviz at all, get 
is probably public.

That said, with both hooks and aviz, I can see data objects, for instance, 
becoming commonly public-get, private-set.  It's already common to have them be 
public readonly, so this is just an extension of that.

> Any 
> divergence from that should stand out and I think that the hamming 
> distance between
>
>  protected string $foo;
>
> and
>
>  protected(set) string $foo;
>
> is too small.

I can only respectfully disagree here.  I think it's reasonably self-evident, 
made moreso by the (), which as Andreas noted looks weird when you're not used 
to it (but we should get used to fairly quickly).  And the benefit of not 
having to type "public" on every property outweighs any initial confusion, much 
the same as readonly classes just reduces boilerplate.

> One note regarding the text. You already confirmed to me in private that:
>
>  class Foo {
>  private $dontTouchMe;
>  }
>
>  $backdoor = function ($key, $value) { $this->{$key} = $value; };
>
>  $f = new Foo();
>  $backdoor->call($f, 'dontTouchMe', 'butIDid');
>  var_dump($f);
>
> would work as expected with aviz. It would make sense to explicitly 
> spell that out, just like it's explicitly spelled out that 
> `ReflectionProperty::setValue()` works.

Added a note to that effect in the Reflection section as well.  Thanks.

--Larry Garfield


Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-05-29 Thread Tim Düsterhus

Hi

On 5/29/24 21:53, Andreas Hennings wrote:

Is there a reason why we cannot just make it "public private string
$x" instead of "public private(set) string $x"?
We would define that the second visibility specifier is for write.

The current proposal with "public private(set)" is less ambiguous, and
it is immediately obvious that this is something new, and not just
somebody accidentally added two modifiers.
At the same time, it feels a bit alien and cluttered.

Other options could be something like "public:private" or "public-private".


The variant with the parentheses is the most future-proof one, should 
additional operations be added. It would allow for:


public private(set,unset,frobnicate) string $foo;

Even if tools would not yet understand whatever 'frobnicate' does, they 
would know that this is an operation that may be performed on $foo and 
would be able to syntax highlight the visibility definition properly and 
they would also know how to autoformat it, without needing to add 
support for the new keyword.


Best regards
Tim Düsterhus


Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-05-29 Thread Larry Garfield
On Wed, May 29, 2024, at 7:53 PM, Andreas Hennings wrote:
> Hello Larry,
> just a quick thought.
> Is there a reason why we cannot just make it "public private string
> $x" instead of "public private(set) string $x"?
> We would define that the second visibility specifier is for write.
>
> The current proposal with "public private(set)" is less ambiguous, and
> it is immediately obvious that this is something new, and not just
> somebody accidentally added two modifiers.
> At the same time, it feels a bit alien and cluttered.
>
> Other options could be something like "public:private" or "public-private".
>
> A consequence of such options would be that you always need to specify
> the read visibility along with the write visibility.
> But this seems ok to me.
>
> This is not a final opinion, just a thought.
>
> -- Andreas

We went through a bunch of syntax variations last year, including "public 
private", "public:private", and "public private:set", plus a few others.  In an 
RCV poll, public private(set) was the favorite. (See link at the end of the 
RFC.)  It also allows for extension to other operations and scopes, and for the 
short-hand syntax.  Many of the other options did not support those.  Thus we 
stuck with the known syntax that had the most flexibility and most support.

By other operations, I mean, suppose we allow varying the visibility for 
obtaining a reference separate from a set (for some reason).  It's obvious how 
that would look with the current syntax: public protected(ref) private(set).  
With "public private" or "public:private", it's really not clear how we'd even 
do that.

--Larry Garfield


Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-05-29 Thread Andreas Hennings
Hello Larry,
just a quick thought.
Is there a reason why we cannot just make it "public private string
$x" instead of "public private(set) string $x"?
We would define that the second visibility specifier is for write.

The current proposal with "public private(set)" is less ambiguous, and
it is immediately obvious that this is something new, and not just
somebody accidentally added two modifiers.
At the same time, it feels a bit alien and cluttered.

Other options could be something like "public:private" or "public-private".

A consequence of such options would be that you always need to specify
the read visibility along with the write visibility.
But this seems ok to me.

This is not a final opinion, just a thought.

-- Andreas

On Wed, 29 May 2024 at 21:17, Larry Garfield  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


Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-05-29 Thread Tim Düsterhus

Hi

On 5/29/24 21:15, Larry Garfield wrote:

* We've brought back the abbreviated form, as public-read, something else set 
is the most common use case.


The most common use case is that 'get' and 'set' are symmetric. Any 
divergence from that should stand out and I think that the hamming 
distance between


protected string $foo;

and

protected(set) string $foo;

is too small.

Other than that the proposal looks good to me. Ship it.

--

One note regarding the text. You already confirmed to me in private that:

class Foo {
private $dontTouchMe;
}

$backdoor = function ($key, $value) { $this->{$key} = $value; };

$f = new Foo();
$backdoor->call($f, 'dontTouchMe', 'butIDid');
var_dump($f);

would work as expected with aviz. It would make sense to explicitly 
spell that out, just like it's explicitly spelled out that 
`ReflectionProperty::setValue()` works.


Best regards
Tim Düsterhus


Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2023-01-05 Thread Dan Ackroyd
On Fri, 25 Nov 2022 at 00:07, Larry Garfield  wrote:
>
> On Sun, Nov 20, 2022, at 7:20 AM, Dan Ackroyd wrote:
> > Hi Larry,
> >
> > Regarding the syntax, up until now PHP has only supported the letters
> > a-z and underscore in keywords.
> >
> > I realise this is an aesthetic thing, but "private(set)" looks like a
> > function to me, and not a keyword. I saw the previous poll, and it
> > didn't include options for either protected_set/private_set or
> > protectedset/privateset.
> >
> > Was there a technical reason for excluding them as an option?
>
> Not in particular.  We originally proposed `private(set)` because that's what 
> Swift uses.  In the discussion people proposed several alternatives that I 
> put into the poll, but `private_set` wasn't one of them.  Although several 
> people said they were opposed to parens in the keyword,

Have you considered updating the RFC to use private_set, and not
introduce new characters for keywords?

As it wasn't in the poll, then sticking to the poll result with at
least some people saying they are opposed to it seems not necessarily
the correct choice. The ()'s look particularly funky to me with
property promotion.

cheers
Dan
Ack

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2023-01-05 Thread Ilija Tovilo
Hi Robert

On Thu, Jan 5, 2023 at 3:54 PM Robert Landers  wrote:
>
> One quick question,
>
> Will changing the property of a protected/private set via reflection
> be allowed? Or will you have to do some shenanigans like you currently
> have to do with readonly?

Since PHP 8.1 ReflectionProperty::setValue() allows writing to any
property from any scope by default (assuming it is not readonly)
without calling ReflectionProperty::setAccessible() first.

https://wiki.php.net/rfc/make-reflection-setaccessible-no-op

Essentially, there's no change to the existing behavior. You can write
to an asymmetric property using setValue() just like you could to a
protected or private property as the visibility check is skipped for
these cases.

I added a sentence to the RFCs reflection section to clarify.
Thanks for pointing this out.

Ilija

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2023-01-05 Thread Robert Landers
One quick question,

Will changing the property of a protected/private set via reflection
be allowed? Or will you have to do some shenanigans like you currently
have to do with readonly?

Robert Landers
Software Engineer
Utrecht NL

On Wed, Jan 4, 2023 at 9:29 PM Larry Garfield  wrote:
>
> On Wed, Dec 21, 2022, at 3:23 PM, Larry Garfield wrote:
> > On Tue, Dec 13, 2022, at 11:03 AM, Claude Pache wrote:
> >>> Le 13 déc. 2022 à 16:34, Claude Pache  a écrit :
> >>>
> >>>
> >>> Hi,
> >>>
> >>> As of today, the following declarations are rejected as syntax errors:
> >>>
> >>> ```php
> >>> class C {
> >>> $a;
> >>> int $b;
> >>> }
> >>> ```
> >>>
> >>> while the following declarations are accepted with implicit `public` 
> >>> visibility:
> >>>
> >>> ```php
> >>> class C {
> >>> static $c;
> >>> readonly int $d;
> >>> }
> >>> ```
> >>>
> >>> It would be reasonable to propose to allow to consistently omit the 
> >>> `public` keyword. But allowing to omit it in some cases (including the 
> >>> most controversial one: `protected(set)`) and not in other cases...? 
> >>> Because of this inconsistency, people are incited to always write 
> >>> explicitly `public` anyway.
> >>>
> >>> —Claude
> >>
> >>
> >> However, I’m just realising that omitting `public` in declarations like
> >> `public $a` and `public int $b` is probably not a good idea, because it
> >> is incompatible with constructor property promotion, as `function
> >> __construct(public int $b) { }`, and `function __construct(int $b) { }`
> >> have different meanings.
> >>
> >> —Claude
> >
> > Well, it seems the only people who have opinions on the abbreviated
> > form at all dislike it, so we've removed it for now and left a mention
> > in future-scope.  A future RFC can add that if desired.
> >
> > That should, I think, be the final change to the asymmetric visibility
> > RFC.  Baring anything else coming up, I expect to call the vote
> > sometime the week of 2 January.
> >
> > Happy $holiday!
> >
> > --Larry Garfield
>
> Happy New Year, PHP.  Fair warning, I will be opening the vote for asymmetric 
> visibility on Friday, baring any sudden new inputs in the next 40-ish hours.
>
> --Larry Garfield
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
>

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2023-01-04 Thread Larry Garfield
On Wed, Dec 21, 2022, at 3:23 PM, Larry Garfield wrote:
> On Tue, Dec 13, 2022, at 11:03 AM, Claude Pache wrote:
>>> Le 13 déc. 2022 à 16:34, Claude Pache  a écrit :
>>> 
>>> 
>>> Hi,
>>> 
>>> As of today, the following declarations are rejected as syntax errors:
>>> 
>>> ```php
>>> class C {
>>> $a;
>>> int $b;
>>> }
>>> ```
>>> 
>>> while the following declarations are accepted with implicit `public` 
>>> visibility:
>>> 
>>> ```php
>>> class C {
>>> static $c;
>>> readonly int $d;
>>> }
>>> ```
>>> 
>>> It would be reasonable to propose to allow to consistently omit the 
>>> `public` keyword. But allowing to omit it in some cases (including the most 
>>> controversial one: `protected(set)`) and not in other cases...? Because of 
>>> this inconsistency, people are incited to always write explicitly `public` 
>>> anyway.
>>> 
>>> —Claude
>>
>>
>> However, I’m just realising that omitting `public` in declarations like 
>> `public $a` and `public int $b` is probably not a good idea, because it 
>> is incompatible with constructor property promotion, as `function 
>> __construct(public int $b) { }`, and `function __construct(int $b) { }` 
>> have different meanings.
>>
>> —Claude
>
> Well, it seems the only people who have opinions on the abbreviated 
> form at all dislike it, so we've removed it for now and left a mention 
> in future-scope.  A future RFC can add that if desired.
>
> That should, I think, be the final change to the asymmetric visibility 
> RFC.  Baring anything else coming up, I expect to call the vote 
> sometime the week of 2 January.
>
> Happy $holiday!
>
> --Larry Garfield

Happy New Year, PHP.  Fair warning, I will be opening the vote for asymmetric 
visibility on Friday, baring any sudden new inputs in the next 40-ish hours.

--Larry Garfield

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-12-21 Thread Larry Garfield
On Tue, Dec 13, 2022, at 11:03 AM, Claude Pache wrote:
>> Le 13 déc. 2022 à 16:34, Claude Pache  a écrit :
>> 
>> 
>> Hi,
>> 
>> As of today, the following declarations are rejected as syntax errors:
>> 
>> ```php
>> class C {
>> $a;
>> int $b;
>> }
>> ```
>> 
>> while the following declarations are accepted with implicit `public` 
>> visibility:
>> 
>> ```php
>> class C {
>> static $c;
>> readonly int $d;
>> }
>> ```
>> 
>> It would be reasonable to propose to allow to consistently omit the `public` 
>> keyword. But allowing to omit it in some cases (including the most 
>> controversial one: `protected(set)`) and not in other cases...? Because of 
>> this inconsistency, people are incited to always write explicitly `public` 
>> anyway.
>> 
>> —Claude
>
>
> However, I’m just realising that omitting `public` in declarations like 
> `public $a` and `public int $b` is probably not a good idea, because it 
> is incompatible with constructor property promotion, as `function 
> __construct(public int $b) { }`, and `function __construct(int $b) { }` 
> have different meanings.
>
> —Claude

Well, it seems the only people who have opinions on the abbreviated form at all 
dislike it, so we've removed it for now and left a mention in future-scope.  A 
future RFC can add that if desired.

That should, I think, be the final change to the asymmetric visibility RFC.  
Baring anything else coming up, I expect to call the vote sometime the week of 
2 January.

Happy $holiday!

--Larry Garfield

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-12-13 Thread Claude Pache


> Le 13 déc. 2022 à 16:34, Claude Pache  a écrit :
> 
> 
> Hi,
> 
> As of today, the following declarations are rejected as syntax errors:
> 
> ```php
> class C {
> $a;
> int $b;
> }
> ```
> 
> while the following declarations are accepted with implicit `public` 
> visibility:
> 
> ```php
> class C {
> static $c;
> readonly int $d;
> }
> ```
> 
> It would be reasonable to propose to allow to consistently omit the `public` 
> keyword. But allowing to omit it in some cases (including the most 
> controversial one: `protected(set)`) and not in other cases...? Because of 
> this inconsistency, people are incited to always write explicitly `public` 
> anyway.
> 
> —Claude


However, I’m just realising that omitting `public` in declarations like `public 
$a` and `public int $b` is probably not a good idea, because it is incompatible 
with constructor property promotion, as `function __construct(public int $b) { 
}`, and `function __construct(int $b) { }` have different meanings.

—Claude



Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-12-13 Thread Claude Pache


> Le 11 déc. 2022 à 20:18, Larry Garfield  a écrit :
> 
> On Thu, Dec 1, 2022, at 12:31 PM, Tim Düsterhus wrote:
>> Hi
>> 
>> On 11/29/22 21:29, Larry Garfield wrote:
>>> Thank you everyone for the feedback.  Based on this thread, we've made two 
>>> changes to the RFC:
>>> 
>>> 1. We've moved readonly back to forbidden with a-viz for now.  I've added a 
>>> section to Future Scope where we really should sort this out in the future, 
>>> but we'll do that in the future when we can all focus on the various 
>>> nuances of just that piece.
>>> 
>>> 2. I rewrote the section on __set to make it clearer.  That also included 
>>> Ilija and I digging into all the nuances that are already present.  The 
>>> text may still look a bit complex, but that's because the existing logic is 
>>> already complex with readonly.  Long story short, the a-viz RFC does not 
>>> change anything in the way __set works vis a vis asymmetric visibility; it 
>>> just inherits and continues what readonly already started, so it's 
>>> consistent.
>>> 
>>> The PR should be updated in the next week or two with the latest changes.  
>>> Baring any major need for change, we expect to call a vote for it shortly 
>>> after New Years.
>>> 
>> 
>> Okay, then I'd like to officially "request" that the abbreviated form 
>> [1] is dropped:
>> 
>> I believe 'protected(set) string $foo' is easily confused with 
>> 'protected string $foo' at a simple glance.
>> 
>> Also any implicit rules are something developers will need to learn by 
>> heart, whereas an explicit 'public protected(set) string $foo' could 
>> reasonably be understood by someone without any PHP experience and some 
>> basic experience of OO concepts.
>> 
>> Having two separate explicit keywords also makes it much clearer that 
>> asymmetric visibility is involved, because it's also asymmetric in the code.
>> 
>> I believe the only benefit of the abbreviated form is saving 6 
>> keystrokes (+ one hit to the spacebar) and I don't believe it's worth 
>> the lack of clarity for an important property of the defined property.
>> 
>> Best regards
>> Tim Düsterhus
>> 
>> [1] https://wiki.php.net/rfc/asymmetric-visibility#abbreviated_form
> 
> 
> Does anyone else have feelings on this point?  IMO, the shorthand makes a lot 
> of sense when used with readonly to avoid lines getting just annoyingly long, 
> but without it I can see the argument for not allowing it; it's about a wash 
> in terms of length with readonly today.  I'm comfortable going with the 
> consensus on this one for now.
> 
> --Larry Garfield

Hi,

As of today, the following declarations are rejected as syntax errors:

``php
class C {
$a;
int $b;
}
```

while the following declarations are accepted with implicit `public` visibility:

``php
class C {
static $c;
readonly int $d;
}
```

It would be reasonable to propose to allow to consistently omit the `public` 
keyword. But allowing to omit it in some cases (including the most 
controversial one: `protected(set)`) and not in other cases...? Because of this 
inconsistency, people are incited to always write explicitly `public` anyway.

—Claude




Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-12-11 Thread Stephen Reay



> On 12 Dec 2022, at 02:18, Larry Garfield  wrote:
> 
> On Thu, Dec 1, 2022, at 12:31 PM, Tim Düsterhus wrote:
>> Hi
>> 
>> On 11/29/22 21:29, Larry Garfield wrote:
>>> Thank you everyone for the feedback.  Based on this thread, we've made two 
>>> changes to the RFC:
>>> 
>>> 1. We've moved readonly back to forbidden with a-viz for now.  I've added a 
>>> section to Future Scope where we really should sort this out in the future, 
>>> but we'll do that in the future when we can all focus on the various 
>>> nuances of just that piece.
>>> 
>>> 2. I rewrote the section on __set to make it clearer.  That also included 
>>> Ilija and I digging into all the nuances that are already present.  The 
>>> text may still look a bit complex, but that's because the existing logic is 
>>> already complex with readonly.  Long story short, the a-viz RFC does not 
>>> change anything in the way __set works vis a vis asymmetric visibility; it 
>>> just inherits and continues what readonly already started, so it's 
>>> consistent.
>>> 
>>> The PR should be updated in the next week or two with the latest changes.  
>>> Baring any major need for change, we expect to call a vote for it shortly 
>>> after New Years.
>>> 
>> 
>> Okay, then I'd like to officially "request" that the abbreviated form 
>> [1] is dropped:
>> 
>> I believe 'protected(set) string $foo' is easily confused with 
>> 'protected string $foo' at a simple glance.
>> 
>> Also any implicit rules are something developers will need to learn by 
>> heart, whereas an explicit 'public protected(set) string $foo' could 
>> reasonably be understood by someone without any PHP experience and some 
>> basic experience of OO concepts.
>> 
>> Having two separate explicit keywords also makes it much clearer that 
>> asymmetric visibility is involved, because it's also asymmetric in the code.
>> 
>> I believe the only benefit of the abbreviated form is saving 6 
>> keystrokes (+ one hit to the spacebar) and I don't believe it's worth 
>> the lack of clarity for an important property of the defined property.
>> 
>> Best regards
>> Tim Düsterhus
>> 
>> [1] https://wiki.php.net/rfc/asymmetric-visibility#abbreviated_form
> 
> 
> Does anyone else have feelings on this point?  IMO, the shorthand makes a lot 
> of sense when used with readonly to avoid lines getting just annoyingly long, 
> but without it I can see the argument for not allowing it; it's about a wash 
> in terms of length with readonly today.  I'm comfortable going with the 
> consensus on this one for now.
> 
> --Larry Garfield
> 
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
> 

I’ll just re-iterate what I said in chat a while ago - I think requiring the 
dev to be explicit about making it public is a safer first step, and it has no 
BC risk if you wanted to later allow the implicit variant, and without the 
capability to combine with the readonly keyword (yet) it doesn’t seem like a 
huge problem to be explicit IMO.



Cheers

Stephen 
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-12-11 Thread Larry Garfield
On Thu, Dec 1, 2022, at 12:31 PM, Tim Düsterhus wrote:
> Hi
>
> On 11/29/22 21:29, Larry Garfield wrote:
>> Thank you everyone for the feedback.  Based on this thread, we've made two 
>> changes to the RFC:
>> 
>> 1. We've moved readonly back to forbidden with a-viz for now.  I've added a 
>> section to Future Scope where we really should sort this out in the future, 
>> but we'll do that in the future when we can all focus on the various nuances 
>> of just that piece.
>> 
>> 2. I rewrote the section on __set to make it clearer.  That also included 
>> Ilija and I digging into all the nuances that are already present.  The text 
>> may still look a bit complex, but that's because the existing logic is 
>> already complex with readonly.  Long story short, the a-viz RFC does not 
>> change anything in the way __set works vis a vis asymmetric visibility; it 
>> just inherits and continues what readonly already started, so it's 
>> consistent.
>> 
>> The PR should be updated in the next week or two with the latest changes.  
>> Baring any major need for change, we expect to call a vote for it shortly 
>> after New Years.
>> 
>
> Okay, then I'd like to officially "request" that the abbreviated form 
> [1] is dropped:
>
> I believe 'protected(set) string $foo' is easily confused with 
> 'protected string $foo' at a simple glance.
>
> Also any implicit rules are something developers will need to learn by 
> heart, whereas an explicit 'public protected(set) string $foo' could 
> reasonably be understood by someone without any PHP experience and some 
> basic experience of OO concepts.
>
> Having two separate explicit keywords also makes it much clearer that 
> asymmetric visibility is involved, because it's also asymmetric in the code.
>
> I believe the only benefit of the abbreviated form is saving 6 
> keystrokes (+ one hit to the spacebar) and I don't believe it's worth 
> the lack of clarity for an important property of the defined property.
>
> Best regards
> Tim Düsterhus
>
> [1] https://wiki.php.net/rfc/asymmetric-visibility#abbreviated_form


Does anyone else have feelings on this point?  IMO, the shorthand makes a lot 
of sense when used with readonly to avoid lines getting just annoyingly long, 
but without it I can see the argument for not allowing it; it's about a wash in 
terms of length with readonly today.  I'm comfortable going with the consensus 
on this one for now.

--Larry Garfield

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-12-05 Thread Larry Garfield
On Mon, Dec 5, 2022, at 12:47 PM, Claude Pache wrote:
>> Le 3 déc. 2022 à 19:28, Larry Garfield  a écrit :
>> 
>> I also clarified that static properties are explicitly not supported with 
>> a-viz.  
>
> This is a serious issue, not necessarily because it is of great value, 
> but because it introduces an unexpected asymmetry between static and 
> non-static properties. In other words, from a user point-of-view, it is 
> expected that staticness is orthogonal to visibility.
>
> Therefore, I would expect that the RFC has a dedicated section about 
> static properties (as it has already one about [un]typed properties), 
> not just a small sentence in the intro that could be overlooked.
>
>
>> and as it's of limited value we're not going to bother.
>
> Whether it’s of limited value or not, depends, I suppose, of coding 
> style. Personally, I use static properties for various good and bad 
> reasons, and some of them would be happy to take advantage of 
> asymmetric visibility. E.g.:
>
> * I may store settings that concern the whole class (and that I cannot 
> or want not register as constants) in static properties;
>
> * My typical implementation of “monostate pattern” is not: 
> `Foo::getInstance()->bar()`, `Foo::getInstance()->baz`, but: 
> `Foo::bar()`, `Foo::$baz`;
>
> * ...
>
> Of course, I would accept the reason “it is difficult to implement”, 
> but not the excuse “it is almost worthless”.

It is difficult to implement, and thus we're not going to put in the effort to 
figure out how to do it because the value is so much less. :-)  But fair 
enough, I'll move it to its own section so it's more readily apparent.

--Larry Garfield

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-12-05 Thread Claude Pache


> Le 3 déc. 2022 à 19:28, Larry Garfield  a écrit :
> 
> I also clarified that static properties are explicitly not supported with 
> a-viz.  

This is a serious issue, not necessarily because it is of great value, but 
because it introduces an unexpected asymmetry between static and non-static 
properties. In other words, from a user point-of-view, it is expected that 
staticness is orthogonal to visibility.

Therefore, I would expect that the RFC has a dedicated section about static 
properties (as it has already one about [un]typed properties), not just a small 
sentence in the intro that could be overlooked.


> and as it's of limited value we're not going to bother.

Whether it’s of limited value or not, depends, I suppose, of coding style. 
Personally, I use static properties for various good and bad reasons, and some 
of them would be happy to take advantage of asymmetric visibility. E.g.:

* I may store settings that concern the whole class (and that I cannot or want 
not register as constants) in static properties;

* My typical implementation of “monostate pattern” is not: 
`Foo::getInstance()->bar()`, `Foo::getInstance()->baz`, but: `Foo::bar()`, 
`Foo::$baz`;

* ...

Of course, I would accept the reason “it is difficult to implement”, but not 
the excuse “it is almost worthless”.


—Claude

Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-12-03 Thread Larry Garfield
On Fri, Dec 2, 2022, at 7:11 AM, Stephen Reay wrote:

> The proposed __set behaviour in this RFC will mean the second example 
> **won’t work**, and that is both extremely unintuitive and IMO, 
> technically unnecessary with regards to avoiding BC breaks.
>
> Cheers
>
> Stephen

Thanks to the wonders of real-time high-bandwidth communication (online chat), 
we've been able to clarify and adjust the behavior of a-viz with __set in a way 
that is internally consistent and has no BC breaks.  I've updated the RFC 
accordingly with the dirty details, but the long story short is that we've been 
able to define it such that unset() is no longer necessary on set-not-visible 
properties; they'll still trigger __set without that.  Readonly properties 
still do, as they do today, but that's off topic to think about.

I also clarified that static properties are explicitly not supported with 
a-viz.  That's mainly for implementation reasons; it's just really hard to do, 
and as it's of limited value we're not going to bother.

--Larry Garfield

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-12-02 Thread Stephen Reay


> On 2 Dec 2022, at 18:31, Ilija Tovilo  wrote:
> 
> Hi Stephen
> 
>> So here’s my last attempt:
>> 
>> Please change this behaviour in your rfc.
>> 
>> You are explicitly making it mutually exclusive with readonly now, so that’s 
>> not a bc break - if/when it becomes compatible with readonly the authors of 
>> that rfc can either keep the limitation as it exists **for readonly 
>> properties** (I’m not an expert but I don’t believe this would be a BC break 
>> either), or decide to drop the limitation completely (deliberate BC break)
>> 
>> Keeping the limitation now on non-readonly properties makes no sense, and 
>> will be confusing to user land developers.
> 
> This behavior is already not limited to readonly, it works the same
> for normal typed properties.
> https://3v4l.org/WpBp4
> 
> The set-visibility is not relevant here: When unset has been called,
> __set will be called (and __get too). The set-visibility is only
> relevant when unset hasn't been called, as that will influence whether
> the property is written to or an error is thrown. The RFC is actually
> wrong saying this is specifically due to readonly properties. This
> behavior has been here for a while.
> 
> See the relevant commit:
> https://github.com/php/php-src/commit/f1848a4b3f807d21415c5a334b461d240b2a83af
> 
>> Assigning to an uninitialized typed property will no longer trigger
>> a call to __set(). However, calls to __set() are still triggered if
>> the property is explicitly unset().
> 
>> This gives us both the behavior people generally expect, and still
>> allows ORMs to do lazy initialization by unsetting properties.
> 
>> For PHP 8, we should fine a way to forbid unsetting of declared
>> properties entirely, and provide a different way to achieve lazy
>> initialization.
> 
> I'm not sure if anybody actually makes use of this trick. It might be
> worth removing this weird behavior by offering an alternative. In any
> case, this is out of scope for this RFC.
> 
> Regards,
> Ilija
> 
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
> 

Hi Ilija

I’m not sure if you missed my earlier emails but I’m pretty sure you’ve 
misunderstood what I’m asking about.

I’m not, and have never, asked for the behaviour of explicitly unset() 
properties to change. Not once, never, nada. I do agree that the behaviour 
weird, but its weird in a way that gives userland developers more 
power/capability, not less.


What I *am* asking for, is that when a non-readonly property is declared with 
protected or private `set` visibility, an attempt to set/write that property 
from outside the class will trigger __set(), exactly the way it does now for a 
property declared as protected or private.

If it’s not obvious the major reason for this is to allow dropping  __get 
boilerplate while maintaining the ability to have checks/custom logic on 
set/write (i.e. a poor mans property set accessor), and thus existing code that 
uses this can easily and safely upgrade to using asymmetric visibility without 
affecting the __set handler logic.


To make it crystal clear, here is an example:

```
class FooSym {
   protected string $bar;

   public function __set($name, $value) {
  if ($name === 'bar') {
 $this->bar = $value;
  }
   }

   public function __get($name) {
  if ($name === 'bar') {
 return $this->bar;
  }
   }
}

$f = new FooSym;
$f->bar = 'hello';
echo $f->bar;


class FooAsym {
   public protected(set) string $bar;

   public function __set($name, $value) {
  if ($name === 'bar') {
 $this->bar = $value;
  }
   }

}

$f = new FooAsym;
$f->bar = 'hello';
echo $f->bar;

```

The first class is a trivial example of what works right now. No use of unset() 
is required, it behaves as expected.

The proposed __set behaviour in this RFC will mean the second example **won’t 
work**, and that is both extremely unintuitive and IMO, technically unnecessary 
with regards to avoiding BC breaks.

Cheers

Stephen 







Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-12-02 Thread Nicolas Grekas
Le ven. 2 déc. 2022 à 12:32, Ilija Tovilo  a écrit :

> Hi Stephen
>
> > So here’s my last attempt:
> >
> > Please change this behaviour in your rfc.
> >
> > You are explicitly making it mutually exclusive with readonly now, so
> that’s not a bc break - if/when it becomes compatible with readonly the
> authors of that rfc can either keep the limitation as it exists **for
> readonly properties** (I’m not an expert but I don’t believe this would be
> a BC break either), or decide to drop the limitation completely (deliberate
> BC break)
> >
> > Keeping the limitation now on non-readonly properties makes no sense,
> and will be confusing to user land developers.
>
> This behavior is already not limited to readonly, it works the same
> for normal typed properties.
> https://3v4l.org/WpBp4
>
> The set-visibility is not relevant here: When unset has been called,
> __set will be called (and __get too). The set-visibility is only
> relevant when unset hasn't been called, as that will influence whether
> the property is written to or an error is thrown. The RFC is actually
> wrong saying this is specifically due to readonly properties. This
> behavior has been here for a while.
>
> See the relevant commit:
>
> https://github.com/php/php-src/commit/f1848a4b3f807d21415c5a334b461d240b2a83af
>
> > Assigning to an uninitialized typed property will no longer trigger
> > a call to __set(). However, calls to __set() are still triggered if
> > the property is explicitly unset().
>
> > This gives us both the behavior people generally expect, and still
> > allows ORMs to do lazy initialization by unsetting properties.
>
> > For PHP 8, we should fine a way to forbid unsetting of declared
> > properties entirely, and provide a different way to achieve lazy
> > initialization.
>
> I'm not sure if anybody actually makes use of this trick. It might be
> worth removing this weird behavior by offering an alternative. In any
> case, this is out of scope for this RFC.
>

Yes, there are critical features built on this, especially Ocramius'
ProxyManager and more recently Symfony's VarExporter, both to provide lazy
initialization. This is an important capability provided by the engine. It
should be preserved (in the current form or a better one possibly of
course.)

Nicolas


Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-12-02 Thread Ilija Tovilo
Hi Stephen

> So here’s my last attempt:
>
> Please change this behaviour in your rfc.
>
> You are explicitly making it mutually exclusive with readonly now, so that’s 
> not a bc break - if/when it becomes compatible with readonly the authors of 
> that rfc can either keep the limitation as it exists **for readonly 
> properties** (I’m not an expert but I don’t believe this would be a BC break 
> either), or decide to drop the limitation completely (deliberate BC break)
>
> Keeping the limitation now on non-readonly properties makes no sense, and 
> will be confusing to user land developers.

This behavior is already not limited to readonly, it works the same
for normal typed properties.
https://3v4l.org/WpBp4

The set-visibility is not relevant here: When unset has been called,
__set will be called (and __get too). The set-visibility is only
relevant when unset hasn't been called, as that will influence whether
the property is written to or an error is thrown. The RFC is actually
wrong saying this is specifically due to readonly properties. This
behavior has been here for a while.

See the relevant commit:
https://github.com/php/php-src/commit/f1848a4b3f807d21415c5a334b461d240b2a83af

> Assigning to an uninitialized typed property will no longer trigger
> a call to __set(). However, calls to __set() are still triggered if
> the property is explicitly unset().

> This gives us both the behavior people generally expect, and still
> allows ORMs to do lazy initialization by unsetting properties.

> For PHP 8, we should fine a way to forbid unsetting of declared
> properties entirely, and provide a different way to achieve lazy
> initialization.

I'm not sure if anybody actually makes use of this trick. It might be
worth removing this weird behavior by offering an alternative. In any
case, this is out of scope for this RFC.

Regards,
Ilija

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-12-01 Thread Stephen Reay



> On 2 Dec 2022, at 01:21, Larry Garfield  wrote:
> 
> On Wed, Nov 30, 2022, at 7:38 PM, Stephen Reay wrote:
> 
 So please, can you explain to me why consistency with an implementation
 detail of readonly properties is more important than consistency with
 declared developer intention for regular properties via the magic
 setter method?
>>> There's a couple of reasons.
>>> One, and arguably the most important, readonly and aviz being incompatible 
>>> is, hopefully, a temporary situation.  There's some fiddly bits to work out 
>>> design-wise, and based on earlier comments in the thread we're going to 
>>> punt on that for now to avoid that dragging down the whole RFC.  I believe 
>>> we absolutely should allow them together in the future (maybe in a later 
>>> 8.3 RFC, maybe a future version, TBD), which means ensuring, now, that they 
>>> are compatible in the future.  This approach involves the fewest future BC 
>>> breaks.
>>> Second, I wouldn't call the current behavior of readonly a mere 
>>> implementation detail.  It's weird and unexpected, I'd agree, but only as a 
>>> side effect of previous design decisions, some of which are even older than 
>>> readonly.  But it's an observed behavior that code can rely on, and in some 
>>> cases does.  For example:
>>> https://peakd.com/hive-168588/@crell/php-tricks-lazy-public-readonly-properties
>>> The "unset a declared property to force it through __get once" is a trick 
>>> that some ORMs use extensively.  readonly just inherited that, leading to 
>>> the current behavior: __set depends on the write/set visibility of the 
>>> property and its settedness.  This RFC doesn't change anything there.  
>>> The alternative would be to have __set called always for a non-public-set 
>>> property.  However, that is a place for bugs, as you then can't not have a 
>>> back-door way to publicly set a property even if it's declared 
>>> private(set).  (Or, you have to be very careful in your __set to avoid it.) 
>>>  That is both inconsistent with the language today, and error prone.
>>> Finally, we're planning to work in the near-future on property hooks (aka 
>>> property accessors), which would allow per-property custom set routines.  
>>> That would largely remove the issue entirely, as the use of __set would go 
>>> way down and you'd basically never have to use it with a declared property, 
>>> fancy tricks or no, so this issue would never come up at all.
>>> --Larry Garfield
>>> --
>>> PHP Internals - PHP Runtime Development Mailing List
>>> To unsubscribe, visit: https://www.php.net/unsub.php
>> Hi Larry,
>> I think there must be some confusion somewhere, based on some of your 
>> comments.
>> I’m not suggesting that the “unset to force a **public** property to go
>> through getter/setter methods” logic should be specifically different.
>> I’m suggesting that when the decision is made to call __set or not, the
>> properties **set** visibility is what should be considered, not it’s
>> **get** visibility.
>> Your own comment even describes this behaviour: "leading to the current
>> behavior: __set depends on the write/set visibility of the property"
>> But your RFC says that __set will depend on the **read/get** visibility
>> of the property.
>>> you then can't not have a back-door way to publicly set a property even if 
>>> it's declared private(set).  (Or, you have to be very careful in your __set 
>>> to avoid it.)  That is both inconsistent with the language today, and error 
>>> prone.
>> If a developer adds a _set() method that can write to a private(set)
>> property, I would expect that is working exactly as desired, exactly as
>> it does **now** where it’s just a “protected” property.
> 
> I think we're talking past each other a bit. :-)
> 
> The logic described in the RFC is, to the best of out knowledge, what already 
> happens in 8.1/8.2 with readonly.  Whether that is good or bad, obvious or 
> intuitive, it's what PHP already does, for better or worse.  We view readonly 
> as, effectively, a shorthand for "private(set) write-once" (which is what it 
> is), and want to ensure that future RFCs can do that explicitly so that we 
> can allow `public protected(set) readonly` in the future.
> 
> For that to be possible, not changing the existing behavior is a necessity.  
> Changing the behavior described in the RFC right now is a BC break.  That's 
> true whether the logic described in the RFC is good or not, because that's 
> how it already works with `readonly`.
> 
> Is it weird that __set depends in part on read visibility?  Kinda, yeah.  But 
> that's already the behavior in 8.1/8.2.  We're not changing anything, and 
> this RFC is not the place to break that kind of BC.
> 
> If someone can demonstrate that the logic described there is not what 
> actually happens now, please let us know, because the goal is to not change 
> any behavior in this regard.  Effectively, that whole section is descriptive 
> of PHP today and a comment 

Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-12-01 Thread Tim Düsterhus

Hi

On 11/29/22 21:29, Larry Garfield wrote:

Thank you everyone for the feedback.  Based on this thread, we've made two 
changes to the RFC:

1. We've moved readonly back to forbidden with a-viz for now.  I've added a 
section to Future Scope where we really should sort this out in the future, but 
we'll do that in the future when we can all focus on the various nuances of 
just that piece.

2. I rewrote the section on __set to make it clearer.  That also included Ilija 
and I digging into all the nuances that are already present.  The text may 
still look a bit complex, but that's because the existing logic is already 
complex with readonly.  Long story short, the a-viz RFC does not change 
anything in the way __set works vis a vis asymmetric visibility; it just 
inherits and continues what readonly already started, so it's consistent.

The PR should be updated in the next week or two with the latest changes.  
Baring any major need for change, we expect to call a vote for it shortly after 
New Years.



Okay, then I'd like to officially "request" that the abbreviated form 
[1] is dropped:


I believe 'protected(set) string $foo' is easily confused with 
'protected string $foo' at a simple glance.


Also any implicit rules are something developers will need to learn by 
heart, whereas an explicit 'public protected(set) string $foo' could 
reasonably be understood by someone without any PHP experience and some 
basic experience of OO concepts.


Having two separate explicit keywords also makes it much clearer that 
asymmetric visibility is involved, because it's also asymmetric in the code.


I believe the only benefit of the abbreviated form is saving 6 
keystrokes (+ one hit to the spacebar) and I don't believe it's worth 
the lack of clarity for an important property of the defined property.


Best regards
Tim Düsterhus

[1] https://wiki.php.net/rfc/asymmetric-visibility#abbreviated_form

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-12-01 Thread Larry Garfield
On Wed, Nov 30, 2022, at 7:38 PM, Stephen Reay wrote:

>>> So please, can you explain to me why consistency with an implementation 
>>> detail of readonly properties is more important than consistency with 
>>> declared developer intention for regular properties via the magic 
>>> setter method?
>> 
>> There's a couple of reasons.
>> 
>> One, and arguably the most important, readonly and aviz being incompatible 
>> is, hopefully, a temporary situation.  There's some fiddly bits to work out 
>> design-wise, and based on earlier comments in the thread we're going to punt 
>> on that for now to avoid that dragging down the whole RFC.  I believe we 
>> absolutely should allow them together in the future (maybe in a later 8.3 
>> RFC, maybe a future version, TBD), which means ensuring, now, that they are 
>> compatible in the future.  This approach involves the fewest future BC 
>> breaks.
>> 
>> Second, I wouldn't call the current behavior of readonly a mere 
>> implementation detail.  It's weird and unexpected, I'd agree, but only as a 
>> side effect of previous design decisions, some of which are even older than 
>> readonly.  But it's an observed behavior that code can rely on, and in some 
>> cases does.  For example:
>> 
>> https://peakd.com/hive-168588/@crell/php-tricks-lazy-public-readonly-properties
>> 
>> The "unset a declared property to force it through __get once" is a trick 
>> that some ORMs use extensively.  readonly just inherited that, leading to 
>> the current behavior: __set depends on the write/set visibility of the 
>> property and its settedness.  This RFC doesn't change anything there.  
>> 
>> The alternative would be to have __set called always for a non-public-set 
>> property.  However, that is a place for bugs, as you then can't not have a 
>> back-door way to publicly set a property even if it's declared private(set). 
>>  (Or, you have to be very careful in your __set to avoid it.)  That is both 
>> inconsistent with the language today, and error prone.
>> 
>> Finally, we're planning to work in the near-future on property hooks (aka 
>> property accessors), which would allow per-property custom set routines.  
>> That would largely remove the issue entirely, as the use of __set would go 
>> way down and you'd basically never have to use it with a declared property, 
>> fancy tricks or no, so this issue would never come up at all.
>> 
>> --Larry Garfield
>> 
>> --
>> PHP Internals - PHP Runtime Development Mailing List
>> To unsubscribe, visit: https://www.php.net/unsub.php
>
> Hi Larry,
>
>
> I think there must be some confusion somewhere, based on some of your 
> comments.
>
> I’m not suggesting that the “unset to force a **public** property to go 
> through getter/setter methods” logic should be specifically different.
>
> I’m suggesting that when the decision is made to call __set or not, the 
> properties **set** visibility is what should be considered, not it’s 
> **get** visibility.
>
> Your own comment even describes this behaviour: "leading to the current 
> behavior: __set depends on the write/set visibility of the property"
>
> But your RFC says that __set will depend on the **read/get** visibility 
> of the property.
>
>
>> you then can't not have a back-door way to publicly set a property even if 
>> it's declared private(set).  (Or, you have to be very careful in your __set 
>> to avoid it.)  That is both inconsistent with the language today, and error 
>> prone.
>
> If a developer adds a _set() method that can write to a private(set) 
> property, I would expect that is working exactly as desired, exactly as 
> it does **now** where it’s just a “protected” property.

I think we're talking past each other a bit. :-)

The logic described in the RFC is, to the best of out knowledge, what already 
happens in 8.1/8.2 with readonly.  Whether that is good or bad, obvious or 
intuitive, it's what PHP already does, for better or worse.  We view readonly 
as, effectively, a shorthand for "private(set) write-once" (which is what it 
is), and want to ensure that future RFCs can do that explicitly so that we can 
allow `public protected(set) readonly` in the future.

For that to be possible, not changing the existing behavior is a necessity.  
Changing the behavior described in the RFC right now is a BC break.  That's 
true whether the logic described in the RFC is good or not, because that's how 
it already works with `readonly`.

Is it weird that __set depends in part on read visibility?  Kinda, yeah.  But 
that's already the behavior in 8.1/8.2.  We're not changing anything, and this 
RFC is not the place to break that kind of BC.

If someone can demonstrate that the logic described there is not what actually 
happens now, please let us know, because the goal is to not change any behavior 
in this regard.  Effectively, that whole section is descriptive of PHP today 
and a comment "and we're not breaking it."

--Larry Garfield

--
PHP Internals - PHP Runtime Development 

Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-30 Thread Stephen Reay



> On 1 Dec 2022, at 08:38, Stephen Reay  wrote:
> 
> 
> 
>> On 30 Nov 2022, at 22:09, Larry Garfield  wrote:
>> 
>> On Tue, Nov 29, 2022, at 11:25 PM, Stephen Reay wrote:
>> 
>>> Hi Larry,
>>> 
>>> Thank you for clarifying the setter behaviour in more explicit terms, 
>>> but I have to say I’m quite disappointed in this continued “use the 
>>> logic of readonly to apply to something that is explicitly not 
>>> readonly” - this is even more stark now that you’ve explicitly made 
>>> them mutually exclusive behaviours.
>>> 
>>> I’m generally very in favour of maintaining consistency, but this seems 
>>> like it’s using technical consistency as an excuse to justify 
>>> unintuitive behaviour that breaks consistency in another, much more 
>>> obvious way.
>>> 
>>> 
>>> Can you explain why it makes more sense to maintain consistency with 
>>> “readonly” than it does to maintain consistency with the existing 
>>> “__set()” behaviour for properties, particularly now that you’ve 
>>> indicated these features (asymmetric visibility and readonly) are 
>>> mutually exclusive? 
>>> 
>>> While it’s stated multiple times that “readonly” introduced a limited 
>>> form of asymmetric visibility, and thus this is a continuation, in 
>>> terms of intuitiveness, the existing __set() rules are very easy to 
>>> comprehend even with readonly:
>>> 
>>> - if the property is declared as public, __set() is never called; if 
>>> it’s declared as protected, __set is called when the property is 
>>> accessed from outside that class or it’s hierarchy. Yes, I know that 
>>> readonly imposes an implicit visibility difference - but that is 
>>> essentially an implementation detail, from the point of view of the 
>>> userland developer, it’s not a clear statement of intended behaviour on 
>>> their part, expressed through the code as written.
>>> 
>>> For example, with `public readonly int $foo` it’s quite obvious why 
>>> __set() isn’t called, using the exiting well-understood logic: it’s a 
>>> public property. PHP applies a kind of asymmetric visibility to the 
>>> property behind the scenes, but that isn’t what the developer declared, 
>>> it’s the implementation. This behaviour matches that of regular, 
>>> non-readonly fields: when the field is declared public (or has implicit 
>>> public visibility) __set() is never called.
>>> 
>>> If we make that field protected, __set() will be called when the 
>>> property is written to from outside the class, regardless of whether 
>>> it’s readonly or not.
>>> 
>>> 
>>> What you’re proposing changes that, in a way that is completely 
>>> unintuitive: when attempting to *write* data to a property that is 
>>> marked as protected(set), the __set() method will not be called.
>>> 
>>> 
>>> So please, can you explain to me why consistency with an implementation 
>>> detail of readonly properties is more important than consistency with 
>>> declared developer intention for regular properties via the magic 
>>> setter method?
>> 
>> There's a couple of reasons.
>> 
>> One, and arguably the most important, readonly and aviz being incompatible 
>> is, hopefully, a temporary situation.  There's some fiddly bits to work out 
>> design-wise, and based on earlier comments in the thread we're going to punt 
>> on that for now to avoid that dragging down the whole RFC.  I believe we 
>> absolutely should allow them together in the future (maybe in a later 8.3 
>> RFC, maybe a future version, TBD), which means ensuring, now, that they are 
>> compatible in the future.  This approach involves the fewest future BC 
>> breaks.
>> 
>> Second, I wouldn't call the current behavior of readonly a mere 
>> implementation detail.  It's weird and unexpected, I'd agree, but only as a 
>> side effect of previous design decisions, some of which are even older than 
>> readonly.  But it's an observed behavior that code can rely on, and in some 
>> cases does.  For example:
>> 
>> https://peakd.com/hive-168588/@crell/php-tricks-lazy-public-readonly-properties
>> 
>> The "unset a declared property to force it through __get once" is a trick 
>> that some ORMs use extensively.  readonly just inherited that, leading to 
>> the current behavior: __set depends on the write/set visibility of the 
>> property and its settedness.  This RFC doesn't change anything there.  
>> 
>> The alternative would be to have __set called always for a non-public-set 
>> property.  However, that is a place for bugs, as you then can't not have a 
>> back-door way to publicly set a property even if it's declared private(set). 
>>  (Or, you have to be very careful in your __set to avoid it.)  That is both 
>> inconsistent with the language today, and error prone.
>> 
>> Finally, we're planning to work in the near-future on property hooks (aka 
>> property accessors), which would allow per-property custom set routines.  
>> That would largely remove the issue entirely, as the use of __set would go 
>> way down and you'd basically never have to use 

Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-30 Thread Stephen Reay



> On 30 Nov 2022, at 22:09, Larry Garfield  wrote:
> 
> On Tue, Nov 29, 2022, at 11:25 PM, Stephen Reay wrote:
> 
>> Hi Larry,
>> 
>> Thank you for clarifying the setter behaviour in more explicit terms, 
>> but I have to say I’m quite disappointed in this continued “use the 
>> logic of readonly to apply to something that is explicitly not 
>> readonly” - this is even more stark now that you’ve explicitly made 
>> them mutually exclusive behaviours.
>> 
>> I’m generally very in favour of maintaining consistency, but this seems 
>> like it’s using technical consistency as an excuse to justify 
>> unintuitive behaviour that breaks consistency in another, much more 
>> obvious way.
>> 
>> 
>> Can you explain why it makes more sense to maintain consistency with 
>> “readonly” than it does to maintain consistency with the existing 
>> “__set()” behaviour for properties, particularly now that you’ve 
>> indicated these features (asymmetric visibility and readonly) are 
>> mutually exclusive? 
>> 
>> While it’s stated multiple times that “readonly” introduced a limited 
>> form of asymmetric visibility, and thus this is a continuation, in 
>> terms of intuitiveness, the existing __set() rules are very easy to 
>> comprehend even with readonly:
>> 
>> - if the property is declared as public, __set() is never called; if 
>> it’s declared as protected, __set is called when the property is 
>> accessed from outside that class or it’s hierarchy. Yes, I know that 
>> readonly imposes an implicit visibility difference - but that is 
>> essentially an implementation detail, from the point of view of the 
>> userland developer, it’s not a clear statement of intended behaviour on 
>> their part, expressed through the code as written.
>> 
>> For example, with `public readonly int $foo` it’s quite obvious why 
>> __set() isn’t called, using the exiting well-understood logic: it’s a 
>> public property. PHP applies a kind of asymmetric visibility to the 
>> property behind the scenes, but that isn’t what the developer declared, 
>> it’s the implementation. This behaviour matches that of regular, 
>> non-readonly fields: when the field is declared public (or has implicit 
>> public visibility) __set() is never called.
>> 
>> If we make that field protected, __set() will be called when the 
>> property is written to from outside the class, regardless of whether 
>> it’s readonly or not.
>> 
>> 
>> What you’re proposing changes that, in a way that is completely 
>> unintuitive: when attempting to *write* data to a property that is 
>> marked as protected(set), the __set() method will not be called.
>> 
>> 
>> So please, can you explain to me why consistency with an implementation 
>> detail of readonly properties is more important than consistency with 
>> declared developer intention for regular properties via the magic 
>> setter method?
> 
> There's a couple of reasons.
> 
> One, and arguably the most important, readonly and aviz being incompatible 
> is, hopefully, a temporary situation.  There's some fiddly bits to work out 
> design-wise, and based on earlier comments in the thread we're going to punt 
> on that for now to avoid that dragging down the whole RFC.  I believe we 
> absolutely should allow them together in the future (maybe in a later 8.3 
> RFC, maybe a future version, TBD), which means ensuring, now, that they are 
> compatible in the future.  This approach involves the fewest future BC breaks.
> 
> Second, I wouldn't call the current behavior of readonly a mere 
> implementation detail.  It's weird and unexpected, I'd agree, but only as a 
> side effect of previous design decisions, some of which are even older than 
> readonly.  But it's an observed behavior that code can rely on, and in some 
> cases does.  For example:
> 
> https://peakd.com/hive-168588/@crell/php-tricks-lazy-public-readonly-properties
> 
> The "unset a declared property to force it through __get once" is a trick 
> that some ORMs use extensively.  readonly just inherited that, leading to the 
> current behavior: __set depends on the write/set visibility of the property 
> and its settedness.  This RFC doesn't change anything there.  
> 
> The alternative would be to have __set called always for a non-public-set 
> property.  However, that is a place for bugs, as you then can't not have a 
> back-door way to publicly set a property even if it's declared private(set).  
> (Or, you have to be very careful in your __set to avoid it.)  That is both 
> inconsistent with the language today, and error prone.
> 
> Finally, we're planning to work in the near-future on property hooks (aka 
> property accessors), which would allow per-property custom set routines.  
> That would largely remove the issue entirely, as the use of __set would go 
> way down and you'd basically never have to use it with a declared property, 
> fancy tricks or no, so this issue would never come up at all.
> 
> --Larry Garfield
> 
> --
> PHP Internals - PHP Runtime 

Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-30 Thread Larry Garfield
On Wed, Nov 30, 2022, at 12:10 PM, Claude Pache wrote:
> Hi,
>
> What is the behaviour of the following code?
>
> ```php
> class Foo {
> public private(set) array $bar = [ ];
> }
>
> $foo = new Foo;
>
> $foo->bar['x'] = 'y'; // error?
>
> var_dump(isset($foo->bar['x'])); // true?, false?
> ```
>
> I think that modification of an array should require write access? 
> (That should be clarified in the RFC.)

Correct, that would not be allowed.  Array writes are always indirect 
modification, because it's two steps to get to it.  That will error out in this 
case, as one would expect from `private(set)`.

--Larry Garfield

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-30 Thread Claude Pache
Hi,

What is the behaviour of the following code?

```php
class Foo {
public private(set) array $bar = [ ];
}

$foo = new Foo;

$foo->bar['x'] = 'y'; // error?

var_dump(isset($foo->bar['x'])); // true?, false?
```

I think that modification of an array should require write access? (That should 
be clarified in the RFC.)

—Claude
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-30 Thread Larry Garfield
On Tue, Nov 29, 2022, at 2:29 PM, Larry Garfield wrote:
> On Sun, Nov 13, 2022, at 2:08 PM, Larry Garfield wrote:
>> Hi folks.  Ilija is nearly done with the implementation for asymmetric 
>> visibility and flushing out edge cases, but we've run into one design 
>> question we'd like feedback on.
>>
>> There's two design decisions we've made at this point, both of which we 
>> think are logical and reasonable:
>>
>> 1. If specified, the set visibility must be tighter than the get 
>> visibility.  So `protected protected(set)` and `protected public(set)` 
>> are not permitted, for instance.
>>
>> 2. `readonly` is a "write once" flag that may be combined with 
>> asymmetric visibility.  If no set visibility is specified, `readoly` 
>> implies `private(set)`, but a different set visibility may also be 
>> provided.
>>
>> These are both reasonable rules.  However, it creates a conflict.  
>> Specifically, in the following cases:
>>
>> public public(set) readonly string $foo
>>
>> protected protected(set) readonly string $foo
>>
>> These would be the only way to have a non-private-set readonly 
>> property.  While the first is in practice quite unlikely, the second 
>> has valid use cases.  (In particular, a base class that provides 
>> properties expected to be set by a child constructor, and then used by 
>> a method in the parent class.)  However, it would not be allowed under 
>> the rules above.  Working around it would require specifying `public 
>> protected(set) readonly...`, which means exposing a property that 
>> likely should not be exposed.
>>
>> That creates an odd situation where readonly and asymmetric visibility 
>> may only be combined "sometimes."  That is not deesireable.  The only 
>> way to combine them in their current form is to allow `protected 
>> protected(set)` only if readonly is in use, which is excessively 
>> complicated both to implement and to explain/document/use.
>>
>> We see two possible ways to resolve this conflict:
>>
>> 1. Relax the set-is-tighter restriction.  That would allow `protected 
>> protected(set)` etc. on any property.  It wouldn't be particularly 
>> useful unless readonly is being used, but it would be syntactically 
>> legal and behave as you'd expect.  We could still disallow "set is more 
>> permissive" combinations (eg, `private public(set)`), as those have no 
>> apparent use case.
>>
>> 2. Disallow readonly and asymmetric visibility being combined, because 
>> readonly already has a hard-coded implied asymmetric visibility.  This 
>> option removes some potential use cases (they would most likely drop 
>> the readonly), but has the upside that it's easier to re-allow at some 
>> point in the future.
>>
>> 3. Some other brilliant idea we've not thought of.
>>
>>
>> Both are viable approaches with pros and cons.  We're split on which 
>> way to go with this, so we throw it out to the group for feedback.  
>> Which approach would you favor, or do you have some other brilliant 
>> idea to square this circle?
>
>
> Thank you everyone for the feedback.  Based on this thread, we've made 
> two changes to the RFC:
>
> 1. We've moved readonly back to forbidden with a-viz for now.  I've 
> added a section to Future Scope where we really should sort this out in 
> the future, but we'll do that in the future when we can all focus on 
> the various nuances of just that piece.
>
> 2. I rewrote the section on __set to make it clearer.  That also 
> included Ilija and I digging into all the nuances that are already 
> present.  The text may still look a bit complex, but that's because the 
> existing logic is already complex with readonly.  Long story short, the 
> a-viz RFC does not change anything in the way __set works vis a vis 
> asymmetric visibility; it just inherits and continues what readonly 
> already started, so it's consistent.
>
> The PR should be updated in the next week or two with the latest 
> changes.  Baring any major need for change, we expect to call a vote 
> for it shortly after New Years.
>
> Thanks all.
>
> --Larry Garfield


One other update: Nicolas poked me off list to remind me that the RFC didn't 
mention inheritance at all.  Oops. :-)  The patch already has inheritance well 
handled and tested, it just wasn't described in the RFC.  I have added a 
section that documents the behavior.  Short version: You can continue to 
expand, but not contract, the visibility in child classes, but you can do it 
for get and set separately.  It's pretty much exactly what you'd expect it to 
do.

--Larry Garfield

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-30 Thread Larry Garfield
On Tue, Nov 29, 2022, at 11:25 PM, Stephen Reay wrote:

> Hi Larry,
>
> Thank you for clarifying the setter behaviour in more explicit terms, 
> but I have to say I’m quite disappointed in this continued “use the 
> logic of readonly to apply to something that is explicitly not 
> readonly” - this is even more stark now that you’ve explicitly made 
> them mutually exclusive behaviours.
>
> I’m generally very in favour of maintaining consistency, but this seems 
> like it’s using technical consistency as an excuse to justify 
> unintuitive behaviour that breaks consistency in another, much more 
> obvious way.
>
>
> Can you explain why it makes more sense to maintain consistency with 
> “readonly” than it does to maintain consistency with the existing 
> “__set()” behaviour for properties, particularly now that you’ve 
> indicated these features (asymmetric visibility and readonly) are 
> mutually exclusive? 
>
> While it’s stated multiple times that “readonly” introduced a limited 
> form of asymmetric visibility, and thus this is a continuation, in 
> terms of intuitiveness, the existing __set() rules are very easy to 
> comprehend even with readonly:
>
> - if the property is declared as public, __set() is never called; if 
> it’s declared as protected, __set is called when the property is 
> accessed from outside that class or it’s hierarchy. Yes, I know that 
> readonly imposes an implicit visibility difference - but that is 
> essentially an implementation detail, from the point of view of the 
> userland developer, it’s not a clear statement of intended behaviour on 
> their part, expressed through the code as written.
>
> For example, with `public readonly int $foo` it’s quite obvious why 
> __set() isn’t called, using the exiting well-understood logic: it’s a 
> public property. PHP applies a kind of asymmetric visibility to the 
> property behind the scenes, but that isn’t what the developer declared, 
> it’s the implementation. This behaviour matches that of regular, 
> non-readonly fields: when the field is declared public (or has implicit 
> public visibility) __set() is never called.
>
> If we make that field protected, __set() will be called when the 
> property is written to from outside the class, regardless of whether 
> it’s readonly or not.
>
>
> What you’re proposing changes that, in a way that is completely 
> unintuitive: when attempting to *write* data to a property that is 
> marked as protected(set), the __set() method will not be called.
>
>
> So please, can you explain to me why consistency with an implementation 
> detail of readonly properties is more important than consistency with 
> declared developer intention for regular properties via the magic 
> setter method?

There's a couple of reasons.

One, and arguably the most important, readonly and aviz being incompatible is, 
hopefully, a temporary situation.  There's some fiddly bits to work out 
design-wise, and based on earlier comments in the thread we're going to punt on 
that for now to avoid that dragging down the whole RFC.  I believe we 
absolutely should allow them together in the future (maybe in a later 8.3 RFC, 
maybe a future version, TBD), which means ensuring, now, that they are 
compatible in the future.  This approach involves the fewest future BC breaks.

Second, I wouldn't call the current behavior of readonly a mere implementation 
detail.  It's weird and unexpected, I'd agree, but only as a side effect of 
previous design decisions, some of which are even older than readonly.  But 
it's an observed behavior that code can rely on, and in some cases does.  For 
example:

https://peakd.com/hive-168588/@crell/php-tricks-lazy-public-readonly-properties

The "unset a declared property to force it through __get once" is a trick that 
some ORMs use extensively.  readonly just inherited that, leading to the 
current behavior: __set depends on the write/set visibility of the property and 
its settedness.  This RFC doesn't change anything there.  

The alternative would be to have __set called always for a non-public-set 
property.  However, that is a place for bugs, as you then can't not have a 
back-door way to publicly set a property even if it's declared private(set).  
(Or, you have to be very careful in your __set to avoid it.)  That is both 
inconsistent with the language today, and error prone.

Finally, we're planning to work in the near-future on property hooks (aka 
property accessors), which would allow per-property custom set routines.  That 
would largely remove the issue entirely, as the use of __set would go way down 
and you'd basically never have to use it with a declared property, fancy tricks 
or no, so this issue would never come up at all.

--Larry Garfield

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-30 Thread Larry Garfield
On Wed, Nov 30, 2022, at 4:02 AM, Claude Pache wrote:
>> Le 30 nov. 2022 à 02:27, Larry Garfield  a écrit :
>> 
>> On Tue, Nov 29, 2022, at 5:46 PM, Claude Pache wrote:
>> 
>>> In the RFC, section Permitted visibility 
>>> (https://wiki.php.net/rfc/asymmetric-visibility#permitted_visibility 
>>> ):
 The set visibility, if it differs from the main (get) visibility, MUST be 
 strictly lesser than the main visibility. That is, the set visibility may 
 only be protected or private. If the main visibility is protected, set 
 visibility may only be private. Any violation of this rule will result in 
 a compile time error.
 
>>> The first sentence does not forbid `public public(set)`, or `protected 
>>> protected(set)`, etc. (the `set` visibility does not differ from the 
>>> main visibility), but the rest of the paragraph does not allow it. That 
>>> should be clarified.
>> 
>> Er.  That's exactly what it says: "strictly lesser" than the main 
>> visibility.  The lines after are just restating it.  "public public(set)" is 
>> not allowed.
>
> As I understand the first sentence (what it says, not what you meant):
>
> “The set visibility, **if it differs from the main (get) visibility**, 
> {$some_restriction}.”
>
> In `public public(set)`, the set visibility does not differ from the 
> main/get visibility, therefore {$some_restriction} does not apply.
>
> My guess is that you wanted to say:
>
> “The set visibility, **if specified explicitly**, {$some_restriction}.”

Ahhh... I see what you're getting at.  Fair point, I'll adjust it.  Thanks.

--Larry Garfield

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-30 Thread Claude Pache



> Le 30 nov. 2022 à 02:27, Larry Garfield  a écrit :
> 
> On Tue, Nov 29, 2022, at 5:46 PM, Claude Pache wrote:
> 
>> In the RFC, section Permitted visibility 
>> (https://wiki.php.net/rfc/asymmetric-visibility#permitted_visibility 
>> ):
>>> The set visibility, if it differs from the main (get) visibility, MUST be 
>>> strictly lesser than the main visibility. That is, the set visibility may 
>>> only be protected or private. If the main visibility is protected, set 
>>> visibility may only be private. Any violation of this rule will result in a 
>>> compile time error.
>>> 
>> The first sentence does not forbid `public public(set)`, or `protected 
>> protected(set)`, etc. (the `set` visibility does not differ from the 
>> main visibility), but the rest of the paragraph does not allow it. That 
>> should be clarified.
> 
> Er.  That's exactly what it says: "strictly lesser" than the main visibility. 
>  The lines after are just restating it.  "public public(set)" is not allowed.

As I understand the first sentence (what it says, not what you meant):

“The set visibility, **if it differs from the main (get) visibility**, 
{$some_restriction}.”

In `public public(set)`, the set visibility does not differ from the main/get 
visibility, therefore {$some_restriction} does not apply.

My guess is that you wanted to say:

“The set visibility, **if specified explicitly**, {$some_restriction}.”

—Claude
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-30 Thread Stephen Reay


> On 30 Nov 2022, at 15:41, Alexandru Pătrănescu  wrote:
> 
> 
> On Wed, Nov 30, 2022, 05:25 Stephen Reay  > wrote:
> 
> 
> > On 30 Nov 2022, at 08:27, Larry Garfield  > > wrote:
> > 
> > On Tue, Nov 29, 2022, at 5:46 PM, Claude Pache wrote:
> > 
> >> In the RFC, section Permitted visibility 
> >> (https://wiki.php.net/rfc/asymmetric-visibility#permitted_visibility 
> >>  
> >>  >> >):
> >>> The set visibility, if it differs from the main (get) visibility, MUST be 
> >>> strictly lesser than the main visibility. That is, the set visibility may 
> >>> only be protected or private. If the main visibility is protected, set 
> >>> visibility may only be private. Any violation of this rule will result in 
> >>> a compile time error.
> >>> 
> >> The first sentence does not forbid `public public(set)`, or `protected 
> >> protected(set)`, etc. (the `set` visibility does not differ from the 
> >> main visibility), but the rest of the paragraph does not allow it. That 
> >> should be clarified.
> > 
> > Er.  That's exactly what it says: "strictly lesser" than the main 
> > visibility.  The lines after are just restating it.  "public public(set)" 
> > is not allowed.
> > 
> > (We may relax that in the future to make it compatible with readonly, but 
> > that's for later.)
> > 
> >> 
> >> (Because forbidding `public public(set)`, etc., makes it slightly more 
> >> cumbersome to explain the rules, I am slightly in favour not to forbid 
> >> it.)
> >> 
> >>> There is one exception, that of a private readonly property. That would 
> >>> technically expand to private private(set) readonly, which is allowed.
> >> 
> >> That sentence should be deleted, as `readonly` is now forbidden.
> > 
> > Good catch, fixed.  Thanks.
> > 
> > --Larry Garfield
> > 
> > -- 
> > PHP Internals - PHP Runtime Development Mailing List
> > To unsubscribe, visit: https://www.php.net/unsub.php 
> > 
> > 
> 
> Hi Larry,
> 
> Thank you for clarifying the setter behaviour in more explicit terms, but I 
> have to say I’m quite disappointed in this continued “use the logic of 
> readonly to apply to something that is explicitly not readonly” - this is 
> even more stark now that you’ve explicitly made them mutually exclusive 
> behaviours.
> 
> I’m generally very in favour of maintaining consistency, but this seems like 
> it’s using technical consistency as an excuse to justify unintuitive 
> behaviour that breaks consistency in another, much more obvious way.
> 
> 
> Can you explain why it makes more sense to maintain consistency with 
> “readonly” than it does to maintain consistency with the existing “__set()” 
> behaviour for properties, particularly now that you’ve indicated these 
> features (asymmetric visibility and readonly) are mutually exclusive? 
> 
> While it’s stated multiple times that “readonly” introduced a limited form of 
> asymmetric visibility, and thus this is a continuation, in terms of 
> intuitiveness, the existing __set() rules are very easy to comprehend even 
> with readonly:
> 
> - if the property is declared as public, __set() is never called; if it’s 
> declared as protected, __set is called when the property is accessed from 
> outside that class or it’s hierarchy. Yes, I know that readonly imposes an 
> implicit visibility difference - but that is essentially an implementation 
> detail, from the point of view of the userland developer, it’s not a clear 
> statement of intended behaviour on their part, expressed through the code as 
> written.
> 
> For example, with `public readonly int $foo` it’s quite obvious why __set() 
> isn’t called, using the exiting well-understood logic: it’s a public 
> property. PHP applies a kind of asymmetric visibility to the property behind 
> the scenes, but that isn’t what the developer declared, it’s the 
> implementation. This behaviour matches that of regular, non-readonly fields: 
> when the field is declared public (or has implicit public visibility) __set() 
> is never called.
> 
> If we make that field protected, __set() will be called when the property is 
> written to from outside the class, regardless of whether it’s readonly or not.
> 
> 
> What you’re proposing changes that, in a way that is completely unintuitive: 
> when attempting to *write* data to a property that is marked as 
> protected(set), the __set() method will not be called.
> 
> 
> So please, can you explain to me why consistency with an implementation 
> detail of readonly properties is more important than consistency with 
> declared developer intention for regular properties via the magic setter 
> method?
> 
> 
> Hey, Stephen, Larry,
> Just clarifying how I see it:
> 
> Practically, the asymmetric 

Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-30 Thread Alexandru Pătrănescu
On Wed, Nov 30, 2022, 05:25 Stephen Reay  wrote:

>
>
> > On 30 Nov 2022, at 08:27, Larry Garfield  wrote:
> >
> > On Tue, Nov 29, 2022, at 5:46 PM, Claude Pache wrote:
> >
> >> In the RFC, section Permitted visibility
> >> (https://wiki.php.net/rfc/asymmetric-visibility#permitted_visibility
> >> ):
> >>> The set visibility, if it differs from the main (get) visibility, MUST
> be strictly lesser than the main visibility. That is, the set visibility
> may only be protected or private. If the main visibility is protected, set
> visibility may only be private. Any violation of this rule will result in a
> compile time error.
> >>>
> >> The first sentence does not forbid `public public(set)`, or `protected
> >> protected(set)`, etc. (the `set` visibility does not differ from the
> >> main visibility), but the rest of the paragraph does not allow it. That
> >> should be clarified.
> >
> > Er.  That's exactly what it says: "strictly lesser" than the main
> visibility.  The lines after are just restating it.  "public public(set)"
> is not allowed.
> >
> > (We may relax that in the future to make it compatible with readonly,
> but that's for later.)
> >
> >>
> >> (Because forbidding `public public(set)`, etc., makes it slightly more
> >> cumbersome to explain the rules, I am slightly in favour not to forbid
> >> it.)
> >>
> >>> There is one exception, that of a private readonly property. That
> would technically expand to private private(set) readonly, which is allowed.
> >>
> >> That sentence should be deleted, as `readonly` is now forbidden.
> >
> > Good catch, fixed.  Thanks.
> >
> > --Larry Garfield
> >
> > --
> > PHP Internals - PHP Runtime Development Mailing List
> > To unsubscribe, visit: https://www.php.net/unsub.php
> >
>
> Hi Larry,
>
> Thank you for clarifying the setter behaviour in more explicit terms, but
> I have to say I’m quite disappointed in this continued “use the logic of
> readonly to apply to something that is explicitly not readonly” - this is
> even more stark now that you’ve explicitly made them mutually exclusive
> behaviours.
>
> I’m generally very in favour of maintaining consistency, but this seems
> like it’s using technical consistency as an excuse to justify unintuitive
> behaviour that breaks consistency in another, much more obvious way.
>
>
> Can you explain why it makes more sense to maintain consistency with
> “readonly” than it does to maintain consistency with the existing “__set()”
> behaviour for properties, particularly now that you’ve indicated these
> features (asymmetric visibility and readonly) are mutually exclusive?
>
> While it’s stated multiple times that “readonly” introduced a limited form
> of asymmetric visibility, and thus this is a continuation, in terms of
> intuitiveness, the existing __set() rules are very easy to comprehend even
> with readonly:
>
> - if the property is declared as public, __set() is never called; if it’s
> declared as protected, __set is called when the property is accessed from
> outside that class or it’s hierarchy. Yes, I know that readonly imposes an
> implicit visibility difference - but that is essentially an implementation
> detail, from the point of view of the userland developer, it’s not a clear
> statement of intended behaviour on their part, expressed through the code
> as written.
>
> For example, with `public readonly int $foo` it’s quite obvious why
> __set() isn’t called, using the exiting well-understood logic: it’s a
> public property. PHP applies a kind of asymmetric visibility to the
> property behind the scenes, but that isn’t what the developer declared,
> it’s the implementation. This behaviour matches that of regular,
> non-readonly fields: when the field is declared public (or has implicit
> public visibility) __set() is never called.
>
> If we make that field protected, __set() will be called when the property
> is written to from outside the class, regardless of whether it’s readonly
> or not.
>
>
> What you’re proposing changes that, in a way that is completely
> unintuitive: when attempting to *write* data to a property that is marked
> as protected(set), the __set() method will not be called.
>
>
> So please, can you explain to me why consistency with an implementation
> detail of readonly properties is more important than consistency with
> declared developer intention for regular properties via the magic setter
> method?
>
>
Hey, Stephen, Larry,
Just clarifying how I see it:

Practically, the asymmetric visibility for properties is not more or less
than asymmetric write-access for properties.
That is what is implemented, that is what other languages have as well and
this is what's needed.
Of course, except for relation with __set(), unset() and other php
specials, it wouldn't make a difference.

If you think it like this, that property is actually visible but only there
is a restriction on writing it, you would probably agree that 

Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-29 Thread Stephen Reay



> On 30 Nov 2022, at 08:27, Larry Garfield  wrote:
> 
> On Tue, Nov 29, 2022, at 5:46 PM, Claude Pache wrote:
> 
>> In the RFC, section Permitted visibility 
>> (https://wiki.php.net/rfc/asymmetric-visibility#permitted_visibility 
>> ):
>>> The set visibility, if it differs from the main (get) visibility, MUST be 
>>> strictly lesser than the main visibility. That is, the set visibility may 
>>> only be protected or private. If the main visibility is protected, set 
>>> visibility may only be private. Any violation of this rule will result in a 
>>> compile time error.
>>> 
>> The first sentence does not forbid `public public(set)`, or `protected 
>> protected(set)`, etc. (the `set` visibility does not differ from the 
>> main visibility), but the rest of the paragraph does not allow it. That 
>> should be clarified.
> 
> Er.  That's exactly what it says: "strictly lesser" than the main visibility. 
>  The lines after are just restating it.  "public public(set)" is not allowed.
> 
> (We may relax that in the future to make it compatible with readonly, but 
> that's for later.)
> 
>> 
>> (Because forbidding `public public(set)`, etc., makes it slightly more 
>> cumbersome to explain the rules, I am slightly in favour not to forbid 
>> it.)
>> 
>>> There is one exception, that of a private readonly property. That would 
>>> technically expand to private private(set) readonly, which is allowed.
>> 
>> That sentence should be deleted, as `readonly` is now forbidden.
> 
> Good catch, fixed.  Thanks.
> 
> --Larry Garfield
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
> 

Hi Larry,

Thank you for clarifying the setter behaviour in more explicit terms, but I 
have to say I’m quite disappointed in this continued “use the logic of readonly 
to apply to something that is explicitly not readonly” - this is even more 
stark now that you’ve explicitly made them mutually exclusive behaviours.

I’m generally very in favour of maintaining consistency, but this seems like 
it’s using technical consistency as an excuse to justify unintuitive behaviour 
that breaks consistency in another, much more obvious way.


Can you explain why it makes more sense to maintain consistency with “readonly” 
than it does to maintain consistency with the existing “__set()” behaviour for 
properties, particularly now that you’ve indicated these features (asymmetric 
visibility and readonly) are mutually exclusive? 

While it’s stated multiple times that “readonly” introduced a limited form of 
asymmetric visibility, and thus this is a continuation, in terms of 
intuitiveness, the existing __set() rules are very easy to comprehend even with 
readonly:

- if the property is declared as public, __set() is never called; if it’s 
declared as protected, __set is called when the property is accessed from 
outside that class or it’s hierarchy. Yes, I know that readonly imposes an 
implicit visibility difference - but that is essentially an implementation 
detail, from the point of view of the userland developer, it’s not a clear 
statement of intended behaviour on their part, expressed through the code as 
written.

For example, with `public readonly int $foo` it’s quite obvious why __set() 
isn’t called, using the exiting well-understood logic: it’s a public property. 
PHP applies a kind of asymmetric visibility to the property behind the scenes, 
but that isn’t what the developer declared, it’s the implementation. This 
behaviour matches that of regular, non-readonly fields: when the field is 
declared public (or has implicit public visibility) __set() is never called.

If we make that field protected, __set() will be called when the property is 
written to from outside the class, regardless of whether it’s readonly or not.


What you’re proposing changes that, in a way that is completely unintuitive: 
when attempting to *write* data to a property that is marked as protected(set), 
the __set() method will not be called.


So please, can you explain to me why consistency with an implementation detail 
of readonly properties is more important than consistency with declared 
developer intention for regular properties via the magic setter method?



Cheers

Stephen 

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-29 Thread Larry Garfield
On Tue, Nov 29, 2022, at 5:46 PM, Claude Pache wrote:

> In the RFC, section Permitted visibility 
> (https://wiki.php.net/rfc/asymmetric-visibility#permitted_visibility 
> ):
>> The set visibility, if it differs from the main (get) visibility, MUST be 
>> strictly lesser than the main visibility. That is, the set visibility may 
>> only be protected or private. If the main visibility is protected, set 
>> visibility may only be private. Any violation of this rule will result in a 
>> compile time error.
>> 
> The first sentence does not forbid `public public(set)`, or `protected 
> protected(set)`, etc. (the `set` visibility does not differ from the 
> main visibility), but the rest of the paragraph does not allow it. That 
> should be clarified.

Er.  That's exactly what it says: "strictly lesser" than the main visibility.  
The lines after are just restating it.  "public public(set)" is not allowed.

(We may relax that in the future to make it compatible with readonly, but 
that's for later.)

>
> (Because forbidding `public public(set)`, etc., makes it slightly more 
> cumbersome to explain the rules, I am slightly in favour not to forbid 
> it.)
>
>> There is one exception, that of a private readonly property. That would 
>> technically expand to private private(set) readonly, which is allowed.
>
> That sentence should be deleted, as `readonly` is now forbidden.

Good catch, fixed.  Thanks.

--Larry Garfield

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-29 Thread Claude Pache


> Le 29 nov. 2022 à 21:29, Larry Garfield  a écrit :
> 
> 
> Thank you everyone for the feedback.  Based on this thread, we've made two 
> changes to the RFC:
> 
> 1. We've moved readonly back to forbidden with a-viz for now.  I've added a 
> section to Future Scope where we really should sort this out in the future, 
> but we'll do that in the future when we can all focus on the various nuances 
> of just that piece.
> 
> 2. I rewrote the section on __set to make it clearer.  That also included 
> Ilija and I digging into all the nuances that are already present.  The text 
> may still look a bit complex, but that's because the existing logic is 
> already complex with readonly.  Long story short, the a-viz RFC does not 
> change anything in the way __set works vis a vis asymmetric visibility; it 
> just inherits and continues what readonly already started, so it's consistent.
> 
> The PR should be updated in the next week or two with the latest changes.  
> Baring any major need for change, we expect to call a vote for it shortly 
> after New Years.
> 
> Thanks all.
> 
> --Larry Garfield
> 

Hi,

In the RFC, section Permitted visibility 
(https://wiki.php.net/rfc/asymmetric-visibility#permitted_visibility 
):
> The set visibility, if it differs from the main (get) visibility, MUST be 
> strictly lesser than the main visibility. That is, the set visibility may 
> only be protected or private. If the main visibility is protected, set 
> visibility may only be private. Any violation of this rule will result in a 
> compile time error.
> 
The first sentence does not forbid `public public(set)`, or `protected 
protected(set)`, etc. (the `set` visibility does not differ from the main 
visibility), but the rest of the paragraph does not allow it. That should be 
clarified.

(Because forbidding `public public(set)`, etc., makes it slightly more 
cumbersome to explain the rules, I am slightly in favour not to forbid it.)

> There is one exception, that of a private readonly property. That would 
> technically expand to private private(set) readonly, which is allowed.

That sentence should be deleted, as `readonly` is now forbidden.

—Claude

Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-29 Thread Larry Garfield
On Sun, Nov 13, 2022, at 2:08 PM, Larry Garfield wrote:
> Hi folks.  Ilija is nearly done with the implementation for asymmetric 
> visibility and flushing out edge cases, but we've run into one design 
> question we'd like feedback on.
>
> There's two design decisions we've made at this point, both of which we 
> think are logical and reasonable:
>
> 1. If specified, the set visibility must be tighter than the get 
> visibility.  So `protected protected(set)` and `protected public(set)` 
> are not permitted, for instance.
>
> 2. `readonly` is a "write once" flag that may be combined with 
> asymmetric visibility.  If no set visibility is specified, `readoly` 
> implies `private(set)`, but a different set visibility may also be 
> provided.
>
> These are both reasonable rules.  However, it creates a conflict.  
> Specifically, in the following cases:
>
> public public(set) readonly string $foo
>
> protected protected(set) readonly string $foo
>
> These would be the only way to have a non-private-set readonly 
> property.  While the first is in practice quite unlikely, the second 
> has valid use cases.  (In particular, a base class that provides 
> properties expected to be set by a child constructor, and then used by 
> a method in the parent class.)  However, it would not be allowed under 
> the rules above.  Working around it would require specifying `public 
> protected(set) readonly...`, which means exposing a property that 
> likely should not be exposed.
>
> That creates an odd situation where readonly and asymmetric visibility 
> may only be combined "sometimes."  That is not deesireable.  The only 
> way to combine them in their current form is to allow `protected 
> protected(set)` only if readonly is in use, which is excessively 
> complicated both to implement and to explain/document/use.
>
> We see two possible ways to resolve this conflict:
>
> 1. Relax the set-is-tighter restriction.  That would allow `protected 
> protected(set)` etc. on any property.  It wouldn't be particularly 
> useful unless readonly is being used, but it would be syntactically 
> legal and behave as you'd expect.  We could still disallow "set is more 
> permissive" combinations (eg, `private public(set)`), as those have no 
> apparent use case.
>
> 2. Disallow readonly and asymmetric visibility being combined, because 
> readonly already has a hard-coded implied asymmetric visibility.  This 
> option removes some potential use cases (they would most likely drop 
> the readonly), but has the upside that it's easier to re-allow at some 
> point in the future.
>
> 3. Some other brilliant idea we've not thought of.
>
>
> Both are viable approaches with pros and cons.  We're split on which 
> way to go with this, so we throw it out to the group for feedback.  
> Which approach would you favor, or do you have some other brilliant 
> idea to square this circle?


Thank you everyone for the feedback.  Based on this thread, we've made two 
changes to the RFC:

1. We've moved readonly back to forbidden with a-viz for now.  I've added a 
section to Future Scope where we really should sort this out in the future, but 
we'll do that in the future when we can all focus on the various nuances of 
just that piece.

2. I rewrote the section on __set to make it clearer.  That also included Ilija 
and I digging into all the nuances that are already present.  The text may 
still look a bit complex, but that's because the existing logic is already 
complex with readonly.  Long story short, the a-viz RFC does not change 
anything in the way __set works vis a vis asymmetric visibility; it just 
inherits and continues what readonly already started, so it's consistent.

The PR should be updated in the next week or two with the latest changes.  
Baring any major need for change, we expect to call a vote for it shortly after 
New Years.

Thanks all.

--Larry Garfield

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-24 Thread Larry Garfield
On Sun, Nov 20, 2022, at 7:20 AM, Dan Ackroyd wrote:
> Hi Larry,
>
> Regarding the syntax, up until now PHP has only supported the letters
> a-z and underscore in keywords.
>
> I realise this is an aesthetic thing, but "private(set)" looks like a
> function to me, and not a keyword. I saw the previous poll, and it
> didn't include options for either protected_set/private_set or
> protectedset/privateset.
>
> Was there a technical reason for excluding them as an option?

Not in particular.  We originally proposed `private(set)` because that's what 
Swift uses.  In the discussion people proposed several alternatives that I put 
into the poll, but `private_set` wasn't one of them.  Although several people 
said they were opposed to parens in the keyword, the two options that had 
parens (`private(set)` and `pubilc(set: private)`) were the leaders for all 
rounds.  I was quite surprised at that, personally; I expected `private:set` to 
do a lot better under the circumstances.  But that's not how the poll played 
out.

--Larry Garfield

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-24 Thread Larry Garfield
On Tue, Nov 22, 2022, at 12:08 PM, Tim Düsterhus wrote:
> Hi
>
> On 11/14/22 21:02, Claude Pache wrote:
>> To clarify my position:
>> 
>> * The set visibility must be either more restrictive or of the same 
>> restriction level than the get visibility.
>> 
>> * When the set visibility is absent, it is inferred as following:
>>   * If `readonly` is present, the set visibility is `private` (as of 
>> today);
>>   * otherwise, the set visibility is the same as the get visibility 
>> (again, as of today).
>> 
>> * We don’t judge whether it is reasonable to write `protected protected(set) 
>> string $foo;` when you could just write `protected string $foo` for the same 
>> effect. Similarly, we don’t judge whether it is reasonable to write `public 
>> function()` when you could just write `function()` for the same effect. We 
>> leave it to coding styles and linters to decide whether the short form or 
>> the long form is preferred.
>> 
>
> I agree with that.
>
> --
>
> As I'm sending an email anyway: Larry, will there be a a new separate 
> discussion thread, once all the problems are resolved and once it's 
> clear what you propose? I just noticed the "Abbreviated Form" section in 
> the RFC 
> (https://wiki.php.net/rfc/asymmetric-visibility#abbreviated_form) which 
> I disagree with, which apparently was added in October, but I remember 
> an email letting readers know of the updated RFC. I didn't follow the 
> evolution of the RFC too closely, though, because I believed that it 
> still was in a somewhat early stage and because discussion is already 
> split into way-to-many threads and also the poll.
>
> Best regards
> Tim Düsterhus

Yes, once we make a decision on this point, I'll respond in this thread.  

The abbreviated form was part of the discussion earlier, and the syntax we 
settled on supported it, so it made sense to include.

I try to highlight on the list any time notable changes are made, even if I 
don't always have a detailed changelog.  Whether it makes sense to use the same 
thread or a new thread varies, and I'm absolutely certain others will make a 
different judgement call on that than I do.  I'm not aware of any standard 
convention around that, so until one exists I'll just continue making vaguely 
educated guesses on that front.

Given the timing, Ilija says he'd prefer to not call the vote until after the 
new year/holidays.  Feedback still welcome at this point but aside from edge 
cases like this thread's, I think we're pretty well set on the basic features.  
Baring any major change of direction expect the vote to be called in early 
January, probably.  Time permitting we're going to also start work on property 
hooks/accessors, which is the intended follow-on to this RFC.

--Larry Garfield

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-22 Thread Tim Düsterhus

Hi

On 11/14/22 21:02, Claude Pache wrote:

To clarify my position:

* The set visibility must be either more restrictive or of the same restriction 
level than the get visibility.

* When the set visibility is absent, it is inferred as following:
  * If `readonly` is present, the set visibility is `private` (as of today);
  * otherwise, the set visibility is the same as the get visibility (again, 
as of today).

* We don’t judge whether it is reasonable to write `protected protected(set) 
string $foo;` when you could just write `protected string $foo` for the same 
effect. Similarly, we don’t judge whether it is reasonable to write `public 
function()` when you could just write `function()` for the same effect. We 
leave it to coding styles and linters to decide whether the short form or the 
long form is preferred.



I agree with that.

--

As I'm sending an email anyway: Larry, will there be a a new separate 
discussion thread, once all the problems are resolved and once it's 
clear what you propose? I just noticed the "Abbreviated Form" section in 
the RFC 
(https://wiki.php.net/rfc/asymmetric-visibility#abbreviated_form) which 
I disagree with, which apparently was added in October, but I remember 
an email letting readers know of the updated RFC. I didn't follow the 
evolution of the RFC too closely, though, because I believed that it 
still was in a somewhat early stage and because discussion is already 
split into way-to-many threads and also the poll.


Best regards
Tim Düsterhus

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-21 Thread Rowan Tommins

On 20/11/2022 13:20, Dan Ackroyd wrote:

This is getting quite complicated.

I think unless someone makes a strong case for allowing the
combination of the two, disallowing them being combined is probably
the best choice.



I'm inclined to agree. There's going to be a lot to understand and agree 
on this RFC as it is, so if some edge cases can reasonably be defined as 
forbidden, we're less likely to end up regretting some detail.


Then if a good use case is identified, there can be a follow-up RFC, 
either within this release cycle, or in a future release.


Regards,

--
Rowan Tommins
[IMSoP]

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-20 Thread Dan Ackroyd
Hi Larry,

Regarding the syntax, up until now PHP has only supported the letters
a-z and underscore in keywords.

I realise this is an aesthetic thing, but "private(set)" looks like a
function to me, and not a keyword. I saw the previous poll, and it
didn't include options for either protected_set/private_set or
protectedset/privateset.

Was there a technical reason for excluding them as an option?

On Sun, 13 Nov 2022 at 20:09, Larry Garfield  wrote:
>
> That creates an odd situation where readonly and asymmetric visibility
> may only be combined "sometimes."...
>
> 2. Disallow readonly and asymmetric visibility being combined, because
> readonly already has a hard-coded implied asymmetric visibility.

This is getting quite complicated.

I think unless someone makes a strong case for allowing the
combination of the two, disallowing them being combined is probably
the best choice.

cheers
Dan
Ack

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-15 Thread Derick Rethans
On Mon, 14 Nov 2022, Ilija Tovilo wrote:

> Hi Derick
> 
> > > As I understand it, you’re suggesting that a property declared as
> > > `public protected(set)` would never trigger __set().
> >
> > I would think that that would be against our current practice, which is
> > easy enough to explain as "if the property isn't visible set,
> > then use __set()". I would argue that "protected(set)" marks a property
> > as invisible from a non-inherited class/method, and hence __set should
> > be called.
> 
> What you're describing does not match the readonly behavior.
> https://3v4l.org/X76pV
> 
> Readonly properties only call __set once they are explicitly unset.
> The same applies to __unset. I changed this in the asymmetric
> visibility implementation recently to match this behavior but the RFC
> has not been adjusted to reflect this yet.
> 
> AFAIK this behavior is there to allow calls to __set for certain edge
> cases. While not very intuitive it makes sense to stay consistent. If
> this behavior is undesirable we should change it in both places.

Now I have re-read the Assymetric Visibility RFC's "Interaction with 
__set" 
(https://wiki.php.net/rfc/asymmetric-visibility#interaction_with_set), 
I'm slightly more confused. Could you update that section, as what it 
currently states seems reasonable.

cheers,
Derick

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php

Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-14 Thread Claude Pache



>> 
>> 1. Relax the set-is-tighter restriction.  That would allow `protected 
>> protected(set)` etc. on any property.  It wouldn't be particularly useful 
>> unless readonly is being used, but it would be syntactically legal and 
>> behave as you'd expect.  We could still disallow "set is more permissive" 
>> combinations (eg, `private public(set)`), as those have no apparent use case.
> 
> I think that Option 1 is the most reasonable. The meaning of `public 
> public(set)` and `protected protected(set)` is straightforward; from a user 
> point-of-view, disallowing them seems more like “it is useless” than “it is 
> confusing”. Unless there are good technical reason to restrict it, we can 
> just leave to linting tools the care of reporting it.
> 
> —Claude
> 

To clarify my position:

* The set visibility must be either more restrictive or of the same restriction 
level than the get visibility.

* When the set visibility is absent, it is inferred as following:
 * If `readonly` is present, the set visibility is `private` (as of today);
 * otherwise, the set visibility is the same as the get visibility (again, 
as of today).

* We don’t judge whether it is reasonable to write `protected protected(set) 
string $foo;` when you could just write `protected string $foo` for the same 
effect. Similarly, we don’t judge whether it is reasonable to write `public 
function()` when you could just write `function()` for the same effect. We 
leave it to coding styles and linters to decide whether the short form or the 
long form is preferred.

—Claude

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-14 Thread Larry Garfield
On Sun, Nov 13, 2022, at 4:08 PM, Deleu wrote:
>>
>>
>> This is untrue.  You can declare a private property identically in a
>> parent and child class, even readonly.  I'm doing this now in a project.
>> It works, but would be unnecessary if the parent's property were
>> protected(set).
>>
>> --Larry Garfield
>>
>
> I do understand the slight complexity here (perhaps stronger in terms of
> implementation), but my assumption was that if a property is private and
> "the set visibility must be tighter", PHP would never assume `private
> protected(set) readonly`. In other words, if `private readonly` then
> `private private(set) readonly`, therefore nothing changes. You can keep
> the use of disjointed variables in inheritance provided they're all
> private. The only concern is when a property is declared protected, which
> then evaluates to what I mentioned on the previous email.

I don't follow.  Right now, this is legal:

class P {
  protected readonly string $foo;

  public useFoo() {
if ($this->foo == 'beep') { ... }
  }
}

class C extends P {
  protected readonly string $foo;

  public function __construct(string $foo) {
$this->foo = $foo;
  }
}

The redeclaration of $foo is necessary because of the implicit private-set on 
readonly today.  I have code that does this.

If we go with options 1 or 4, then that could be simplified to:

class P {
  protected protected(set) readonly string $foo;

  public useFoo() {
if ($this->foo == 'beep') { ... }
  }
}

class C extends P {
  public function __construct(string $foo) {
$this->foo = $foo;
  }
}

This would not require "set is wider", just "set is the same".

If we changed readonly to be an implicit protected(set) instead of 
private(set), that would also resolve that use case but I do not know if that 
would cause other problems with code like the above.

> I'm also under the stated assumption that `public public(set) readonly` is
> not something needed to be supported.

I am not aware of any use cases for it, though if it technically becomes 
possible as a side effect of other changes I don't object.

--Larry Garfield

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-14 Thread Ilija Tovilo
Hi Derick

> > As I understand it, you’re suggesting that a property declared as
> > `public protected(set)` would never trigger __set().
>
> I would think that that would be against our current practice, which is
> easy enough to explain as "if the property isn't visible set,
> then use __set()". I would argue that "protected(set)" marks a property
> as invisible from a non-inherited class/method, and hence __set should
> be called.

What you're describing does not match the readonly behavior.
https://3v4l.org/X76pV

Readonly properties only call __set once they are explicitly unset.
The same applies to __unset. I changed this in the asymmetric
visibility implementation recently to match this behavior but the RFC
has not been adjusted to reflect this yet.

AFAIK this behavior is there to allow calls to __set for certain edge
cases. While not very intuitive it makes sense to stay consistent. If
this behavior is undesirable we should change it in both places.

Ilija

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-14 Thread Derick Rethans
On Mon, 14 Nov 2022, Stephen Reay wrote:

> As I understand it, you’re suggesting that a property declared as 
> `public protected(set)` would never trigger __set().

I would think that that would be against our current practice, which is 
easy enough to explain as "if the property isn't visible set, 
then use __set()". I would argue that "protected(set)" marks a property 
as invisible from a non-inherited class/method, and hence __set should 
be called.

cheers,
Derick

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php

Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-14 Thread Derick Rethans
On Sun, 13 Nov 2022, Larry Garfield wrote:

> There's two design decisions we've made at this point, both of which 
> we think are logical and reasonable:
> 
> 1. If specified, the set visibility must be tighter than the get 
> visibility.  So `protected protected(set)` and `protected public(set)` 
> are not permitted, for instance.
> 
> 2. `readonly` is a "write once" flag that may be combined with 
> asymmetric visibility.  If no set visibility is specified, `readoly` 
> implies `private(set)`, but a different set visibility may also be 
> provided.
> 
> These are both reasonable rules.  However, it creates a conflict.  
> Specifically, in the following cases:
> 
> public public(set) readonly string $foo
> 
> protected protected(set) readonly string $foo

Just to see if I understand this correctly, the "protected(set)" 
overwrites the implicit "private(set)" that "readonly" confers?

I think that alone is confusing.

> These would be the only way to have a non-private-set readonly 
> property.  While the first is in practice quite unlikely, the second 
> has valid use cases.  (In particular, a base class that provides 
> properties expected to be set by a child constructor, and then used by 
> a method in the parent class.)  However, it would not be allowed under 
> the rules above.  Working around it would require specifying `public 
> protected(set) readonly...`, which means exposing a property that 
> likely should not be exposed.
> 
> That creates an odd situation where readonly and asymmetric visibility 
> may only be combined "sometimes."  That is not deesireable.  The only 
> way to combine them in their current form is to allow `protected 
> protected(set)` only if readonly is in use, which is excessively 
> complicated both to implement and to explain/document/use.
> 
> We see two possible ways to resolve this conflict:
> 
> 1. Relax the set-is-tighter restriction.  That would allow `protected 
> protected(set)` etc. on any property.  It wouldn't be particularly 
> useful unless readonly is being used, but it would be syntactically 
> legal and behave as you'd expect.  We could still disallow "set is 
> more permissive" combinations (eg, `private public(set)`), as those 
> have no apparent use case.
> 
> 2. Disallow readonly and asymmetric visibility being combined, because 
> readonly already has a hard-coded implied asymmetric visibility.  
> This option removes some potential use cases (they would most likely 
> drop the readonly), but has the upside that it's easier to re-allow at 
> some point in the future.

I am in favour of this option 2. As I already think "protected 
protected(set) readonly" is a confusing thing to see. If I hadn't read 
this email, I wouldn't have understood the interacting between the 
"protected(set)" and "readonly".

cheers,
Derick

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-14 Thread Stephen Reay

> On 14 Nov 2022, at 03:08, Larry Garfield  wrote:
> 
> Hi folks.  Ilija is nearly done with the implementation for asymmetric 
> visibility and flushing out edge cases, but we've run into one design 
> question we'd like feedback on.
> 
> There's two design decisions we've made at this point, both of which we think 
> are logical and reasonable:
> 
> 1. If specified, the set visibility must be tighter than the get visibility.  
> So `protected protected(set)` and `protected public(set)` are not permitted, 
> for instance.
> 
> 2. `readonly` is a "write once" flag that may be combined with asymmetric 
> visibility.  If no set visibility is specified, `readoly` implies 
> `private(set)`, but a different set visibility may also be provided.
> 
> These are both reasonable rules.  However, it creates a conflict.  
> Specifically, in the following cases:
> 
> public public(set) readonly string $foo
> 
> protected protected(set) readonly string $foo
> 
> These would be the only way to have a non-private-set readonly property.  
> While the first is in practice quite unlikely, the second has valid use 
> cases.  (In particular, a base class that provides properties expected to be 
> set by a child constructor, and then used by a method in the parent class.)  
> However, it would not be allowed under the rules above.  Working around it 
> would require specifying `public protected(set) readonly...`, which means 
> exposing a property that likely should not be exposed.
> 
> That creates an odd situation where readonly and asymmetric visibility may 
> only be combined "sometimes."  That is not deesireable.  The only way to 
> combine them in their current form is to allow `protected protected(set)` 
> only if readonly is in use, which is excessively complicated both to 
> implement and to explain/document/use.
> 
> We see two possible ways to resolve this conflict:
> 
> 1. Relax the set-is-tighter restriction.  That would allow `protected 
> protected(set)` etc. on any property.  It wouldn't be particularly useful 
> unless readonly is being used, but it would be syntactically legal and behave 
> as you'd expect.  We could still disallow "set is more permissive" 
> combinations (eg, `private public(set)`), as those have no apparent use case.
> 
> 2. Disallow readonly and asymmetric visibility being combined, because 
> readonly already has a hard-coded implied asymmetric visibility.  This option 
> removes some potential use cases (they would most likely drop the readonly), 
> but has the upside that it's easier to re-allow at some point in the future.
> 
> 3. Some other brilliant idea we've not thought of.
> 
> 
> Both are viable approaches with pros and cons.  We're split on which way to 
> go with this, so we throw it out to the group for feedback.  Which approach 
> would you favor, or do you have some other brilliant idea to square this 
> circle?
> 
> 
> -- 
>  Larry Garfield
>  la...@garfieldtech.com
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
> 

Hi Larry,

I asked for some clarification / further thought about the magic 
getters/setters interaction of this RFC back when you announced it, and never 
heard much besides saying that you’re working on a consolidated response to the 
feedback, but I’ve not seen anything regarding what I’d asked about, and the 
RFC still seems to have the (IMO) confusing and inconsistent magic 
getters/setters interaction described.


As I understand it, you’re suggesting that a property declared as `public 
protected(set)` would never trigger __set().


While I understand that this is meant to “keep consistency with readonly”, I 
would imagine people would want to use native asymmetric visibility on objects 
that currently have protected (or private) properties that are accessed via 
magic getters and setters. I think it would be a natural assumption that 
asymmetric visibility would allow the user to remove the often boilerplate 
__get method, while maintaining the ability to have checks/other logic beyond 
simple type checks when a property is being set. Having the association of a 
*set* action tied to the *get* visibility is very unintuitive to me.

The impact of this “same” limitation on readonly properties is IMO greatly 
reduced, because of the nature of something being readonly. The ability to run 
some logic when writing to a property that’s otherwise readable is surely a 
concept that’s very common and easy to understand, it’s literally the next 
example after (1) “readonly” and (2)  “asymmetric visibility” in Nikita’s 
original property accessors RFC.

The stated reason (on both this and the readonly RFC) for not allowing __set() 
is "to avoid surprising behaviour”. To me, having a field marked as `public 
protected(set)` then not call __set() when setting a property from outside the 
class **is** the surprising behaviour.



Cheers

Stephen







Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-13 Thread Claude Pache



> 
> public public(set) readonly string $foo
> 
> protected protected(set) readonly string $foo
> 
> These would be the only way to have a non-private-set readonly property.  
> While the first is in practice quite unlikely, the second has valid use 
> cases.  

Both have use cases. Whether they are valid is quite subjective. (I am speaking 
as someone who suffer from the `match()` construct forbidding having both 
`default` and  some other `case` pointing to the same expression. That 
restriction seemed reasonable the time the feature was designed and voted.)

> 
> 1. Relax the set-is-tighter restriction.  That would allow `protected 
> protected(set)` etc. on any property.  It wouldn't be particularly useful 
> unless readonly is being used, but it would be syntactically legal and behave 
> as you'd expect.  We could still disallow "set is more permissive" 
> combinations (eg, `private public(set)`), as those have no apparent use case.

I think that Option 1 is the most reasonable. The meaning of `public 
public(set)` and `protected protected(set)` is straightforward; from a user 
point-of-view, disallowing them seems more like “it is useless” than “it is 
confusing”. Unless there are good technical reason to restrict it, we can just 
leave to linting tools the care of reporting it.

—Claude

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-13 Thread Deleu
On Sun, Nov 13, 2022 at 5:09 PM Larry Garfield 
wrote:

> Hi folks.  Ilija is nearly done with the implementation for asymmetric
> visibility and flushing out edge cases, but we've run into one design
> question we'd like feedback on.
>
> There's two design decisions we've made at this point, both of which we
> think are logical and reasonable:
>
> 1. If specified, the set visibility must be tighter than the get
> visibility.  So `protected protected(set)` and `protected public(set)` are
> not permitted, for instance.
>
> 2. `readonly` is a "write once" flag that may be combined with asymmetric
> visibility.  If no set visibility is specified, `readoly` implies
> `private(set)`, but a different set visibility may also be provided.


>
These are both reasonable rules.  However, it creates a conflict.
> Specifically, in the following cases:
>
To unsubscribe, visit: https://www.php.net/unsub.php
>
>
The more I think about this, the more it makes more sense (to me) to
simplify it even further;

1) The set visibility should be the same as the get visibility when one is
not provided. That is:

```
public $var -> public public(set) $var
protected $var -> protected protected(set) $var
private $var -> private private(set) $var
```

The explicit declaration of same visibility can be disallowed e.g. `public
public(set) $var` is not allowed, you must use `public $var` if you want
visibility symmetry. However, if it simplifies implementation to allow it,
why not? The behavior would already be in place anyway.

2) The readonly flag should no longer have an impact on the set visibility.
This is again a conceptual breaking change, but one that can even be fixed
with a SEARCH/REPLACE on a project scope. The "breaking change" is
categorized as follows:

The code `public readonly $var` used to be `public private(set) readonly
$var` should become `public public(set) readonly $var`
The code `protected readonly $var` used to be `protected private(set)
readonly $var` should become `protected protected(set) readonly $var`
The code `private readonly $var` should not have any change.

-- 
Marco Deleu


Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-13 Thread Deleu
>
>
> This is untrue.  You can declare a private property identically in a
> parent and child class, even readonly.  I'm doing this now in a project.
> It works, but would be unnecessary if the parent's property were
> protected(set).
>
> --Larry Garfield
>

I do understand the slight complexity here (perhaps stronger in terms of
implementation), but my assumption was that if a property is private and
"the set visibility must be tighter", PHP would never assume `private
protected(set) readonly`. In other words, if `private readonly` then
`private private(set) readonly`, therefore nothing changes. You can keep
the use of disjointed variables in inheritance provided they're all
private. The only concern is when a property is declared protected, which
then evaluates to what I mentioned on the previous email.

I'm also under the stated assumption that `public public(set) readonly` is
not something needed to be supported.

-- 
Marco Deleu


Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-13 Thread Larry Garfield
On Sun, Nov 13, 2022, at 3:50 PM, Deleu wrote:
>>
>>
>> 2. `readonly` is a "write once" flag that may be combined with asymmetric
>> visibility.  If no set visibility is specified, `readoly` implies
>> `private(set)`, but a different set visibility may also be provided.
>>
>> These are both reasonable rules.  However, it creates a conflict.
>> Specifically, in the following cases:
>>
>> public public(set) readonly string $foo
>>
>> protected protected(set) readonly string $foo
>>
>
> What if the implicit rule for `readonly` is changed into `protected(set)`?
> Let's run with this for a minute.
>
> 1- It's not truly a CODE breaking change. Right now if you have a
> `protected readonly` property, you're either calling the parent constructor
> or you're never making use of the variable, otherwise you're getting a
> Fatal Error.

This is untrue.  You can declare a private property identically in a parent and 
child class, even readonly.  I'm doing this now in a project.  It works, but 
would be unnecessary if the parent's property were protected(set).

--Larry Garfield

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-13 Thread Deleu
>
>
> 2. `readonly` is a "write once" flag that may be combined with asymmetric
> visibility.  If no set visibility is specified, `readoly` implies
> `private(set)`, but a different set visibility may also be provided.
>
> These are both reasonable rules.  However, it creates a conflict.
> Specifically, in the following cases:
>
> public public(set) readonly string $foo
>
> protected protected(set) readonly string $foo
>

What if the implicit rule for `readonly` is changed into `protected(set)`?
Let's run with this for a minute.

1- It's not truly a CODE breaking change. Right now if you have a
`protected readonly` property, you're either calling the parent constructor
or you're never making use of the variable, otherwise you're getting a
Fatal Error.
2- It's a CONCEPTUAL breaking change. If you've declared a `protected
readonly` property, you may expect anyone in the inheritance chain to be
calling your constructor. A new PHP version will warn you to either change
your property into `protected private(set) readonly` (Rector might be able
to do this) or accept the new behavior.
3- The two logical design choices can be kept.

To be honest, I think asymmetric visibility seems way over complex for very
little benefit, so I'm a bit against the entire feature, but if we were to
have them, it would really be nicer to not have crazy shenanigans involved.

-- 
Marco Deleu


Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-13 Thread Larry Garfield
On Sun, Nov 13, 2022, at 2:08 PM, Larry Garfield wrote:
> Hi folks.  Ilija is nearly done with the implementation for asymmetric 
> visibility and flushing out edge cases, but we've run into one design 
> question we'd like feedback on.
>
> There's two design decisions we've made at this point, both of which we 
> think are logical and reasonable:
>
> 1. If specified, the set visibility must be tighter than the get 
> visibility.  So `protected protected(set)` and `protected public(set)` 
> are not permitted, for instance.
>
> 2. `readonly` is a "write once" flag that may be combined with 
> asymmetric visibility.  If no set visibility is specified, `readoly` 
> implies `private(set)`, but a different set visibility may also be 
> provided.
>
> These are both reasonable rules.  However, it creates a conflict.  
> Specifically, in the following cases:
>
> public public(set) readonly string $foo
>
> protected protected(set) readonly string $foo
>
> These would be the only way to have a non-private-set readonly 
> property.  While the first is in practice quite unlikely, the second 
> has valid use cases.  (In particular, a base class that provides 
> properties expected to be set by a child constructor, and then used by 
> a method in the parent class.)  However, it would not be allowed under 
> the rules above.  Working around it would require specifying `public 
> protected(set) readonly...`, which means exposing a property that 
> likely should not be exposed.
>
> That creates an odd situation where readonly and asymmetric visibility 
> may only be combined "sometimes."  That is not deesireable.  The only 
> way to combine them in their current form is to allow `protected 
> protected(set)` only if readonly is in use, which is excessively 
> complicated both to implement and to explain/document/use.
>
> We see two possible ways to resolve this conflict:
>
> 1. Relax the set-is-tighter restriction.  That would allow `protected 
> protected(set)` etc. on any property.  It wouldn't be particularly 
> useful unless readonly is being used, but it would be syntactically 
> legal and behave as you'd expect.  We could still disallow "set is more 
> permissive" combinations (eg, `private public(set)`), as those have no 
> apparent use case.
>
> 2. Disallow readonly and asymmetric visibility being combined, because 
> readonly already has a hard-coded implied asymmetric visibility.  This 
> option removes some potential use cases (they would most likely drop 
> the readonly), but has the upside that it's easier to re-allow at some 
> point in the future.
>
> 3. Some other brilliant idea we've not thought of.
>
>
> Both are viable approaches with pros and cons.  We're split on which 
> way to go with this, so we throw it out to the group for feedback.  
> Which approach would you favor, or do you have some other brilliant 
> idea to square this circle?

Addendum: Ilija and I were talking past each other a bit, it seems.  Allowing 
`protected protected(set) readonly` only in the context of readonly would be 
straightforward to implement.  It's potentially not the easiest to explain that 
exception, but implementation-wise it's fine.

So that gives another viable option to consider:

4. Allow get and set visibility to be both set explicitly to the same level, 
iff in the presence of readonly.  So `protected protected(set) string $foo` is 
not allowed, but `protected protected(set) readonly string $foo` is allowed.  
This gives the most options and the least pointless syntax, but at the cost of 
having an exception that needs to be documented/explained/understood.

--Larry Garfield

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Asymmetric visibility

2022-09-02 Thread Karoly Negyesi
Hello,

public private(set) string $bar;

This is extremely weird to read and especially with the future operations,
very hard to understand too.

I would strongly recommend explicit over implicit and use instead

public(get) private(set) string $bar;

Now that's quite clear.

Thanks

NK


Re: [PHP-DEV] [RFC] Asymmetric visibility

2022-08-31 Thread Larry Garfield
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



Re: [PHP-DEV] [RFC] Asymmetric visibility

2022-08-31 Thread Claude Pache



> Le 31 août 2022 à 23:27, Tim Düsterhus  a écrit :
> 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.

Even if they manage to make the difference clear for the engine without 
resorting to “raw”, I think that it is important to have a syntactical marker 
for the sake of humans. Otherwise, someone would want to incrementally improve 
their class property, and at some unkwown point in time,  it becomes 
unexpectedly unusable for references and array mutations. 

—Claude 

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Asymmetric visibility

2022-08-31 Thread Tim Düsterhus

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.

Best regards
Tim Düsterhus

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Asymmetric visibility

2022-08-31 Thread Larry Garfield
On Fri, Aug 5, 2022, at 12:08 PM, Larry Garfield wrote:
> Ilija Tovilo and I are happy to present the first new RFC for PHP 8.3: 
> Asymmetric Visibility.
>
> https://wiki.php.net/rfc/asymmetric-visibility
>
> Details are in the RFC, but it's largely a copy of Swift's support for the 
> same.

Hi folks. Ilija and I have been discussing and experimenting extensively based 
on the feedback to the first draft.  Here's our thoughts so far, some 
additional data, and a request for feedback.  (These changes haven't been made 
to the RFC just yet, as there's outstanding questions for which we want 
feedback below.)

1. Rather than `readonly` being forbidden on asymmetric properties, it's better 
to redefine it as "write once, and if no `set` visibility is defined, make it 
private."  That would still allow for `public protected(set) readonly string 
$blah` (to work around existing limitations in `readonly`), but also more or 
less preserve the current syntax in a logical way.

2. Given that... we're not sure that it makes sense to have any visibility 
scope other than `get`/`set`.  `once` becomes unnecessary with that 
understanding of `readonly`, and we cannot think of any other examples that are 
not a stretch.  So that axis of extensibility is of minimal importance.

3. Since there has been some confusion, our goal *is* to implement property 
accessors in the future as a follow-on to this RFC.  However, conceptually 
property "hooks" and asymmetric visibility are separate features.  They also 
both have ample bikeshed potential.  That's why we're proposing them as two 
separate RFCs.  (Technically property hooks could also be done first, but this 
one is smaller.)  That said, it's become obvious that we cannot avoid 
discussing property hooks at the same time since the syntax does overlap.  So 
in the discussion below I will include property hooks, but deliberately gloss 
over parts that are not relevant right now.  Please humor me and do the same. 
:-)

4. In concept, there's two main syntactic models for property hooks/accessors: 
Javascript/Python style (annotated methods) and Swift/C# style (method-esque 
code blocks on properties).  We were trying to keep our options open and avoid 
a syntax that locks us into one or the other.  However, we've concluded that 
the annotated methods style just wouldn't work at all in a language with 
explicit types and visibility controls.  We've therefore made the executive 
decision that only the Swift/C# style is an option.

5. That leaves the basic question of "where to put the visibility," as Swift 
and C# put them in different places.  (There are other differences not relevant 
for now.)

Swift:

```swift
class User {
   public private(set) var first: String
   public private(set) var last: String
  
   public private(set) fullName: String {
   get { ... }
   set { ... }
   }
}
```

C#:

```csharp
class User {
   public string first { get; private set; }
   public string last { get; private set; }
  
   public string fullName {
   get { ... }
   private set { ... }
   }
}
```

The relevant difference is that in Swift, all visibility is on the left of the 
property while in C# it is split between the left and right.

The main argument for Swift-style: Keep everything in one place, and if there's 
no property hooks we don't even have to think about it.

The main argument for C#-style: It avoids repeating a keyword (eg, `set`) if 
using both features.

It *may* be possible to omit the `get` in the C# example above if it's just the 
default. Ilija is still working to figure that out.

## References make everything worse

One other caveat to consider is (naturally) references. A `get` hook cannot 
return by reference, as that would allow setting the value via its reference 
and bypassing a `set` hook.

A side effect of that restriction is that arrays cannot be modified in place on 
properties with a `get` hook.  That is, assuming the `$bar` property is an 
array that leverages the extra hooks above (by whatever syntax), the following 
is not possible:

```php
$f = new Foo();

$f->bar[] = 'beep';
```

That would require returning `$bar` by reference so that the `[]` operation 
could apply to it directly.  However, that then bypasses any restrictions 
imposed by a `set` hook (such as the values had to be integers).  The 
following, however, would be legal:

```php
$f = new Foo();

$b = $f->bar;

$b[] = 'beep';

$f->bar = $b;
```

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;
   

Re: [PHP-DEV] [RFC] Asymmetric visibility

2022-08-12 Thread MKS Archive
Hi Ollie,

> On Aug 8, 2022, at 6:12 AM, Ollie Read  wrote:
> 
> On Mon, Aug 8, 2022, at 3:54 AM, Mike Schinkel wrote:
>> 3.) I have concerns about the proposed methods isProtectedSet() and 
>> isPrivateSet().  
>> 
>> These names feels like we are asking if some thing "Set" is "Protected" or 
>> "Private" where no such "thing" exists in this context.  
>> 
>> In other words it reads as if you are asking "Is it a *protected* Set?" or 
>> "Is it a *private* Set?"  Such naming also does not relate to the Property 
>> itself which is what the prefix verb "is" is acting on.
>> 
>> I would propose instead we consider the following are these instead would be 
>> asking the *ability* to "Set" the Property is "Protected" or "Private" where 
>> The Property is again what the prefix verb "is" is acting on:
>> 
>> isSetProtected()
>> isSetPrivate()
>> isGetProtected(), and
>> isGetPrivate()
> 
> I feel almost as if we shouldn't pollute ReflectionProperty with these 
> additional methods but should instead have something like 
> ReflectionAsymmetricProperty, which would in turn extend ReflectionProperty. 

On my 3rd point that you quoted my primary concern was that I felt the RFC 
solution of "isSet()" was hard to reason about but my own suggestion 
almost incidental. I felt if I voiced my concerns then it would be incumbent 
upon me to at least suggest an alternative.

OTOH, I'm not sure I would embrace yet another reflection class. I think that 
would make an already (IMO) too-complex reflection class hierarchy even more 
complex.

Maybe a better solution could be to add an optional $flags parameter to the 
existing is() methods, something like?

isPublic(ReflectionProperty::GETTABLE)
isProtected(ReflectionProperty::GETTABLE)
isPrivate(ReflectionProperty::GETTABLE)

isPublic(ReflectionProperty::SETTABLE)
isProtected(ReflectionProperty::SETTABLE)
isPrivate(ReflectionProperty::SETTABLE)

isPublic(ReflectionProperty::GETTABLE & ReflectionProperty::SETTABLE)
isProtected(ReflectionProperty::GETTABLE & ReflectionProperty::SETTABLE)
isPrivate(ReflectionProperty::GETTABLE & ReflectionProperty::SETTABLE)

#fwiw

-Mike

> I guess it depends on how it's handled. If all property handling is updated 
> so that "public int $number" is identical to "public:get public:set int 
> $number", there's no issue, but if we treat those with separate visibilities 
> to be additional, it probably makes sense to be somewhat separate.
> 
> While isGetProtected() is technically false for "public int $number", if it's 
> not inferred, it's semantically incorrect. A good example of this is 
> ReflectionMethod::getPrototype, which throws an exception if there's no 
> prototype. Although this is somewhat bizarre, it is at least a thing we do.
> 
> ---
> Best Regards,
> *Ollie Read*



Re: [PHP-DEV] [RFC] Asymmetric visibility

2022-08-11 Thread Mike Schinkel

> On Aug 11, 2022, at 7:38 PM, André Hänsel  wrote:
> 
> Nicolas Grekas wrote:
> 
>> But I'm also wondering about the use case where asymmetry would be
>> useful in practice now that we have readonly?
>> I voted against readonly at the time because it didn't address
>> cloning, and also because it deprives end-users vs code authors IMHO
>> (alike "final"). I would have very much prefered asymmetric
>> visibility back then. But now that we are here, what are the use cases?
> 
> Isn't it (obviously?) to have setters that ensure all invariants of the
> properties are met? I'd still rather have Property Accessors as
> described in https://wiki.php.net/rfc/property_accessors, but I think
> AV is a step in the right direction.
> 
> As for readonly, I don't understand why that exists at all.


For immutability. 

Here is one reference on immutability offered up by the google gods:

https://hackernoon.com/5-benefits-of-immutable-objects-worth-considering-for-your-next-project-f98e7e85b6ac
 


Immutability goes hand-in-hand with Functional Programming (FP.)  While PHP is 
not a functional programming language,  PHP developers can gain benefits from 
an FP style for which immutability is beneficial. 

Also from the google gods, if you are unfamiliar with FP:

https://alvinalexander.com/scala/fp-book/benefits-of-functional-programming/ 
 

Hope this helps.

-Mike

P.S. Also, the Internals list's very own Larry Garfield is a huge advocate for 
FP in PHP, voilà:

https://leanpub.com/thinking-functionally-in-php
https://www.garfieldtech.com/taxonomy/term/95


> Yes, it's
> good that readonly properties can only be set from within the class,
> but only once, so you get setters that throw when called a second time,
> which I think is very, VERY unexpected behavior. Calling them
> "readonly" is also somewhat misleading because of course the objects
> assigned to those "readonly" properties can still be mutated, they can
> just not be reassigned.
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
> 



RE: [PHP-DEV] [RFC] Asymmetric visibility

2022-08-11 Thread André Hänsel
 Nicolas Grekas wrote:

> But I'm also wondering about the use case where asymmetry would be
> useful in practice now that we have readonly?
> I voted against readonly at the time because it didn't address
> cloning, and also because it deprives end-users vs code authors IMHO
> (alike "final"). I would have very much prefered asymmetric
> visibility back then. But now that we are here, what are the use cases?

Isn't it (obviously?) to have setters that ensure all invariants of the
properties are met? I'd still rather have Property Accessors as
described in https://wiki.php.net/rfc/property_accessors, but I think
AV is a step in the right direction.

As for readonly, I don't understand why that exists at all. Yes, it's
good that readonly properties can only be set from within the class,
but only once, so you get setters that throw when called a second time,
which I think is very, VERY unexpected behavior. Calling them
"readonly" is also somewhat misleading because of course the objects
assigned to those "readonly" properties can still be mutated, they can
just not be reassigned.

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Asymmetric visibility

2022-08-11 Thread Larry Garfield
On Thu, Aug 11, 2022, at 8:48 AM, Nicolas Grekas wrote:
>> Ilija Tovilo and I are happy to present the first new RFC for PHP 8.3:
>> Asymmetric Visibility.
>>
>> https://wiki.php.net/rfc/asymmetric-visibility
>>
>> Details are in the RFC, but it's largely a copy of Swift's support for the
>> same.
>>
>
> Thank you Larry and Ilija for this RFC.
>
> After reading it, I'm wondering about inheritance rules. What would be the
> rules when redeclaring an existing asymmetric property in a child class?
> The RFC should mention them I believe.

Yeah, Ilija is working on that still, I believe.  I believe the plan is, as 
with properties now, to allow widening access but not narrowing.  static 
properties will also be supported, but that implementation is WIP.

> But I'm also wondering about the use case where asymmetry would be useful
> in practice now that we have readonly?
> I voted against readonly at the time because it didn't address cloning, and
> also because it deprives end-users vs code authors IMHO (alike "final"). I
> would have very much prefered asymmetric visibility back then. But now that
> we are here, what are the use cases? If it's cloning only, then I would
> very much prefer finding a way to fix it rather than providing two subtly
> different ways to achieve the same thing.
>
> Eg can't we allow __clone methods to bypass the readonly restrictions? The
> engine already handles "guards" when using magic property accessors. Can't
> we use something similar for clone?
>
> And if yes, what would remain of the motivations for the asymmetric RFC?
>
> Cheers,
> Nicolas

There's a couple of use cases I see off hand:

1) Cloneability, as you've noted.

2) Fixing inheritance with readonly.  Right now, readonly is only settable from 
private scope, not protected.  So child classes are SOL.

3) A property that is rebuild based on other properties.  Eg, public 
private(set) $fullName, which is updated internally whenever $o->setFirstName() 
or $o->setLastName() are called.  (Or with accessor hooks in the future, which 
is on the roadmap.)

There's likely others, too.

I would also have rather had AV in the first place rather than readonly, as 
readonly is now getting in the way. :-(  But there are things readonly cannot 
reasonably do, and that's made worse by bad assumptions that static analysis 
tools have made about its usage.

We're working on a response to some other points made, but want to get on the 
same page with some more details first.  Stay tuned for a follow up.

--Larry Garfield

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Asymmetric visibility

2022-08-11 Thread Nicolas Grekas
> Ilija Tovilo and I are happy to present the first new RFC for PHP 8.3:
> Asymmetric Visibility.
>
> https://wiki.php.net/rfc/asymmetric-visibility
>
> Details are in the RFC, but it's largely a copy of Swift's support for the
> same.
>

Thank you Larry and Ilija for this RFC.

After reading it, I'm wondering about inheritance rules. What would be the
rules when redeclaring an existing asymmetric property in a child class?
The RFC should mention them I believe.

But I'm also wondering about the use case where asymmetry would be useful
in practice now that we have readonly?
I voted against readonly at the time because it didn't address cloning, and
also because it deprives end-users vs code authors IMHO (alike "final"). I
would have very much prefered asymmetric visibility back then. But now that
we are here, what are the use cases? If it's cloning only, then I would
very much prefer finding a way to fix it rather than providing two subtly
different ways to achieve the same thing.

Eg can't we allow __clone methods to bypass the readonly restrictions? The
engine already handles "guards" when using magic property accessors. Can't
we use something similar for clone?

And if yes, what would remain of the motivations for the asymmetric RFC?

Cheers,
Nicolas


Re: [PHP-DEV] [RFC] Asymmetric visibility

2022-08-09 Thread juan carlos morales
Quite a feature to the language. Nice

I wonder if can be done using a different wording. If I can get an idea to
contribute I Will write again.

Keep it up!


  1   2   >