Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:109199 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 65216 invoked from network); 22 Mar 2020 04:24:23 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 22 Mar 2020 04:24:23 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 71DD71804B8 for ; Sat, 21 Mar 2020 19:48:12 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-1.4 required=5.0 tests=BAYES_00, FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS15169 209.85.128.0/17 X-Spam-Virus: No X-Envelope-From: Received: from mail-lj1-f180.google.com (mail-lj1-f180.google.com [209.85.208.180]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Sat, 21 Mar 2020 19:48:12 -0700 (PDT) Received: by mail-lj1-f180.google.com with SMTP id 19so10729731ljj.7 for ; Sat, 21 Mar 2020 19:48:12 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=lvup7hZU+JzKKMjyhpVqweaAGR/ITO4bfcvZh5XSuCg=; b=X9EPtJGkGesFTTCxGmV3dEFZHdsgjOxQWukM+ruLC2EFKa+oK6TzofzoxWheP//02S VNb+O2KTM1hevxGUvoUupyrquSnmif5bxqjD9mdKxjyzn6qe70iuWuXFG70kn+EFECJ1 xfOyH2NIwo/8fcT4TBUbu8PCNtiE57n9j4QAARJC+jOJviyGrWGQBItjNAXfd+6LawmB ddVfTHbb6V8Eqsxg//kHDqfI6LtJnkIXat7WPeJE04uanBxIfu2N3a5OXb1MRhJhxK4b UUTWKAcQF/JY2PQe4krpyiZ/Wf1usyIKt7+hqT+J59LIQLbgc7lPXB/vDGK0oqBxbGSg adbg== X-Gm-Message-State: ANhLgQ167Yk4grO5TridPvzEFBZi7g84v5Hp+JVp1l1an8OM5zLzm/+p JBlDEN94Hucd1WtcvzKrHWO86w87hxGClNRUAL0= X-Google-Smtp-Source: ADFU+vtLkYJMdseucN4+sjY7+8VeprgIduGoR3bmzqqkRC4jU0H1SQLyVg3cin5tZqzwmfbNhDKFFKtmixfFi3ZhK5U= X-Received: by 2002:a2e:240d:: with SMTP id k13mr10191250ljk.33.1584845288871; Sat, 21 Mar 2020 19:48:08 -0700 (PDT) MIME-Version: 1.0 References: <5e765d7c.1c69fb81.ebac3.8787SMTPIN_ADDED_MISSING@mx.google.com> In-Reply-To: <5e765d7c.1c69fb81.ebac3.8787SMTPIN_ADDED_MISSING@mx.google.com> Date: Sat, 21 Mar 2020 21:47:58 -0500 Message-ID: To: Andrea Faulds Cc: php internals Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Subject: Re: [PHP-DEV] [RFC] [DISCUSSION] Compact Object Property Assignment From: jakob@givoni.dk (Jakob Givoni) Hi Andrea, thanks for your feedback. Let's talk about syntax then :-) The currently suggested syntax is -> [ =3D , ... ] The can be an existing object: $foo->[a =3D 1]; Or a new, yet anonymous, object: (new Foo)->[a =3D 1]; 1. The (normal) brackets =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D The reason I think it's necessary to wrap the new Foo in brackets is because it's a language construct and not an expression in itself. Wrapping it in brackets make it an expression. For example, these are both syntax errors (missing brackets): new Foo->a =3D 1; new Foo()->setA(1); In this RFC I did not want to propose changing the lexer/parser to make that possible, since my focus was to suggest a rather trivial implementation. I'm open to change this view, but only if someone with solid knowledge of internals come forward and promise that it's a good idea. 2. The arrow =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D When the arrow follows an object expression it suggest we're doing something on that object, like accessing a property (set/get) or calling a method. There are exceptions though: When the object expression is followed by curly or square brackets it means we're accessing it as if it were an array: $foo[1] $foo{1} // Deprecated And when it's followed by normal brackets, we're invoking it as a callable: $foo() I see a window of opportunity here though: Since the curly brackets were deprecated in PHP 7.4 we could repurpose it for COPA: $foo{a =3D 1, b =3D 2} Is it too soon? 3. The square brackets =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D The assignments need to be grouped together, somehow (at least I think that's the sane thing to do?) - we cannot use curly brackets as, like you say, that's reserved to create an expression that evaluates to a property name: $foo->{a =3D1, b =3D 2}; // syntax error, unexpected '=3D' That leaves us with either normal brackets or square brackets: $foo->(a =3D 1, b =3D 2); $foo->[a =3D 1, b =3D 2]; Which one is more natural when we're dealing with structure data? 4. The property name =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D All I can say is that I really don't want to add anything that is not strictly necessary, like the arrow before each property, unless it's adding something of actual value. Familiarity you say... yes, I can see that, but it gets very verbose with that leading arrow... In my opinion array literal syntax is already too verbose for me. 5. The equals sign =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D I don't really know why =3D> was chosen for array assignment, since we use simple =3D to assign values everywhere else. Since i prefer it less verbose, and since we already use =3D in $foo->a =3D 1 I think a single =3D is the best option. COPA is NOT object initializer =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D COPA can follow any object expression and has nothing to do with object construction in itself. You can use COPA as many times as you like at any point in an object's life. Though object initializer would also solve what COPA is solving, COPA doesn't introduce any new concepts, just new syntax. I don't know why object initializer and other similar proposals failed in the past, but I wanted to try something different, less elaborate and more pragmatic. I don't know if COPA has any better chance than those that came before :-) I am going to suggest a few alternative syntaxes that we can also vote on, but only after they've been vetted by experienced internals developers. Syntax A - the initial one Syntax B: $foo{ a =3D 1, b =3D 2, }; Syntax C: $foo->a =3D 1, b =3D 2; Syntax D: $foo->a =3D 1, ->b =3D 2; Syntax E: $foo->( a =3D 1, b =3D 2, ); We can try to iterate over these as well, please let me know what you think= ! On Sat, Mar 21, 2020 at 1:31 PM Andrea Faulds wrote: > > 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 =E2=80=9Cdesignated initialisers=E2=80= =9D, which lets > you initialise not only structs but arrays: > > // Struct initialisation > struct some_struct foo =3D { > .bar =3D 1, > .baz =3D 2, > }; > > // Array initialisation > int bar[] =3D { > [0] =3D 1, > [1] =3D 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 =3D 1;`, so within the > curly braces you write `.bar =3D 1,`. Likewise a normal array member > assignment on its own looks like `bar[0] =3D 1;`, so within the curly > braces you write `[0] =3D 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 =3D new Foo { > ->bar =3D 1, > ->baz =3D 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 `=3D` should be `=3D>= ` > 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 > =E2=80=9Cobject initialisers=E2=80=9D: > > Foo foo =3D new Foo { > bar =3D 1, > baz =3D 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 > =E2=80=9Cobject initialisers=E2=80=9D: > > var foo =3D new { > bar =3D 1, > baz =3D 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 >