rfc:compact-object-property-assignment

This is an old revision of the document!


PHP RFC: Compact Object Property Assignment

  • Version: 0.9
  • Date: 2020-03-10
  • Author: Jakob Givoni jakob@givoni.dk
  • Status: Draft

Introduction

Summary

A pragmatic approach to mimicking object literals.

This RFC proposes a new, compact syntax to assign values to multiple properties on an object in a single expression.

Example

// Current syntax
$myObj->prop_a = 1;
$myObj->prop_b = 2;
$myObj->prop_c = 3;
 
// COPA syntax
$myObj->[
    prop_a = 1,
    prop_b = 2,
    prop_c = 3,
];

Motivation

The purpose of this feature is to lighten the effort of populating data structures, especially medium to large ones.

Ideally the solution should meets the following criteria:

  • Brief - only mention the object once (less repetition)
  • Inline - object can be created and populated in a single expression (pseudo object literals, nested objects)
  • Typo-proof - property names can be autocompleted easily by IDE (faster typing, fewer errors)
  • Type-checking - IDE can verify correct type for typed properties and annotated virtual properties
  • Order-agnostic - properties can be specified in any order (this doesn't mean that the result is necessarily the same for any ordering, as that will depend on the object implementation)
  • Simple - COPA does what you would expect without introducing any new concepts into the language

Proposal

Syntax

The proposed syntax following an object expression $myObj | (new MyClass()) is the object arrow operator -> followed by a set of square brackets […] containing a comma-separated list of property name equal = expression. A trailing comma is permitted for the same reasons it's permitted in array literals and function calls (as of PHP 7.3). The whole block is considered an expression that returns the object we started with.

Interpretation

Each comma-separated assignment inside the curly brackets is executed as an assignment of the named property on the object preceding the block. If the property is defined and publicly accessible, it will simply be set, or possible throw a TypeError. If there's no property with that name, or if it's protected or private, the magic method _ _ set will be called just like you would expect. When used in an expression, COPA simply returns the object itself.

Use cases

DTOs - data transfer objects

  • many properties
  • some properties may be optional or have default values
  • properties may be public so we may avoid writing a lot of boilerplate code when defining them

With COPA we can create the whole object inline right inside the function call:

class Dto {
    public string $foo;
    public int $bar = 1; // Optional, with default
    public string $baz;
}
 
// Currently...
$myDto = new Dto();
$myDto->foo = 'get';
$myDto->baz = 'life';
 
myFunc($myDto);
 
// With COPA…
myFync((new Dto())->[
    foo = 'get',
    baz = 'life',
]);

Argument bags

  • many arguments needs to be passed to function
  • some arguments are optional
  • order of arguments is not important

With COPA we can avoid using simple arrays and instead get autocomplete and type-checking in the IDE with a syntax that smells of named parameters:

// Currently…
class Foo {
     protected string $foo;
    protected int $bar;
    protected string $baz;
 
    public function __construct(array $options) {
        $this->foo = $options['foo'];
        $this->bar = $options['bar'];
        $this->baz = $options['baz'];
    }
}
 
$myFoo = new Foo([
    'foo' => 'get',
    'baz' => 'life',
]);
 
// With COPA...
class FooOptions {
    public string $foo;
    public int $bar = 1; // Optional, with default
    public string $baz;
}
 
class Foo {
    protected string $foo;
    protected int $bar;
    protected string $baz;
 
    public function __construct(FooOptions $options) {
        $this->foo = $options->foo;
        $this->bar = $options->bar;
        $this->baz = $options->baz;
    }
}
 
$myFoo = new Foo((new FooOptions())->[
    foo = 'get',
    baz = 'life',
]);

Backward Incompatible Changes

None. Array followed by square bracket causes syntax error in PHP 7.4. This new syntax is optional. If you don't use it, your code will continue to run.

Proposed PHP Version(s)

Next PHP 8.x

Open Issues

Proposed Voting Choices

Patches and Tests

There are yet no patches nor tests. The question of who will be developing this will be addressed if the RFC passes.

Implementation

After the project is implemented, this section should contain

  1. the version(s) it was merged into
  2. a link to the git commit(s)
  3. a link to the PHP manual entry for the feature
  4. a link to the language specification section (if any)

References

Rejected Features

rfc/compact-object-property-assignment.1583892094.txt.gz · Last modified: 2020/03/11 02:01 by jgivoni