Re: [RFC] Short Array Variable Shorthand

From: Date: Fri, 02 Oct 2026 17:22:32 +0000
Subject: Re: [RFC] Short Array Variable Shorthand
References: 1  Groups: php.internals 
Request: Send a blank email to internals+get-132774@lists.php.net to get a copy of this message
Hi all, This week I have gathered several recommendations from various source concerning this RFC. And finally, I am writing this email to put all these discussions together and announce some changes to the RFC. I have taken my time to implement a very beginning draft on Github, which contains tests of every egde cases I can think of. However, there may be more. Feel free to review it if you want [1] By the way, the diff itself to the parser is surprisingly small, which is good to see. Let me begin with whitespaces. Whitespaces after : is allowed in this syntax. That whitespace includes not only " ". It also includes \t\n\r. To be clear you can also put comments between them. I am going to go back to use : instead of =. I know this sounds like I am jumping between choices, but I am still going to do it. People both on and off the list provide very sensible reasons backing it, and I hope this justify the change: Now let's talk about ternary expressions. Last week I rush back to using = because I thought it crashes with existing syntax, which is ternary expressions inside a array [$a ? $b : $c]. However, there is no ambiguity when it comes to parser, because we always search if there is a ? token before the : token, and if there is, it should be parsed as ternarys, otherwise it should be parsed as a shorthand. The only difference between is ambiguity for static analyzers, and arguably for humans. For example ```php $array = [ $a ? $b : $c ]; ``` Since whitespaces (including " ", \n, \r, etc) is allowed after : in the shorthand RFC, there *may* be some cases that is hard for humen to read. However, the alternative = has the same problem since it also crashes with  ```php [$a = $b]; [$a, = $b]; ```  So they have the same problem. It makes no sense to say = is better than : when it comes to ambiguity. Another down side of = is it is close to => for keyed arrays, and : is more distiguishable in this case. Another point is existing languages. The Raku programming language which support this shorthand all uses : [2] And the perl programming language uses => for similar feature [3]. Finally, I've tried to raise this topic in different php community. And I got the vibe of preferring : tha = when it comes to coding aestheic. Or more plainfully, taste. So. I hope these reasons justifies why I switch back to :. I hope you treat this as a decision after considerations. Now, when I was implementing this feature. I find several new edgecases that I want to bring to the list. First if $object implements ArrayAccess [4] [:$name] = $object; is a valid syntax. And it reads $object["name"] and give the value to $name. It is same to ``` ['name' => $name] = $object ``` Second: ``` $name = 'new'; $a = [...['name' => 'old'], :$name]; // ['name' => 'new'] $b = [:$name, ...['name' => 'later']]; // ['name' => 'later'] ``` Third. There are some limitations when you nest. You CANNOT mix [] with list() when using this syntax. Though this is same when you dont use the shorthand expression. (So basically you can't do this anyways) But it's important to mention since I was surprised when writing test for this RFC. ``` $record = ['user' => ['name' => 'Ada']]; ['user' => [:$name]] = $record; // OK list('user' => list(:$name)) = $record; // OK list('user' => [:$name]) = $record; // Error ``` Fourth. You cannot mix keyed and unkeyed elements. Again this is not unique to the shorthand syntax. You cannot do this anyways but I want to mention just in case. ``` [:$name, $age] = $row; // Error ``` I will put these cases into the RFC. Sorry I didn't catch these in the first place. Please tell me if you have any questions. Lastly I want to talk about references. When you create an array with [:$name], it will not create a new reference to the orginal variable. ``` $name = 'before'; $array = [:$name]; $name = 'after'; echo $array['name']; // before ``` When destructing, if the variable is already a reference. It will overwrite the stuff that reference points to. ``` $target = 'before'; $name =& $target; [:$name] = ['name' => 'after']; echo $target; // after ``` The RFC text is not updated for now. Because I haven't finished testing the syntax, but there are all of my thoughts and work in this week. Besides them, I find nothing new. I hope you find it useful. I'd update the RFC tomorrow according to this email. If any changes, I will inform. I have no intention to vote any time soon. I wrote this 4 a.m so there may be mistake. Apologize for the wall of text. Yours sincerely Weilin Du [1]: https://github.com/php/php-src/pull/24034 [2]: https://docs.raku.org/syntax/Colon%20Pair [3]: https://perldoc.perl.org/perlop#Comma-Operator [4]: https://www.php.net/manual/en/class.arrayaccess.php

« previous php.internals (#132774) next »