Re: [RFC] Short Array Variable Shorthand
| From: | Weilin Du | 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