Re: [PHP-DEV] Allowing `(object)['key' => 'value']` in initializers?

2021-10-04 Thread Nikita Popov
On Sat, Sep 25, 2021 at 5:45 PM tyson andre 
wrote:

>
> Hi internals,
>
> In PHP 8.1, it is possible to allow constructing any class name in an
> initializer, after the approval of
> https://wiki.php.net/rfc/new_in_initializers
>
> ```
> php > static $x1 = new ArrayObject(['key' => 'value']);
> php > static $x2 = new stdClass();
> php > static $x3 = (object)['key' => 'value'];
>
> Fatal error: Constant expression contains invalid operations in php shell
> code on line 1
> ```
>
> What are your thoughts on allowing the `(object)` cast in initializer
> types where `new` was already allowed, but only when followed by an array
> literal node. (e.g. continue to forbid `(object)SOME_CONSTANT`) (see
> https://wiki.php.net/rfc/new_in_initializers)
>
> stdClass has never implemented a factory method such as `__set_state`
> (which is not yet allowed). Instead, `(object)[]` or the `(object)array()`
> shorthand is typically used when a generic object literal is needed. This
> is also how php represents objects in var_export.
>
> ```
> php > var_export(new stdClass());
> (object) array(
> )
> ```
>
> Reasons:
> - The ability to construct empty stdClass instances but not non-empty ones
> is something users would find surprising,
>   and a lack of support for `(object)[]` be even more inconsistent if
> factory methods were allowed in the future.
> - stdClass is useful for some developers, e.g. in unit tests, when using
> libraries requiring it for parameters,
>   when you need to ensure data is encoded as a JSON `{}` rather than `[]`,
> etc.
> - It would help developers write a clearer api contract for methods,
>   e.g. `function setData(stdClass $default = (object)['key' => 'value'])`
>   is clearer than `function setData(?stdClass $default = null) { $default
> ??= (object)['key' => 'value']; `
> - stdClass may be the only efficient built-in way to represent objects
> with arbitrary names if RFCs such as https://externals.io/message/115800
>   passed
>

I'm not super convinced about the usefulness of (object)[] in particular,
but I also think that we shouldn't artificially limit the types of
expressions supported in constant expressions -- if there's no strong
reason why something should be forbidden, it should be allowed.

>From that perspective, I think the root issue here is that constant
expressions currently don't support casts at all. It's not just a matter of
being unable to write (object)[], you also can't write (int)X (but you can
write +X). I think it's perfectly reasonable to support casts in constant
expressions, and if we do, then I don't think we need to go out of the way
to forbid object casts either, so support for (object)[] should just fall
out as a special case.

Regards,
Nikita


Re: [PHP-DEV] Allowing `(object)['key' => 'value']` in initializers?

2021-09-27 Thread Lynn
On Mon, Sep 27, 2021 at 3:15 PM Sara Golemon  wrote:

> I think for consistency's sake, we'd want to provide a base constructor to
> stdClass to take an associative array that maps into dynamic properties,
> e.g.
>
> class stdClass {
>   public function __construct(array $props) {
> foreach ($prop as $name => $val) {
>   $this->$name = $val;
> }
>   }
> }
>
> Then you could:
> php>  static $x3 = new stdClass(['key' => 'value']);
>

If the structure of `$something = {};` would ever be allowed in PHP, the
following could be done instead: `$something = { ...$array };`. This will
reduce the dependency on the stdClass.


Re: [PHP-DEV] Allowing `(object)['key' => 'value']` in initializers?

2021-09-27 Thread Sara Golemon
On Sat, Sep 25, 2021 at 10:45 AM tyson andre 
wrote:

> In PHP 8.1, it is possible to allow constructing any class name in an
> initializer, after the approval of
> https://wiki.php.net/rfc/new_in_initializers
>
> ```
> php > static $x1 = new ArrayObject(['key' => 'value']);
> php > static $x2 = new stdClass();
> php > static $x3 = (object)['key' => 'value'];
>
> Fatal error: Constant expression contains invalid operations in php shell
> code on line 1
> ```
>
> What are your thoughts on allowing the `(object)` cast in initializer
> types where `new` was already allowed, but only when followed by an array
> literal node.
>
>
I think for consistency's sake, we'd want to provide a base constructor to
stdClass to take an associative array that maps into dynamic properties,
e.g.

class stdClass {
  public function __construct(array $props) {
foreach ($prop as $name => $val) {
  $this->$name = $val;
}
  }
}

Then you could:
php>  static $x3 = new stdClass(['key' => 'value']);

This avoids special-casing object cases in the engine while making it clear
that a stdClass is what you wind up with, and honestly I think it'd be a
useful pattern to use when initializing stdClass with defaults elsewhere.

As to whether or not we SHOULD: While using declared props is preferred in
the vast majority of cases, both for performance and for readability, there
are legitimate cases where a short lived container wants the flexibility
and convenience of an untyped, dynamic structure like an associative array
with the visually clean aesthetic of object access.  stdClass does that,
and even if deprecation of dynamic properties passes it will continue to do
that.  I started this paragraph ambivalent about the feature, but I think I
convinced myself around to a +1, though in the constructor form, not the
cast form.

-Sara


Re: [PHP-DEV] Allowing `(object)['key' => 'value']` in initializers?

2021-09-25 Thread Mike Schinkel
> On Sep 25, 2021, at 12:03 PM, Marco Pivetta  wrote:
> 
> Hey Tyson,
> 
> On Sat, 25 Sep 2021, 18:00 tyson andre,  wrote:
> 
>> My original message had a section with reasons why an end user might want
>> that.
>> 
> 
> Yeh, it sounds like stuff we wanna get away from 

Point of order here: "we" is not unanimous.

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



Re: [PHP-DEV] Allowing `(object)['key' => 'value']` in initializers?

2021-09-25 Thread Rowan Tommins

On 25/09/2021 16:45, tyson andre wrote:

What are your thoughts on allowing the `(object)` cast in initializer types 
where `new` was already allowed



I'm not strongly opposed to this, but am not convinced it's a big 
improvement.


Firstly, as with everything involving stdClass, I would be more 
interested in a) improving the initialization of anonymous objects, and 
b) allowing those in initialisers (the RFC currently forbids them, but 
doesn't say why, so I'm not sure if it's an implementation decision or a 
philosophical one).


Secondly, if you have enough knowledge of the structure to provide an 
inline default, then you probably have enough to be worth defining a 
named class, even if that class then implements __set() to allow 
additional ad hoc properties. That class can then have its own defaults, 
so that your example becomes `function setData(Data $values = new Data())`


Regards,

--
Rowan Tommins
[IMSoP]

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



Re: [PHP-DEV] Allowing `(object)['key' => 'value']` in initializers?

2021-09-25 Thread Marco Pivetta
Hey Tyson,

On Sat, 25 Sep 2021, 18:00 tyson andre,  wrote:

> My original message had a section with reasons why an end user might want
> that.
>

Yeh, it sounds like stuff we wanna get away from 


> Not a push for getting rid of stdClass. Way too many things use stdClass
> to get rid of stdClass.
>

Yes, but for legacy reasons, not for further perpetuating the practice.

>


Re: [PHP-DEV] Allowing `(object)['key' => 'value']` in initializers?

2021-09-25 Thread tyson andre
Hey Marco Pivetta,

> > What are your thoughts on allowing the `(object)` cast in initializer types 
> > where `new` was already allowed, but only when followed by an array literal 
> > node. (e.g. continue to forbid `(object)SOME_CONSTANT`) (see 
> > https://wiki.php.net/rfc/new_in_initializers)
> > ...
> > Reasons:
> > - The ability to construct empty stdClass instances but not non-empty ones 
> > is something users would find surprising,
> >   and a lack of support for `(object)[]` be even more inconsistent if 
> > factory methods were allowed in the future.
> > - stdClass is useful for some developers, e.g. in unit tests, when using 
> > libraries requiring it for parameters,
> >   when you need to ensure data is encoded as a JSON `{}` rather than `[]`, 
> > etc.
> > - It would help developers write a clearer api contract for methods,
> >   e.g. `function setData(stdClass $default = (object)['key' => 'value'])`
> >   is clearer than `function setData(?stdClass $default = null) { $default 
> > ??= (object)['key' => 'value']; `
> > - stdClass may be the only efficient built-in way to represent objects with 
> > arbitrary names if RFCs such as https://externals.io/message/115800 passed

>   passed
>
> Right now, there's even an interest in getting rid (or deprecating) dynamic 
> properties on objects: why push the complete opposite ways?
> 
> What is the actual value of using an stdClass instance instead of an 
> `array` (already supported)?

My original message had a section with reasons why an end user might want that.

There's a push for getting rid of (or deprecating) dynamic properties on 
**objects that are not stdClass (or subclasses)**
Not a push for getting rid of stdClass. Way too many things use stdClass to get 
rid of stdClass.
(whether or not stdClass gets aliased or even renamed to DynamicObject).

```
php > var_dump(json_decode('{}'));
object(stdClass)#1 (0) {
}
```

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



Re: [PHP-DEV] Allowing `(object)['key' => 'value']` in initializers?

2021-09-25 Thread Marco Pivetta
Hey Tyson,

On Sat, 25 Sep 2021, 17:45 tyson andre,  wrote:

> What are your thoughts on allowing the `(object)` cast in initializer
> types where `new` was already allowed, but only when followed by an array
> literal node. (e.g. continue to forbid `(object)SOME_CONSTANT`) (see
> https://wiki.php.net/rfc/new_in_initializers)
>

Right now, there's even an interest in getting rid (or deprecating) dynamic
properties on objects: why push the complete opposite ways?

What is the actual value of using an stdClass instance instead of an
`array` (already supported)?

>