Re: [PHP-DEV] [VOTE] Undefined Property Error Promotion

2022-04-28 Thread Larry Garfield
On Thu, Apr 28, 2022, at 9:05 AM, Côme Chilliet wrote:
> Le lundi 25 avril 2022, 18:19:33 CEST Rowan Tommins a écrit :
>> Look at how the untyped property behaves in this example: 
>> https://3v4l.org/nClNs The property disappears from var_dump(), but is 
>> not actually deleted from the object, as seen by it still being private 
>> when assigned a new value. Given that we have the magic "uninitialized" 
>> state, and we're proposing to make reading an unset property an error, 
>> it would make more sense for it to show as '["untyped":"Foo":private] => 
>> uninitialized(mixed)'
>
> I second that it would make sense for an untyped property to behave the 
> same as a typed one with type mixed.
> Getting a behavior change by adding a mixed typing to an untyped 
> property is highly unexpected.
>
> Côme

Changing the logic so that untyped properties are essentially a shorthand for 
typing mixed (like no-visibility is a shorthand for public) could be beneficial 
in the long run.  It would be more consistent, and with the robustness around 
null-based tooling now that also works with undefined, it would probably not be 
too drastic a break if people knew to prepare for it (vis, happen in 9).  I 
could get behind that, but that should be its own separate RFC.

--Larry Garfield

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



Re: [PHP-DEV] [VOTE] Undefined Property Error Promotion

2022-04-28 Thread Côme Chilliet
Le lundi 25 avril 2022, 18:19:33 CEST Rowan Tommins a écrit :
> Look at how the untyped property behaves in this example: 
> https://3v4l.org/nClNs The property disappears from var_dump(), but is 
> not actually deleted from the object, as seen by it still being private 
> when assigned a new value. Given that we have the magic "uninitialized" 
> state, and we're proposing to make reading an unset property an error, 
> it would make more sense for it to show as '["untyped":"Foo":private] => 
> uninitialized(mixed)'

I second that it would make sense for an untyped property to behave the same as 
a typed one with type mixed.
Getting a behavior change by adding a mixed typing to an untyped property is 
highly unexpected.

Côme

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



Re: [PHP-DEV] [VOTE] Undefined Property Error Promotion

2022-04-25 Thread Rowan Tommins

On 21/04/2022 22:45, Mark Randall wrote:

Internals,

I have now opened voting on Undefined Property Error Promotion.

https://wiki.php.net/rfc/undefined_property_error_promotion



In case anyone missed it due to some messed-up mail headers, the thread 
I intended to be a reply to this is here: 
https://externals.io/message/117571


My position is that both this and the undefined variable RFC should have 
been a review of functionality, not a blind copy and paste of Warnings 
into Errors. Since I don't seem to have persuaded anyone else of this, I 
will try to raise one or more follow-up RFCs trying to fill in the gaps.


Regards,

--
Rowan Tommins
[IMSoP]

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



Re: [PHP-DEV] [VOTE] Undefined Property Error Promotion

2022-04-25 Thread Guilliam Xavier
> > Are you proposing to deprecate the implicit `= null` default initializer
> > for untyped properties?
>
> Yes.
>
>
> > Thanks for the recap. For untyped properties, that's the historical
> > behavior. For typed properties, that's explained in
> >
> https://wiki.php.net/rfc/typed_properties_v2#uninitialized_and_unset_properties
> > *. What's the issue?
>
> The issue is that for new users, saying "that's the historical
> behaviour, you just have to learn it" is not very helpful.
>
>
> > * "If a typed property is `unset()`, then it returns to the uninitialized
> > state. While we would love to remove support for the unsetting of
> > properties, this functionality is currently used for lazy initialization
> by
> > Doctrine, in combination with the functionality described in the
> following
> > section."
>
> I think both you and Mark misunderstood my point in bringing this up -
> I'm not complaining about the ability to call unset(), I'm complaining
> that it behaves differently depending how the property was declared.
>
> Look at how the untyped property behaves in this example:
> https://3v4l.org/nClNs The property disappears from var_dump(), but is
> not actually deleted from the object, as seen by it still being private
> when assigned a new value. Given that we have the magic "uninitialized"
> state, and we're proposing to make reading an unset property an error,
> it would make more sense for it to show as '["untyped":"Foo":private] =>
> uninitialized(mixed)'
>

Understood (also https://3v4l.org/DgXJl ). Maybe start a new thread? (this
one is not shown on externals.io, only findable via search)

-- 
Guilliam Xavier


Re: [PHP-DEV] [VOTE] Undefined Property Error Promotion

2022-04-25 Thread Rowan Tommins

On 25/04/2022 12:24, Guilliam Xavier wrote:

Hi Rowan,

(...) Also, there's this non-standard class called

"stdClass", which unlike standard classes, you can read and write any
property you like without declaring it,


Better reordered "write and read" I think. Yes, like associative arrays,
stdClass is "dynamic" by design.



Indeed, and if that was the only exception, it would be reasonable; it's 
when you pile it on top of all the other rules that it starts making 
people sad.




and even if you use unset(),
you'll never get an error.


That's not true, e.g. given `$o = (object)['foo' => 1]; $o->bar = 2;` then
`unset($o->foo, $o->bar);`, trying to read `$o->foo` or `$o->bar` will both
cause an error (like for `$o->qux`); or I'm misunderstanding you?



You're right, I was mis-remembering; the RFC explicitly says that this 
will error.




Are you proposing to deprecate the implicit `= null` default initializer
for untyped properties?



Yes.




Thanks for the recap. For untyped properties, that's the historical
behavior. For typed properties, that's explained in
https://wiki.php.net/rfc/typed_properties_v2#uninitialized_and_unset_properties
*. What's the issue?



The issue is that for new users, saying "that's the historical 
behaviour, you just have to learn it" is not very helpful.




* "If a typed property is `unset()`, then it returns to the uninitialized
state. While we would love to remove support for the unsetting of
properties, this functionality is currently used for lazy initialization by
Doctrine, in combination with the functionality described in the following
section."



I think both you and Mark misunderstood my point in bringing this up - 
I'm not complaining about the ability to call unset(), I'm complaining 
that it behaves differently depending how the property was declared.


Look at how the untyped property behaves in this example: 
https://3v4l.org/nClNs The property disappears from var_dump(), but is 
not actually deleted from the object, as seen by it still being private 
when assigned a new value. Given that we have the magic "uninitialized" 
state, and we're proposing to make reading an unset property an error, 
it would make more sense for it to show as '["untyped":"Foo":private] => 
uninitialized(mixed)'



Regards,

--
Rowan Tommins
[IMSoP]

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



Re: [PHP-DEV] [VOTE] Undefined Property Error Promotion

2022-04-25 Thread Guilliam Xavier
Hi Rowan,

(...) Also, there's this non-standard class called
> "stdClass", which unlike standard classes, you can read and write any
> property you like without declaring it,


Better reordered "write and read" I think. Yes, like associative arrays,
stdClass is "dynamic" by design.


> and even if you use unset(),
> you'll never get an error.
>

That's not true, e.g. given `$o = (object)['foo' => 1]; $o->bar = 2;` then
`unset($o->foo, $o->bar);`, trying to read `$o->foo` or `$o->bar` will both
cause an error (like for `$o->qux`); or I'm misunderstanding you?

> You could special case nullable, but then it's an extra rule to learn
> > beyond "typed = needs to be initialized".
>
> I'm more inclined to the opposite: if reading an "undefined" property is
> going to be an error, maybe reading an "uninitialized" one should be
> too, even if you don't declare a type for it.
>

Are you proposing to deprecate the implicit `= null` default initializer
for untyped properties?


> And maybe we should think about exactly what unset() means, and which
> error you're going to get after you use it - is the property "undefined"
> or "uninitialized"? Currently, an untyped property becomes "undefined",
> as though it never existed; but a typed property is still on the object,
> but "uninitialized". Yet either way, assigning a new value brings back
> the declared property, not a dynamic one with the same name:
> https://3v4l.org/nClNs
>

Thanks for the recap. For untyped properties, that's the historical
behavior. For typed properties, that's explained in
https://wiki.php.net/rfc/typed_properties_v2#uninitialized_and_unset_properties
*. What's the issue?

* "If a typed property is `unset()`, then it returns to the uninitialized
state. While we would love to remove support for the unsetting of
properties, this functionality is currently used for lazy initialization by
Doctrine, in combination with the functionality described in the following
section."

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] [VOTE] Undefined Property Error Promotion

2022-04-22 Thread Rowan Tommins

On 22/04/2022 21:47, Mark Randall wrote:
The rule that anything typed must be initialized, nullable or not, is 
clearish enough.



It's "clear" in the sense of "it can be described in one sentence". It's 
not at all "clear" in the sense of "makes any logical sense whatsoever".



You could special case nullable, but then it's an extra rule to learn 
beyond "typed = needs to be initialized". 



I'm more inclined to the opposite: if reading an "undefined" property is 
going to be an error, maybe reading an "uninitialized" one should be 
too, even if you don't declare a type for it.


And maybe we should think about exactly what unset() means, and which 
error you're going to get after you use it - is the property "undefined" 
or "uninitialized"? Currently, an untyped property becomes "undefined", 
as though it never existed; but a typed property is still on the object, 
but "uninitialized". Yet either way, assigning a new value brings back 
the declared property, not a dynamic one with the same name: 
https://3v4l.org/nClNs


Regards,

--
Rowan Tommins
[IMSoP]

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



Re: [PHP-DEV] [VOTE] Undefined Property Error Promotion

2022-04-22 Thread Mark Randall

On 22/04/2022 21:30, Rowan Tommins wrote:
Do you not have even a little bit of hope that we could make that less 
confusing, since we're breaking everyone's old code anyway?



I seem to remember we had a discussion years ago about deleting unset on 
properties, but it was being used for a very popular proxy manager to 
force them to be routed to __get.


The rule that anything typed must be initialized, nullable or not, is 
clearish enough. You could special case nullable, but then it's an extra 
rule to learn beyond "typed = needs to be initialized".


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



Re: [PHP-DEV] [VOTE] Undefined Property Error Promotion

2022-04-22 Thread Rowan Tommins

On 22/04/2022 18:12, Mark Randall wrote:
Accessing an unset property, which currently emits a warning, will 
instead throw an Error.


[...]

Re: Case 4, an untyped property without its own initializer is 
effectively defaulted to null.



Imagine you're a new user, learning PHP 9.0, and learning that "public 
$foo" defaults to null; and if you call unset(), it's deleted from the 
object, and then accessing it is an error. But then you change it to 
"public ?string $foo" and it doesn't default to null, even though it's 
nullable, and accessing it will give you a different error; and calling 
unset() on that doesn't delete it from the object, but does mean you get 
an error reading it. Also, there's this non-standard class called 
"stdClass", which unlike standard classes, you can read and write any 
property you like without declaring it, and even if you use unset(), 
you'll never get an error.


Do you not have even a little bit of hope that we could make that less 
confusing, since we're breaking everyone's old code anyway?


Regards,

--
Rowan Tommins
[IMSoP]

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



Re: [PHP-DEV] [VOTE] Undefined Property Error Promotion

2022-04-22 Thread Mark Randall

On 22/04/2022 14:42, Rowan Tommins wrote:

As with your previous RFC, I approve of this in principle, but am
frustrated how little time has been spent considering the edge cases, such
as the ones I mentioned here: https://externals.io/message/117487#117487



Accessing an unset property, which currently emits a warning, will 
instead throw an Error.


If a property has already been written to via some mechanism, then the 
property exists and this RFC does not apply, no warning or error should 
be expected. It's a different responsibility to handle the guards 
against writing to one which has not been defined 
(AllowDynamicProperties RFC).


Re: Case 4, an untyped property without its own initializer is 
effectively defaulted to null.


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



Re: [PHP-DEV] [VOTE] Undefined Property Error Promotion

2022-04-22 Thread Rowan Tommins
On 21 April 2022 22:45:17 BST, Mark Randall  wrote:
>Internals,
>
>I have now opened voting on Undefined Property Error Promotion.
>
>https://wiki.php.net/rfc/undefined_property_error_promotion


As with your previous RFC, I approve of this in principle, but am
frustrated how little time has been spent considering the edge cases, such
as the ones I mentioned here: https://externals.io/message/117487#117487

It seems to me that we've got an increasingly complicated set of states a
property can be in, depending on whether it's been declared with a type,
without one, or not at all; whether it's had a value assigned to it;
whether it's been unset; etc. If I am struggling to follow the distinctions
between "declared", "defined", "initialised", "dynamic", "nullable" etc,
how will users who start with PHP 9.0 understand why some situations
produce errors and others do not?

Regards,
-- 
Rowan Tommins
[IMSoP]