Hi,

Jakob Givoni wrote:
Hello Internals,

I'm opening up my new RFC for discussion:

https://wiki.php.net/rfc/compact-object-property-assignment
- A pragmatic approach to object literals

Let me know what you think!

Best,
Jakob


I really don't like this `(new Foo)->[]` syntax for a few reasons:

* It doesn't seem unreasonable to me to imagine that `->` could be
  overloaded to take a value that isn't a string for the property name.
  Of course, that would be `(new Foo)->{[]}` not `(new Foo)->[]`, but it
  is too close for comfort for me.
* It looks like short array syntax, but it's not an array, in fact
  it is an object, which is a similar but different thing.
* Brackets normally enclose an expression: if I have `new Foo`, I can
  enclose that as `(new Foo)`, yet this is adding something extra to the
  `new` expression while not being part of it? This is surprising to me.
  If it affects the `new`, it should be inside the brackets.
* Do we need the brackets?

I think there are some alternative syntaxes that could be used as inspiration.

C99 has a versatile feature called “designated initialisers”, which lets you initialise not only structs but arrays:

    // Struct initialisation
    struct some_struct foo = {
        .bar = 1,
        .baz = 2,
    };

    // Array initialisation
    int bar[] = {
        [0] = 1,
        [1] = 2,
    };

Notice how the syntax between the curly braces resemblance the normal syntax for accessing and assigning to members of a type. A normal struct member assignment on its own looks like `foo.bar = 1;`, so within the curly braces you write `.bar = 1,`. Likewise a normal array member assignment on its own looks like `bar[0] = 1;`, so within the curly braces you write `[0] = 1,`. This resemblance provides familiarity for someone seeing the syntax for the first time and provides a clue as to what it does, and also retains the visual distinctiveness between array and struct assignments.

If we were to copy the C99 model, perhaps it would look something like:

    $foo = new Foo {
        ->bar = 1,
        ->baz = 2,
    };

(I am assuming the call to the constructor has no arguments here, but otherwise you would insert the normal argument list brackets before the opening `{`. I have used `{` here like C, but perhaps `[` would be better. There would also be the question of whether `=` should be `=>` if we want to deliberately resemble arrays.)

However, we don't have to be so imaginitive and adapt a similar feature, because C# already has the exact feature you are proposing, and calls it “object initialisers”:

    Foo foo = new Foo {
        bar = 1,
        baz = 2,
    };

(I am again assuming the call to the constructor has no arguments. If there are arguments, they go before the opening `{` in C#.)

I am neutral on whether it's a better or worse syntax than using `->`.

Side-note, C# even supports a special kind of anonymous classes with “object initialisers”:

    var foo = new {
        bar = 1,
        baz = 2,
    };

I think PHP won't need this given `new stdClass {` would work perfectly well, although it would be nice to have a shorter and prettier alternative to the current `(object)[`.

Anyway, thanks for proposing something I have wanted for ages but never gotten round to implementing. :)
Andrea

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

Reply via email to