Re: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-07-01 Thread Erick de Azevedo Lima
Hey everyone.

Any news on this? I'm really excited about this one. =)

--
Erick de Azevedo Lima

Em ter., 30 de mai. de 2023 às 14:15, Larry Garfield 
escreveu:

>
>
> --
>   Larry Garfield
>   la...@garfieldtech.com
>
> On Mon, May 29, 2023, at 8:28 PM, Claude Pache wrote:
> >> Le 8 mai 2023 à 23:38, Larry Garfield  a écrit
> :
> >>
> >> Ilija Tovilo and I would like to offer another RFC for your
> consideration.  It's been a while in coming, and we've evolved the design
> quite a bit just in the last week so if you saw an earlier draft of it in
> the past few months, I would encourage you to read it over again to make
> sure we're all on the same page.  I'm actually pretty happy with where it
> ended up, even if it's not the original design.  This approach eliminates
> several hard-to-implement edge cases while still providing a lot of
> functionality in one package.
> >>
> >> https://wiki.php.net/rfc/property-hooks
> >>
> >
> > Hi,
> >
> > If I understand correctly, given:
> >
> >  >
> > class C {
> >
> > public int $someInt;
> >
> > public float $someFloat;
> >
> > public int $someIntWithHook {
> > get => $field;
> > set => $field = $value;
> > }
> >
> > public float $someFloatWithHook {
> > get => $field;
> > set => $field = $value;
> > }
> >
> > }
> > ?>
> >
> > we have:
> >
> >  > $obj = new C;
> > var_dump($obj->someInt = 42.0); // int(42)
> > var_dump($obj->someFloat = 42); // float(42)
> > ?>
> >
> > but:
> >
> >  > $obj = new C;
> > var_dump($obj->someIntWithHook = 42.0); // float(42)
> > var_dump($obj->someFloatWithHook = 42); // int(42)
> > ?>
> >
> > If I am correct, it means that the “This also implies that adding a set
> > hook to a property cannot change the result of the = operator”
> > statement is a bit too optimistic.
>
> We looked into this a bit; it's correct if you're in weak mode.  In strict
> mode, it applies only to $o->float = $anInt, as that's the only legal type
> coercion.  Still, you're right that it's not quite "cannot change", so I've
> adjusted the wording to better describe the edge cases.  The behavior is
> still the same as __set(), so we don't see a need to change it further.
>
> Thanks for the catch.
>
> --Larry Garfield
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
>
>


Re: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-05-30 Thread Larry Garfield



-- 
  Larry Garfield
  la...@garfieldtech.com

On Mon, May 29, 2023, at 8:28 PM, Claude Pache wrote:
>> Le 8 mai 2023 à 23:38, Larry Garfield  a écrit :
>> 
>> Ilija Tovilo and I would like to offer another RFC for your consideration.  
>> It's been a while in coming, and we've evolved the design quite a bit just 
>> in the last week so if you saw an earlier draft of it in the past few 
>> months, I would encourage you to read it over again to make sure we're all 
>> on the same page.  I'm actually pretty happy with where it ended up, even if 
>> it's not the original design.  This approach eliminates several 
>> hard-to-implement edge cases while still providing a lot of functionality in 
>> one package.
>> 
>> https://wiki.php.net/rfc/property-hooks
>> 
>
> Hi,
>
> If I understand correctly, given:
>
> 
> class C {
>
> public int $someInt;
>
> public float $someFloat;
>
> public int $someIntWithHook {
> get => $field;
> set => $field = $value;
> }
>
> public float $someFloatWithHook {
> get => $field;
> set => $field = $value;
> }
>
> }
> ?>
>
> we have:
>
>  $obj = new C;
> var_dump($obj->someInt = 42.0); // int(42)
> var_dump($obj->someFloat = 42); // float(42)
> ?>
>
> but:
>
>  $obj = new C;
> var_dump($obj->someIntWithHook = 42.0); // float(42)
> var_dump($obj->someFloatWithHook = 42); // int(42)
> ?>
>
> If I am correct, it means that the “This also implies that adding a set 
> hook to a property cannot change the result of the = operator” 
> statement is a bit too optimistic.

We looked into this a bit; it's correct if you're in weak mode.  In strict 
mode, it applies only to $o->float = $anInt, as that's the only legal type 
coercion.  Still, you're right that it's not quite "cannot change", so I've 
adjusted the wording to better describe the edge cases.  The behavior is still 
the same as __set(), so we don't see a need to change it further.

Thanks for the catch.

--Larry Garfield

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



Re: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-05-29 Thread Claude Pache



> Le 8 mai 2023 à 23:38, Larry Garfield  a écrit :
> 
> Ilija Tovilo and I would like to offer another RFC for your consideration.  
> It's been a while in coming, and we've evolved the design quite a bit just in 
> the last week so if you saw an earlier draft of it in the past few months, I 
> would encourage you to read it over again to make sure we're all on the same 
> page.  I'm actually pretty happy with where it ended up, even if it's not the 
> original design.  This approach eliminates several hard-to-implement edge 
> cases while still providing a lot of functionality in one package.
> 
> https://wiki.php.net/rfc/property-hooks
> 

Hi,

If I understand correctly, given:

 $field;
set => $field = $value;
}

public float $someFloatWithHook {
get => $field;
set => $field = $value;
}

}
?>

we have:

someInt = 42.0); // int(42)
var_dump($obj->someFloat = 42); // float(42)
?>

but:

someIntWithHook = 42.0); // float(42)
var_dump($obj->someFloatWithHook = 42); // int(42)
?>

If I am correct, it means that the “This also implies that adding a set hook to 
a property cannot change the result of the = operator” statement is a bit too 
optimistic.


—Claude

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



Re: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-05-20 Thread Erick de Azevedo Lima
I can't wait!

Especially because I'm heading a modernization of the systems in my
organization and my plan is to use the cutting edge PHP version for it.
Currently our internal "framework" uses PHP 7.4, but with a PHP 5.6 coding
style.
Again: I can't wait!

I can't do much but thank everyone who spends their time to make PHP evolve.
Thank you all!

Regards,
Erick

Em sex., 19 de mai. de 2023 às 17:48, Larry Garfield 
escreveu:

> On Mon, May 8, 2023, at 9:38 PM, Larry Garfield wrote:
> > Ilija Tovilo and I would like to offer another RFC for your
> > consideration.  It's been a while in coming, and we've evolved the
> > design quite a bit just in the last week so if you saw an earlier draft
> > of it in the past few months, I would encourage you to read it over
> > again to make sure we're all on the same page.  I'm actually pretty
> > happy with where it ended up, even if it's not the original design.
> > This approach eliminates several hard-to-implement edge cases while
> > still providing a lot of functionality in one package.
> >
> > https://wiki.php.net/rfc/property-hooks
>
> Hi folks.  Based on feedback we've made a few smaller changes to the RFC.
>
> Changelog:
>
> * The sections describing isset/unset and magic methods have been
> rewritten to be clearer.  Nothing changed in the actual behavior, it is now
> just explained better.
>
> * Contravariance on the "set" type is now enforced.  Ilija figured out how
> to make it work. :-)  That means a non-contravariant type on the set hook
> will now throw an error, as expected.
>
> * After extensive discussion with Nicolas Grekas, we've decided to allow
> references in a very narrow case.  Specifically, on a *virtual property*
> (one that has no inherent backing store), you may implement a `` hook
> instead of `get`, and the value it returns will be returned by reference,
> and may be captured using $foo =& $bar->baz;  We determined that it is a
> bit better for BC (in the rare cases that you actually want to get a
> reference to a property, you can, even if it requires a little more work),
> doesn't break anything else, and is consistent with the way `&__get`
> behaves.  __get/__set are basically "anonymous virtual properties", so now
> they behave the same way.  By the same token, setting by reference is still
> not allowed, which is also true for __set today.
>
> As there was no other interest in it stated, we're going to hold off on an
> `unset` hook at this time.  Given the earlier discussion I think there is a
> valid use case for it, so it would be a worthwhile follow up RFC in the
> future, but for the moment we want to keep it simple.
>
> There also doesn't seem to be much interest in specifying which hook gets
> the double-shortened syntax.  I can see the argument for it, but it would
> increase the typing in a common case for an unclear benefit, and only one
> person expressed any interest in it.  So we're not going to go that route.
>
> There's two items still pending.
>
> 1. Ilija is experimenting with the `parent::$prop::get()` syntax, to see
> if either the syntax or implementation can be simplified.  There may or may
> not be a small change here as a result, TBD.
>
> 2. Ilija still has to verify that foreach() can work with virtual
> properties as the RFC currently describes.  The implementation details are
> thornier than they seem, so that still needs some validation and testing.
>
> Assuming both of those get sorted out soon, we will probably call a vote
> around the end of the month, give or take.
>
> Cheers.
>
> --Larry Garfield
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
>
>


Re: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-05-19 Thread Larry Garfield
On Mon, May 8, 2023, at 9:38 PM, Larry Garfield wrote:
> Ilija Tovilo and I would like to offer another RFC for your 
> consideration.  It's been a while in coming, and we've evolved the 
> design quite a bit just in the last week so if you saw an earlier draft 
> of it in the past few months, I would encourage you to read it over 
> again to make sure we're all on the same page.  I'm actually pretty 
> happy with where it ended up, even if it's not the original design.  
> This approach eliminates several hard-to-implement edge cases while 
> still providing a lot of functionality in one package.
>
> https://wiki.php.net/rfc/property-hooks

Hi folks.  Based on feedback we've made a few smaller changes to the RFC.

Changelog:

* The sections describing isset/unset and magic methods have been rewritten to 
be clearer.  Nothing changed in the actual behavior, it is now just explained 
better.

* Contravariance on the "set" type is now enforced.  Ilija figured out how to 
make it work. :-)  That means a non-contravariant type on the set hook will now 
throw an error, as expected.

* After extensive discussion with Nicolas Grekas, we've decided to allow 
references in a very narrow case.  Specifically, on a *virtual property* (one 
that has no inherent backing store), you may implement a `` hook instead of 
`get`, and the value it returns will be returned by reference, and may be 
captured using $foo =& $bar->baz;  We determined that it is a bit better for BC 
(in the rare cases that you actually want to get a reference to a property, you 
can, even if it requires a little more work), doesn't break anything else, and 
is consistent with the way `&__get` behaves.  __get/__set are basically 
"anonymous virtual properties", so now they behave the same way.  By the same 
token, setting by reference is still not allowed, which is also true for __set 
today.

As there was no other interest in it stated, we're going to hold off on an 
`unset` hook at this time.  Given the earlier discussion I think there is a 
valid use case for it, so it would be a worthwhile follow up RFC in the future, 
but for the moment we want to keep it simple.

There also doesn't seem to be much interest in specifying which hook gets the 
double-shortened syntax.  I can see the argument for it, but it would increase 
the typing in a common case for an unclear benefit, and only one person 
expressed any interest in it.  So we're not going to go that route.

There's two items still pending.

1. Ilija is experimenting with the `parent::$prop::get()` syntax, to see if 
either the syntax or implementation can be simplified.  There may or may not be 
a small change here as a result, TBD.

2. Ilija still has to verify that foreach() can work with virtual properties as 
the RFC currently describes.  The implementation details are thornier than they 
seem, so that still needs some validation and testing.

Assuming both of those get sorted out soon, we will probably call a vote around 
the end of the month, give or take.

Cheers.

--Larry Garfield

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



Re: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-05-15 Thread Hendra Gunawan
> Secondary votes are generally discouraged.  I can see the argument for 
> wanting a short-short version of set, given how common the validation use 
> case is, but => is almost universally the "evaluates to" symbol, so using 
> that for a set operation rather than get just feels weirdly inconsistent.  If 
> there were a set-only shorthand, it should be something else.
>
> That said, the ideal for validation would probably be guard clauses, like 
> this, but that would be a completely different RFC for another time.
> ```
> function foo(string $name where strlen($name) < 10) { ... }
>
> class Foo {
>   public function __construct(
> public string $name where strlen($name) < 10;
>   ) {}
> }
> ```
```guard``` seems a subset feature of ```hook```, although you want to
expand its use case in parameter. Property and parameter are variable.
If ```guard``` can be implemented in both case as you write above,
theoretically  ```hook``` can be either. I will choose ```hook```
rather than ```guard``` to anticipate future expansion. Isn't it
better to choose one broad concept than many?

I found a contradiction here. Previously you said that:
> ... the problem with omitting the {} is that it creates yet another syntax 
> variant. That makes it harder for the parser, for static analyzers, for 
> user-space parsing tools like php-parser, etc. That's more work for everyone 
> for fairly little gain.

And here, you introduce a syntax variant. Is it really significant if
we introduce a new ```where``` keyword ```compared to the already used
```get``` keyword? I will clarify here in case there is
misunderstanding:
* If we have more than one hook per property, then the syntax will be
the same as proposed by RFC.
* If we have only one hook per property, than the syntax are:
```
public function __construct(
  public string $prop1 get => strtoupper($this->_prop1),
){}

public function __construct(
  public string $prop2 set => $field = strtolower($value),
){}

public function __construct(
  public string $prop3 get {
$temp = strtoupper($this->_prop1);
return substr($temp, 0, 10) . '...';
  },
){}

public function __construct(
  public string $prop4 set {
$temp = strtolower($value);
$field = substr($temp, 0, 10);
  },
){}
```
Note: Please ignore any error. The ending comma is actually part of
the parameter list, not a hook. So it becomes optional if the param is
only one or it is the last param.

All the examples are constructor property promotion, because that is
my only concern. Because the space is limited, the more consistent the
code, the better. If I have to write hooks outside CPP, I don't mind
using the other syntax. There's plenty of room to fill, and
consistency is tolerable.

Should we postpone the implementation of the shortest version?
Hopefully we have enough time to decide which one will be implemented
next.

>
> ... Ilija also noted to me off-list that you could also have a set hook that 
> throws an exception rather than just being null, which would also work to 
> prevent writes.

Such a coincidence. I was going to revise my code:
```
// cache once and freeze,
// and without additional hidden property
// in case asymmetric visibility in not implemented yet
public string $prop1 {
  get => $field ??= $this->heavyTask($this->propx, $prop->y);
  set => throw new Exception("prop1 is read only");
}
```

> I think an unset hook is a fine addition in the future.  The way the code is 
> implemented it should be straightforward to add.  However, it feels like 
> scope creep to include it right now, especially when there are workarounds 
> available.  If there's a clear consensus from voters to include it, though, 
> we can consider that.  (Meaning, anyone that would favor including an unset 
> hook now, speak up or we'll assume it's better to stick with just get/set for 
> now.)

+1 for including ```unset``` as part of this RFC.

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



Re: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-05-15 Thread Larry Garfield
On Mon, May 15, 2023, at 8:12 PM, Hendra Gunawan wrote:

>> For the second, the problem with omitting the {} is that it creates yet 
>> another syntax variant.  That makes it harder for the parser, for static 
>> analyzers, for user-space parsing tools like php-parser, etc.  That's more 
>> work for everyone for fairly little gain.
>
> Sad to read that. Making one of them as the shortest shorthand feels
> like a picky decision. Some people agree with ```get```. Some people
> will argue that ```set``` deserves more than ```get```. Personally, I
> choose ```set``` to be the shortest shorthand as it is more relevant
> with constructor property promotion and value object. Do we need a 2nd
> vote for this one?

Secondary votes are generally discouraged.  I can see the argument for wanting 
a short-short version of set, given how common the validation use case is, but 
=> is almost universally the "evaluates to" symbol, so using that for a set 
operation rather than get just feels weirdly inconsistent.  If there were a 
set-only shorthand, it should be something else.

That said, the ideal for validation would probably be guard clauses, like this, 
but that would be a completely different RFC for another time.

function foo(string $name where strlen($name) < 10) { ... }

class Foo {
  public function __construct(
public string $name where strlen($name) < 10;
  ) {}
}

>> What we really would need here is asymmetric visibility.  No set hook, but 
>> make the property private(set) so that trying to write to it gives an error, 
>> as it should.
>
> So if asymmetric visibility is implemented, will my code be this simple?
> ```
> // cache once and freeze,
> // and without additional hidden property
> public private(set) string $prop1 {
>   get => $field ??= $this->heavyTask($this->propx, $prop->y);
> }
> ```

If you don't want cache clearing, yes.  Ilija also noted to me off-list that 
you could also have a set hook that throws an exception rather than just being 
null, which would also work to prevent writes.

For clearing that cached value, I think an unset hook is probably the best way, 
with either approach.

>>  For cache clearing, the best way to do that is probably with an unset hook. 
>>  That's been omitted from the RFC for now for simplicity, but that sounds 
>> like it would be an argument to introduce it later.
>
> I was going to write about this one. IMO, why do we need to provide
> additional hidden properties, when we are able to store the cache
> directly into it? Obviously we need a ```unset``` hook.

I think an unset hook is a fine addition in the future.  The way the code is 
implemented it should be straightforward to add.  However, it feels like scope 
creep to include it right now, especially when there are workarounds available. 
 If there's a clear consensus from voters to include it, though, we can 
consider that.  (Meaning, anyone that would favor including an unset hook now, 
speak up or we'll assume it's better to stick with just get/set for now.)

--Larry Garfield

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



Re: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-05-15 Thread Hendra Gunawan
> (Also, when replying, please please remove duplicate names from the to/cc 
> line.  I just got double copies of everything in this thread this morning.  
> I'm on the list, I don't need to be CCed.)

Sorry about that. Not my habit before.

> For the second, the problem with omitting the {} is that it creates yet 
> another syntax variant.  That makes it harder for the parser, for static 
> analyzers, for user-space parsing tools like php-parser, etc.  That's more 
> work for everyone for fairly little gain.

Sad to read that. Making one of them as the shortest shorthand feels
like a picky decision. Some people agree with ```get```. Some people
will argue that ```set``` deserves more than ```get```. Personally, I
choose ```set``` to be the shortest shorthand as it is more relevant
with constructor property promotion and value object. Do we need a 2nd
vote for this one?

> Removing the {} entirely from all forms makes it harder to denote where the 
> list of hooks begins and ends.  They would probably have to be 
> comma-separated, like this:
>
> public string $foo
>   get { return $this->bar; },
>   set { $this->bar = $value; };
>
> Which I'd argue is harder to read anyway, because you have to be careful of 
> the very small , and ; marks.  The {} is just easier for humans to parse as 
> well as the machine.

Looks like it's not more simple compared to the other one.

> What we really would need here is asymmetric visibility.  No set hook, but 
> make the property private(set) so that trying to write to it gives an error, 
> as it should.

So if asymmetric visibility is implemented, will my code be this simple?
```
// cache once and freeze,
// and without additional hidden property
public private(set) string $prop1 {
  get => $field ??= $this->heavyTask($this->propx, $prop->y);
}
```

>  For cache clearing, the best way to do that is probably with an unset hook.  
> That's been omitted from the RFC for now for simplicity, but that sounds like 
> it would be an argument to introduce it later.

I was going to write about this one. IMO, why do we need to provide
additional hidden properties, when we are able to store the cache
directly into it? Obviously we need a ```unset``` hook.

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



Re: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-05-15 Thread Larry Garfield
On Mon, May 15, 2023, at 8:32 AM, Lynn wrote:

> It's starting to get crowded in object constructors. The following example
> is so much more readable and maintainable imo. Would it be possible to
> still add the quick assignment as a language feature? I'm personally not
> happy having property definitions in both the class body _and_ the
> constructor signature.
>
> ```php
> class User {
> private string $first;
> private string $last;
> public string $fullName {
> get => $this->first . ' ' . $this->last;
> set => [$this->first, $this->last] = explode(' ', $value, 2);
> }
>
> public function __construct($this->fullName) {}
> }
>
> // vs
>
> class User {
> private string $first;
> private string $last;
>
> public function __construct(
> public string $fullName {
> get => $this->first . ' ' . $this->last;
> set => [$this->first, $this->last] = explode(' ', $value, 2);
> }
> ) {}
> }
>
> // or
>
> class User {
> private string $first;
> private string $last;
> public string $fullName {
> get => $this->first . ' ' . $this->last;
> set => [$this->first, $this->last] = explode(' ', $value, 2);
> }
>
> public function __construct(string $fullName)
> {
> $this->fullName = $fullName;
> }
> }

The last version skips constructor promotion entirely, so will absolutely work. 
 For this case, that's frankly the best approach, since you're right, the 
constructor gets rather messy otherwise.

Changing the syntax and semantics for CPP itself (as in the first code block 
above) is considerably out of scope for this RFC.  I recall someone pointing 
out why double-declaring the property would cause problems, but I forget the 
reason.  In any case, another promotion syntax would be a topic for another 
RFC.  I don't recall off hand the reasons Nikita had for choosing the syntax 
that ended up being used.

--Larry Garfield

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



Re: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-05-15 Thread Larry Garfield
Missed one...

On Mon, May 15, 2023, at 8:14 AM, Hendra Gunawan wrote:

> Can the engine detect these logical errors?
> ```
> public string $fullName = "hendra gunawan" => $this->first . " " . 
> $this->last;
>
> // or with my proposal:
> public string $fullName = "hendra gunawan" get => $this->first . " " .
> $this->last;
>
> // or even this one:
> public string $fullName = "hendra gunawan" {
>   get => $this->first . " " . $this->last;
>   set => [$this->first, $this->last] = explode(" ", $value);
> ```
>
> Explanation:
> There is no automatic backing store value created to store the default value.
>
> Terima Kasih.

Those would be compile-time syntax errors, yes.  (Or possibly link time, if 
inheritance is involved, but still before execution time.)

--Larry Garfield

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



Re: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-05-15 Thread Larry Garfield
Consolidating all replies into a single message.  Please try to keep them 
together so it's easier to respond to.

(Also, when replying, please please remove duplicate names from the to/cc line. 
 I just got double copies of everything in this thread this morning.  I'm on 
the list, I don't need to be CCed.)

On Sun, May 14, 2023, at 11:41 PM, Hendra Gunawan wrote:

> Hi Larry.
>
> ```
> public string $fullName => $this->first . " " . $this->last;
> ```
> 1. Suppose that I forgot to declare ```$this->first```. Based on the
> "deprecate dynamic properties" proposal, will I get an error/warning?

Correct, it will behave the same as if you had a fullName() method that 
accessed an undefined $first property.  

> 2. The shorthand notations supported (the shortest one) creates
> impaired syntax, and not pretty to look at for constructor property
> promotion.
>
> ```
> public function __construct(
>   public string $prop1 => strtoupper($this->_prop1),
>   public string $prop2 {set => $field = strtolower($value);},
> ){}
> ```

Well, the first is not really valid anyway.  That creates a virtual property 
with no set hook, which when you pass a value to it in the constructor call 
will give an error that you are trying to write to a virtual property.  So 
that's already a non-issue.

For the second, the problem with omitting the {} is that it creates yet another 
syntax variant.  That makes it harder for the parser, for static analyzers, for 
user-space parsing tools like php-parser, etc.  That's more work for everyone 
for fairly little gain.

Removing the {} entirely from all forms makes it harder to denote where the 
list of hooks begins and ends.  They would probably have to be comma-separated, 
like this:

public string $foo 
  get { return $this->bar; }, 
  set { $this->bar = $value; };

Which I'd argue is harder to read anyway, because you have to be careful of the 
very small , and ; marks.  The {} is just easier for humans to parse as well as 
the machine.

> Suppose that I just want to cache once and freeze, and I don't want to
> create additional hidden property. Please make a judgement on the
> validity of this syntax:
> ```
> public string $prop1 {
>   get => $field ??= $this->heavyTask($this->propx, $prop->y);
>   set => null;
> }
> ```
>
> Explanation:
> * Since the ```get``` hook uses ```$field```, the engine will create a
> backing store value with name ```$prop1```, and will be filled at the
> first call only. The later call will use the already stored value.
> * Since no new value is assigned to ```$field``` in the ```set```
> hook, the value stored in ```$prop1``` is still the same as before.
> * Since any return statement will be discharged in ```set``` hook, the
> assignment chaining is safe to use and the value which is transferred
> is alway the rightmost value (not the value returned by the ```set```
> hook).
> ```
> $varx = $obj->prop1 = "hello";  // $varx value is "hello", and
> $obj->prop1 value is unchanged
> ```

An interesting approach.  It should work as you describe, but there's two 
reasons I would discourage it:

1. A "set that doesn't set" creates unexpected behavior for callers.  If I call 
set, I expect something to happen.  It would be rather confusing to call set 
and not set things.
2. It doesn't actually allow a cache clearing option.

What we really would need here is asymmetric visibility.  No set hook, but make 
the property private(set) so that trying to write to it gives an error, as it 
should.  For cache clearing, the best way to do that is probably with an unset 
hook.  That's been omitted from the RFC for now for simplicity, but that sounds 
like it would be an argument to introduce it later.  Asymmetric visibility 
would be the higher priority, though.

> But, this statement below is NOT ALWAYS correct for "cache once and freeze":
> ```
> public string $prop1 {
>   set => $field ??= $this->heavyTask($this->propx, $prop->y);
> }
> ```
> Explanation:
> * Since default ```get``` hook can be called before ```set``` hook,
> backing store value with name ```$prop1``` will still be empty.
> * Otherwise, I have to duplicate the body of the ```set``` hook into
> ```get``` hook to prevent an emptiness backing store.
>
> Please give a comment.
> Thanks.

Correct; while this syntax would compile, it would result in the value assigned 
to the property being ignored, and then the other heavyTask() value assigned to 
it, but that still wouldn't ensure it was available the first time you called 
`get`.  That's probably not what anyone wants.

It looks like you answered your own question on the interface point, so I'll 
leave that be.

--Larry Garfield

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



Re: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-05-15 Thread Hendra Gunawan
> If there is no forward compatibility consideration, can we simplify
> interface definition to this one?
> ```
> interface IFace
> {
>   public string $readable;
>   public string $writeable;
>   public string $both;
> }
> ```

After carefully reading the proposal again, I think I know the answer
for my own question.

Short answer: no, we still need ```{ get; }``` to enforce the implemented class.

There are two different things here:
1. enforcing the implemented class
2. enforcing the caller site

If there are only ordinary properties, then ```{ get; }``` is truly
useless at the moment. On the other hand, virtual properties need
rules to be enforced, since there is no default hook given to it.

Since PHP lacks method definition enforcement at the caller site, I
assume that property would suffer the same.

Since we don't know what type of property is in the caller site,
static analysis tools can benefit from ```{ get; }``` to produce a
warning that we should not assign value to the property. A more
complex check should be performed to the implemented class because the
property type can be determined directly (if i am not wrong).
```
interface IFace
{
  public string $readable1 { get; }
  public string $readable2 { get; }
}

class CX implements IFace {
  private string $_propx;

  public string $readable1;
  public string $readable2 {
get => $this->_propx;
set => $this->_propx = $value;
  }

  public function consumeIt(IFace $par) {
// these statements should trigger warning by SA tools
$par->readable1 = "hello";
$par->readable2 = "world";

// OK
$this->readable1 = "hello";

// this statement should trigger error by SA tools
$this->readable2 = "hello";
  }
}
```

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



Re: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-05-15 Thread Hendra Gunawan
> ```php
> class User {
> private string $first;
> private string $last;
> public string $fullName {
> get => $this->first . ' ' . $this->last;
> set => [$this->first, $this->last] = explode(' ', $value, 2);
> }
>
> public function __construct($this->fullName) {}
> }
> ```

Not entirely true, you created redundancy code for ```$fullName```.
This is why we created constructor property promotion: to eliminate
redundancy.

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



Re: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-05-15 Thread Lynn
On Mon, May 15, 2023 at 1:41 AM Hendra Gunawan 
wrote:

> 2. The shorthand notations supported (the shortest one) creates
> impaired syntax, and not pretty to look at for constructor property
> promotion.
>

It's starting to get crowded in object constructors. The following example
is so much more readable and maintainable imo. Would it be possible to
still add the quick assignment as a language feature? I'm personally not
happy having property definitions in both the class body _and_ the
constructor signature.

```php
class User {
private string $first;
private string $last;
public string $fullName {
get => $this->first . ' ' . $this->last;
set => [$this->first, $this->last] = explode(' ', $value, 2);
}

public function __construct($this->fullName) {}
}

// vs

class User {
private string $first;
private string $last;

public function __construct(
public string $fullName {
get => $this->first . ' ' . $this->last;
set => [$this->first, $this->last] = explode(' ', $value, 2);
}
) {}
}

// or

class User {
private string $first;
private string $last;
public string $fullName {
get => $this->first . ' ' . $this->last;
set => [$this->first, $this->last] = explode(' ', $value, 2);
}

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

```


Re: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-05-15 Thread Hendra Gunawan
On Tue, May 9, 2023 at 4:38 AM Larry Garfield  wrote:
>
> Ilija Tovilo and I would like to offer another RFC for your consideration.  
> It's been a while in coming, and we've evolved the design quite a bit just in 
> the last week so if you saw an earlier draft of it in the past few months, I 
> would encourage you to read it over again to make sure we're all on the same 
> page.  I'm actually pretty happy with where it ended up, even if it's not the 
> original design.  This approach eliminates several hard-to-implement edge 
> cases while still providing a lot of functionality in one package.
>
> https://wiki.php.net/rfc/property-hooks
>
> --
>   Larry Garfield
>   la...@garfieldtech.com

Hi Larry

Can the engine detect these logical errors?
```
public string $fullName = "hendra gunawan" => $this->first . " " . $this->last;

// or with my proposal:
public string $fullName = "hendra gunawan" get => $this->first . " " .
$this->last;

// or even this one:
public string $fullName = "hendra gunawan" {
  get => $this->first . " " . $this->last;
  set => [$this->first, $this->last] = explode(" ", $value);
```

Explanation:
There is no automatic backing store value created to store the default value.

Terima Kasih.

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



Re: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-05-14 Thread Hendra Gunawan
On Tue, May 9, 2023 at 4:38 AM Larry Garfield  wrote:
>
> Ilija Tovilo and I would like to offer another RFC for your consideration.  
> It's been a while in coming, and we've evolved the design quite a bit just in 
> the last week so if you saw an earlier draft of it in the past few months, I 
> would encourage you to read it over again to make sure we're all on the same 
> page.  I'm actually pretty happy with where it ended up, even if it's not the 
> original design.  This approach eliminates several hard-to-implement edge 
> cases while still providing a lot of functionality in one package.
>
> https://wiki.php.net/rfc/property-hooks
>
> --
>   Larry Garfield
>   la...@garfieldtech.com

Hi, Larry

```
interface IFace
{
  public string $readable { get; }
  public string $writeable { set; }
  public string $both { get; set; }
}
```
How important is ```{ get; }``` statement (and friends) in the interface?

Since PHP does not enforce method definition existence in caller site,
this code is valid (at least at compile time):
```
interface IA {
  // ...
}

interface IB {
  public function doIt(IA $par1);
}

class CA1 implements IA {
  // makeIt is not part of IA
  public function makeIt() {
echo " makeIt() is called";
  }
}

class CA2 implements IA {}

class CB implements IB {
  public function doit(IA $par1) {
// makeIt is not enforced to be invalid
$par1->makeit();
  }
}

$a1 = new CA1;
$a2 = new CA2;
$b = new CB;
$b->doIt($a1); // valid
$b->doIt($a2); // invalid at runtime
```

IMO, ```{ get; }``` (and friends) only useful if there are:
* definition existence enforcement or implemented asymmetric visibility
* AND no default hook implementation provided.

I assume that ```{ get; }``` do exist in the property accessors
proposal because there is no default hook implementation. Whether
there is already implemented property definition existence enforcement
or not, i don't know. If yes, then all things are in the right place.
If not, it feels like a half baked feature, just like the method was:
the error will pop up at runtime. The only positive value is ```{ get;
}``` can still be consumed by static analysis tools.
```
class CX {
  public function consumeIt(IFace $par) {
// this statement should trigger error
// produced by engine or SA tools
$par->readable = "hello";
  }
}
```

Things will be different with property hooks. Without definition
existence enforcement nor implemented asymmetric visibility, static
analysis tools will give misconception about unlisted hooks if there
is error/warning message.
```
class CX {
  public function consumeIt(IFace $par) {
// default hook is provided by engine
// any message is not relevant for this valid statement
$par->readable = "hello";
  }
}
```

If there is no forward compatibility consideration, can we simplify
interface definition to this one?
```
interface IFace
{
  public string $readable;
  public string $writeable;
  public string $both;
}
```

Thanks in advance.

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



Re: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-05-14 Thread Hendra Gunawan
On Tue, May 9, 2023 at 4:38 AM Larry Garfield  wrote:
>
> Ilija Tovilo and I would like to offer another RFC for your consideration.  
> It's been a while in coming, and we've evolved the design quite a bit just in 
> the last week so if you saw an earlier draft of it in the past few months, I 
> would encourage you to read it over again to make sure we're all on the same 
> page.  I'm actually pretty happy with where it ended up, even if it's not the 
> original design.  This approach eliminates several hard-to-implement edge 
> cases while still providing a lot of functionality in one package.
>
> https://wiki.php.net/rfc/property-hooks
>
> --
>   Larry Garfield
>   la...@garfieldtech.com
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
>

Hi Larry.

Suppose that I just want to cache once and freeze, and I don't want to
create additional hidden property. Please make a judgement on the
validity of this syntax:
```
public string $prop1 {
  get => $field ??= $this->heavyTask($this->propx, $prop->y);
  set => null;
}
```

Explanation:
* Since the ```get``` hook uses ```$field```, the engine will create a
backing store value with name ```$prop1```, and will be filled at the
first call only. The later call will use the already stored value.
* Since no new value is assigned to ```$field``` in the ```set```
hook, the value stored in ```$prop1``` is still the same as before.
* Since any return statement will be discharged in ```set``` hook, the
assignment chaining is safe to use and the value which is transferred
is alway the rightmost value (not the value returned by the ```set```
hook).
```
$varx = $obj->prop1 = "hello";  // $varx value is "hello", and
$obj->prop1 value is unchanged
```

But, this statement below is NOT ALWAYS correct for "cache once and freeze":
```
public string $prop1 {
  set => $field ??= $this->heavyTask($this->propx, $prop->y);
}
```
Explanation:
* Since default ```get``` hook can be called before ```set``` hook,
backing store value with name ```$prop1``` will still be empty.
* Otherwise, I have to duplicate the body of the ```set``` hook into
```get``` hook to prevent an emptiness backing store.

Please give a comment.
Thanks.

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



Re: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-05-14 Thread Hendra Gunawan
On Tue, May 9, 2023 at 4:38 AM Larry Garfield  wrote:
>
> Ilija Tovilo and I would like to offer another RFC for your consideration.  
> It's been a while in coming, and we've evolved the design quite a bit just in 
> the last week so if you saw an earlier draft of it in the past few months, I 
> would encourage you to read it over again to make sure we're all on the same 
> page.  I'm actually pretty happy with where it ended up, even if it's not the 
> original design.  This approach eliminates several hard-to-implement edge 
> cases while still providing a lot of functionality in one package.
>
> https://wiki.php.net/rfc/property-hooks
>
> --
>   Larry Garfield
>   la...@garfieldtech.com
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
>

Hi Larry.

```
public string $fullName => $this->first . " " . $this->last;
```
1. Suppose that I forgot to declare ```$this->first```. Based on the
"deprecate dynamic properties" proposal, will I get an error/warning?

2. The shorthand notations supported (the shortest one) creates
impaired syntax, and not pretty to look at for constructor property
promotion.

```
public function __construct(
  public string $prop1 => strtoupper($this->_prop1),
  public string $prop2 {set => $field = strtolower($value);},
){}
```

My suggestion is: use get/set keyword immediately after property
name/default value rather than "=>" or "{" without losing multiline
statements.
```
public function __construct(
  public string $prop1 get => strtoupper($this->_prop1),
  public string $prop2 set => $field = strtolower($value),
  public string $prop3 get {
$temp = strtoupper($this->_prop1);
return substr($temp, 0, 10) . '...';
  }
  public string $prop4 set {
$temp = strtolower($value);
$field = substr($temp, 0, 10);
  }
){}
```
This syntax is aligned with a single statement if/for/foreach.

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



Re: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-05-13 Thread Matthew Brown
>
> Regarding $field vs. $this->propName, there's a few reasons we went that
> route.


Overall I think this is a really good proposal, but you might want to
consider a second vote for that particular syntax.

`$field` vs `$this->propName` feels a little magical. It's a simpler magic
than actual magic methods — it's magic that static analysis tools can
quickly reason about (as they can with promoted properties).

But I can imagine developers coming across this particular syntax in a PR
and thinking "that looks like a bug".

I know it's a few extra keypresses, but I think $this->propName is easier
to scan, and more familiar (given this RFC introduces a lot of other new
syntax).


Re: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-05-10 Thread Larry Garfield
On Wed, May 10, 2023, at 11:35 AM, Robert Landers wrote:
>> Regarding $field vs. $this->propName, there's a few reasons we went that 
>> route.
>>
>> 1. It's shorter and less typing for what will be a common pattern.
>> 2. That makes it consistent between hook implementations.  In working on 
>> examples, I found many cases where I was adding basically the same line to 
>> multiple hooks on the same class.  Making the code easier to copy-paste 
>> seems like a win.
>> 3. It also will be helpful if hook packages are added in the future, as 
>> they'll need a more "generic" way to access the backing property.  (See 
>> Future Scope.)  Eg, "$field = someLogic($value)" applied to a dozen 
>> different properties; it wouldn't work if it was "$this->specificProperty = 
>> someLogic($value)".
>> 4. We're used to our eyes glossing over "$this->propName", as it's so 
>> common.  Having a separate name to mentally scan for to determine if a 
>> property is virtual or not seems like it will be helpful in practice.
>> 5. There's precedent for it: Kotlin has almost the same functionality as we 
>> describe here, and uses a `field` variable in the exact same way.
>>
>> So it's mainly an ergonomics argument rather than a technical one.  "Compile 
>> time macro" means it translates to the same AST as if you'd used 
>> $this->propName.  There's precedent for that.  Constructor Property 
>> Promotion works basically the same way.
>
> With using a common name for say, $value, open the door for a library
> of common hook implementations (eventually)?
>
> Maybe something like:
>
> class User {
>   // snip
>   public string $fullName { get => FancyLibrary\fullName(...) }
>   // snip
> }
>
> I could imagine something like this would be a huge boon to PHP if it
> automatically bound the closure.

$field is only available inside the hook itself, not inside functions called 
from it.  But that does mean you could do this instead:

class User {
  // snip
  public string $fullName { get => FancyLibrary\fullName($field) }
  // snip
}

Which, yes, should work fine.

If such a library actually became popular, that would be an argument to 
implement the "property hook packages" or "property traits" concept that Swift 
has, as noted in Future Scope.

--Larry Garfield

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



Re: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-05-10 Thread Robert Landers
> Regarding $field vs. $this->propName, there's a few reasons we went that 
> route.
>
> 1. It's shorter and less typing for what will be a common pattern.
> 2. That makes it consistent between hook implementations.  In working on 
> examples, I found many cases where I was adding basically the same line to 
> multiple hooks on the same class.  Making the code easier to copy-paste seems 
> like a win.
> 3. It also will be helpful if hook packages are added in the future, as 
> they'll need a more "generic" way to access the backing property.  (See 
> Future Scope.)  Eg, "$field = someLogic($value)" applied to a dozen different 
> properties; it wouldn't work if it was "$this->specificProperty = 
> someLogic($value)".
> 4. We're used to our eyes glossing over "$this->propName", as it's so common. 
>  Having a separate name to mentally scan for to determine if a property is 
> virtual or not seems like it will be helpful in practice.
> 5. There's precedent for it: Kotlin has almost the same functionality as we 
> describe here, and uses a `field` variable in the exact same way.
>
> So it's mainly an ergonomics argument rather than a technical one.  "Compile 
> time macro" means it translates to the same AST as if you'd used 
> $this->propName.  There's precedent for that.  Constructor Property Promotion 
> works basically the same way.

With using a common name for say, $value, open the door for a library
of common hook implementations (eventually)?

Maybe something like:

class User {
  // snip
  public string $fullName { get => FancyLibrary\fullName(...) }
  // snip
}

I could imagine something like this would be a huge boon to PHP if it
automatically bound the closure.

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



Re: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-05-09 Thread Larry Garfield
On Tue, May 9, 2023, at 5:46 PM, Larry Garfield wrote:


>> I have a bigger concern: the take on references contradicts with the intro
>> about BC breaks: turning a materialized property into virtual one would
>> break BC as far as refs are concerned. One idea to fix that: add a ref
>> hook, that must return a reference. If not implemented => Error when trying
>> to get-by-ref. This could also help solve the $foo->array[] case (including
>> the asym-visiblity issue).
>
> That might be possible.  The issue there is that the returned ref would 
> still be bypassing the get/set hooks, so you're just adding a way to 
> dance around the existing hook implementations, which is exactly what 
> we're trying to avoid.  Also, what would that hook even mean if used on 
> a virtual property?
>
> Moreover, in practice, getting a reference to a property is extremely 
> rare, with the exception of array writes.  I cannot recall the last 
> time I even saw some code get a reference to a property.  That's why we 
> felt comfortable just leaving it at is.  In an earlier version of the 
> RFC we had a way for properties to just disable references without 
> adding any hooks, but removed it on the grounds that it was not worth 
> the effort.

Addendum here: The RFC wasn't clear, in part because I wasn't clear, but the 
prohibition on [] on properties applies only on set.  On get, whatever array 
value is returned from the hook is just a boring array, which can then be 
dereferenced to look up a key.

I've updated the RFC accordingly to make it clearer what is and isn't allowed 
with arrays.

--Larry Garfield

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



Re: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-05-09 Thread Larry Garfield
On Mon, May 8, 2023, at 9:38 PM, Larry Garfield wrote:
> Ilija Tovilo and I would like to offer another RFC for your 
> consideration.  It's been a while in coming, and we've evolved the 
> design quite a bit just in the last week so if you saw an earlier draft 
> of it in the past few months, I would encourage you to read it over 
> again to make sure we're all on the same page.  I'm actually pretty 
> happy with where it ended up, even if it's not the original design.  
> This approach eliminates several hard-to-implement edge cases while 
> still providing a lot of functionality in one package.
>
> https://wiki.php.net/rfc/property-hooks

Thanks everyone for your feedback so far.  I'm going to collapse the replies 
into one message to reduce noise.

On Tue, May 9, 2023, at 7:57 AM, Tim Düsterhus wrote:

> (1) How does the set() hook interact with #[\SensitiveParameter]?

Internally, the hook is a method, so it should respect it the same way as any 
other method.  Viz, you should be able to write:

```
public string $foo {
  set ($[\SensitiveParameter] string $value) {
$field = strtolower($foo);
  }
}
```

I'll ask Ilija to add a test to confirm that.

> (2) How will a Stack Trace emitted from a hook look like? Please include 
> an example of the Exception::__toString() output or so.

I'll ask Ilija to add a test to his branch and link it here.

> (3) ReflectionProperty::getHook(): Will this throw if an invalid hook 
> name is given or will this return null?

Null if you ask for get/set and one doesn't exist.  Error if you ask for 
something other than "get" or "set".  We're still keeping it as a single 
method, though, to make supporting other hooks easier in the future if desired. 
 I've updated the RFC to clarify that.

> (4) The "Unaffected PHP Functionality" section is empty. It should 
> either be filled in or removed.

Removed.  I don't quite understand the purpose of that section. :-)

On Tue, May 9, 2023, at 9:54 AM, Nicolas Grekas wrote:

>- does set($value) { mean set(mixed $value) { or set(TypeFromProp
>$value) { ? I understand it would be the latter but it might be nice to
>clarify (unless I missed it)

Conceptually, I believe it means set(TypeFromProp $value).  Since at present 
that cannot be enforced, though, they're basically the same thing.  (If someone 
with more engine-fu than either of us wants to help enforce contravariant types 
in set, please speak up because we'd prefer to do so.)

>- function setFullName => ucfirst is not found in the "set" version

Yes it is.  Look at the end of the `set` line.

>- could parent::$x::set($x) be replaced by parent::$x = $x ? Same for
>the get variant? Why not if not?

There's a subtle but important distinction here.  parent::$x would suggest 
accessing the parent *property*, ie, its backing value, directly.  What is 
actually intended here is accessing the parent *hook*, ie, its equivalent to 
parent::setFoo($foo).  The property itself is already available as $field.

We're open to alternate syntaxes for accessing the parent accessor syntax if 
people have good (and easily implementable) suggestions.

>- readonly: could this be supported by materializing them, using the
>storage for memoization after first access? that'd be quite powerful

That was one of my early ideas, as it then became a cheap form of cached lazy 
property.  However, that then means there's no meaningful way to unset the 
cache.  In the end we decided that there were too many nooks and crannies to 
readonly to try and make sense of.  (The more I use it, the more I think 
readonly was a mistake and we should have gone straight to aviz.)

(As a side note, if we had aviz, then we could use the field itself as a cache 
by making writes private, like so:

public string $name => $field ??= $this->first . $this->last;

But right now that would also imply public-set, which we wouldn't want.  Aviz 
would solve that issue entirely.  Another reason aviz is an important and 
useful feature. :-) )

What a readonly flag on a set-only property means... I have no idea.  

>- I'm not sure we need ReflectionProperty::getHook('set')  when we can
>do getHooks()['set'] ?? null

The double-methods were mainly for consistency with the rest of the Reflection 
API, which tends to have both getFoo(): object and getFoos(): array options.  
It's no more redundant than the rest of Reflection.

>- What does ReflectionMethod::getName return on a hook? And getClosure?

Either "get" or some hashed string that includes "get".  I'm not sure off hand. 
 I'll have to check with Ilija.

>- Should we add ReflectionProperty::IS_VIRTUAL ?

Funny story.  I just asked Ilija this, and he said he already did add it for 
testing purpose but forgot to tell me. :-)  RFC updated.

>- I'm a bit surprised by the possibility of adding attributes to hooks.
>I'm not sure I see the use case and I think this might be confusing in
>addition to attributes on the 

RE: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-05-09 Thread Jeffrey Dafoe
> Ilija Tovilo and I would like to offer another RFC for your consideration.  
> It's
> been a while in coming, and we've evolved the design quite a bit just in the 
> last
> week so if you saw an earlier draft of it in the past few months, I would
> encourage you to read it over again to make sure we're all on the same page.
> I'm actually pretty happy with where it ended up, even if it's not the 
> original
> design.  This approach eliminates several hard-to-implement edge cases while
> still providing a lot of functionality in one package.
> 
> https://wiki.php.net/rfc/property-hooks

+1 from me, I've used it in C# and it makes for clean code and less boilerplate.

-Jeff

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



Re: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-05-09 Thread Erick de Azevedo Lima
It looks great!

Thank you so, so much. I've been wanting this for a long time. I have used
properties in C# and it's very useful. I'm reading this RFC since it was in
draft. =)
One thing that I did not understand was this piece of code:

class C {
public array $_names;
public string $names {
set {
$this->*_prop* = explode(',', $value); // *< Where this
"_prop" is coming from?*
}
}
}
$c = new C();
var_dump($c->names = 'Ilija,Larry'); // 'Ilija,Larry'
var_dump($c->_names); // ['Ilija', 'Larry']

Does "_prop" have any special meaning or is it just a typo?

Thanks one more time for this!

Regards,
Erick

Em ter., 9 de mai. de 2023 às 08:52, Dik Takken 
escreveu:

>
>
> On 08-05-2023 23:38, Larry Garfield wrote:
> > Ilija Tovilo and I would like to offer another RFC for your
> consideration.  It's been a while in coming, and we've evolved the design
> quite a bit just in the last week so if you saw an earlier draft of it in
> the past few months, I would encourage you to read it over again to make
> sure we're all on the same page.  I'm actually pretty happy with where it
> ended up, even if it's not the original design.  This approach eliminates
> several hard-to-implement edge cases while still providing a lot of
> functionality in one package.
> >
> > https://wiki.php.net/rfc/property-hooks
> >
>
> Thanks for all the work that has gone into this. It looks great. The
> ability to add properties to interfaces is also really nice.
>
> One thing that concerns me is the following: "the use of [] on any
> property (with or without a key) will result in a runtime error being
> thrown". While the intent of the RFC is to allow adding hooks without
> causing BC breaks, this detail does introduce a BC break. And the break
> may get introduced without realizing it.
>
> I'm not sure which solution would be best here: Just accept the
> limitations for arrays (same as for list properties in Python) or forbid
> the use of hooks for array properties? I'm leaning towards accepting the
> limitations, like Python does. Then it is up to the API designer to
> decide if a property hook is the right tool for the job or not.
>
> Regards,
> Dik
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
>
>


Re: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-05-09 Thread Benjamin Außenhofer
On Mon, May 8, 2023 at 11:38 PM Larry Garfield 
wrote:

> Ilija Tovilo and I would like to offer another RFC for your
> consideration.  It's been a while in coming, and we've evolved the design
> quite a bit just in the last week so if you saw an earlier draft of it in
> the past few months, I would encourage you to read it over again to make
> sure we're all on the same page.  I'm actually pretty happy with where it
> ended up, even if it's not the original design.  This approach eliminates
> several hard-to-implement edge cases while still providing a lot of
> functionality in one package.
>
> https://wiki.php.net/rfc/property-hooks


Thank you! Looks interesting, I will need to think about things before more
qualitative feedback.

An error maybe, the "class C" example in "Detailed Proposal > set" uses a
"$this->_prop", but probably meant to use $this->_names, since private
array $_names; is declared in the example.

I think $field should be its own "chapter". Its a central part of the
proposal that should be clarified early and so that readers don't
accidentally skip it.

I am also confused why $field exists when $this->propertyName works and why
its not recommended to be used. Is $field a reference? or does the "compile
time macro" part mean its replaced at compile time? Ifso, this feels
different to anything else PHP, i am leaning towards $this->propertyName if
there are no other compelling reasons why $field should be used.

>
>
> --
>   Larry Garfield
>   la...@garfieldtech.com
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
>
>


Re: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-05-09 Thread Dik Takken




On 08-05-2023 23:38, Larry Garfield wrote:

Ilija Tovilo and I would like to offer another RFC for your consideration.  
It's been a while in coming, and we've evolved the design quite a bit just in 
the last week so if you saw an earlier draft of it in the past few months, I 
would encourage you to read it over again to make sure we're all on the same 
page.  I'm actually pretty happy with where it ended up, even if it's not the 
original design.  This approach eliminates several hard-to-implement edge cases 
while still providing a lot of functionality in one package.

https://wiki.php.net/rfc/property-hooks



Thanks for all the work that has gone into this. It looks great. The 
ability to add properties to interfaces is also really nice.


One thing that concerns me is the following: "the use of [] on any 
property (with or without a key) will result in a runtime error being 
thrown". While the intent of the RFC is to allow adding hooks without 
causing BC breaks, this detail does introduce a BC break. And the break 
may get introduced without realizing it.


I'm not sure which solution would be best here: Just accept the 
limitations for arrays (same as for list properties in Python) or forbid 
the use of hooks for array properties? I'm leaning towards accepting the 
limitations, like Python does. Then it is up to the API designer to 
decide if a property hook is the right tool for the job or not.


Regards,
Dik

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



Re: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-05-09 Thread Nicolas Grekas
Ilija Tovilo and I would like to offer another RFC for your consideration.
> It's been a while in coming, and we've evolved the design quite a bit just
> in the last week so if you saw an earlier draft of it in the past few
> months, I would encourage you to read it over again to make sure we're all
> on the same page.  I'm actually pretty happy with where it ended up, even
> if it's not the original design.  This approach eliminates several
> hard-to-implement edge cases while still providing a lot of functionality
> in one package.
>
> https://wiki.php.net/rfc/property-hooks
>

Congrats for the RFC for property hooks, I like it all, including
abbreviated forms, $value as default name, etc.

Some notes:

   - does set($value) { mean set(mixed $value) { or set(TypeFromProp
   $value) { ? I understand it would be the latter but it might be nice to
   clarify (unless I missed it)
   - function setFullName => ucfirst is not found in the "set" version
   - could parent::$x::set($x) be replaced by parent::$x = $x ? Same for
   the get variant? Why not if not?
   - readonly: could this be supported by materializing them, using the
   storage for memoization after first access? that'd be quite powerful
   - I'm not sure we need ReflectionProperty::getHook('set')  when we can
   do getHooks()['set'] ?? null
   - What does ReflectionMethod::getName return on a hook? And getClosure?
   - Should we add ReflectionProperty::IS_VIRTUAL ?
   - I'm a bit surprised by the possibility of adding attributes to hooks.
   I'm not sure I see the use case and I think this might be confusing in
   addition to attributes on the property itself.
   - For serialization: exclude them from var_export() and serialize(),
   which don't need virtual props to rebuild the state (you mean
   json_encode(), not JsonSerializable on that list), call get for
   var_dump/print_r when it's defined (but ignore exceptions). But (array) /
   get_mangled_object_vars() / get_object_vars() shouldn't call any "get".

I have a bigger concern: the take on references contradicts with the intro
about BC breaks: turning a materialized property into virtual one would
break BC as far as refs are concerned. One idea to fix that: add a ref
hook, that must return a reference. If not implemented => Error when trying
to get-by-ref. This could also help solve the $foo->array[] case (including
the asym-visiblity issue).

Nicolas


Re: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-05-09 Thread Tim Düsterhus

Hi

On 5/8/23 23:38, Larry Garfield wrote:

Ilija Tovilo and I would like to offer another RFC for your consideration.  
It's been a while in coming, and we've evolved the design quite a bit just in 
the last week so if you saw an earlier draft of it in the past few months, I 
would encourage you to read it over again to make sure we're all on the same 
page.  I'm actually pretty happy with where it ended up, even if it's not the 
original design.  This approach eliminates several hard-to-implement edge cases 
while still providing a lot of functionality in one package.

https://wiki.php.net/rfc/property-hooks



I've read a previous draft and now did another pass through the updated 
version:


(1) How does the set() hook interact with #[\SensitiveParameter]?
(2) How will a Stack Trace emitted from a hook look like? Please include 
an example of the Exception::__toString() output or so.
(3) ReflectionProperty::getHook(): Will this throw if an invalid hook 
name is given or will this return null?
(4) The "Unaffected PHP Functionality" section is empty. It should 
either be filled in or removed.
(5) I strongly dislike the doubly abbreviated form of `public string 
$fullName => $this->first . " " . $this->last;`. Having just the extra 
'>' in there to distinguish it from a regular property feels non-obvious.


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] Property hooks, nee accessors

2023-05-09 Thread Michał Marcin Brzuchalski
Hi Larry,

pon., 8 maj 2023 o 23:38 Larry Garfield  napisał(a):

> Ilija Tovilo and I would like to offer another RFC for your
> consideration.  It's been a while in coming, and we've evolved the design
> quite a bit just in the last week so if you saw an earlier draft of it in
> the past few months, I would encourage you to read it over again to make
> sure we're all on the same page.  I'm actually pretty happy with where it
> ended up, even if it's not the original design.  This approach eliminates
> several hard-to-implement edge cases while still providing a lot of
> functionality in one package.
>
> https://wiki.php.net/rfc/property-hooks


> Using $this->propertyName directly is supported, but not recommended.
Why is that? IMHO in the scope of accessor this is much clearer to me than
using the $field.

> The following example does make use of $field, however, and thus a
backing value will be created, and write operations will simply write to
the property as normal.
This looks like new magic to me, whether we allow setting and baking the
value explicitly or not. I consider this behavior confusing.

Overall I vote yes.
Cheers,
Michał Marcin Brzuchalski