[RFC] [PHP 6] Uniform Variable Syntax

php.internals

Nikita Popov

12 years ago
Hi internals! I have created a proposal for a more consistent and complete variable syntax for PHP 6: https://wiki.php.net/rfc/uniform_variable_syntax The RFC is targeted at PHP 6 because it breaks compatibility for some rarely used variable-variable constructs. Thanks, Nikita

Andrew Faulds

12 years ago
On 9 Jun 2014, at 14:33, Nikita Popov <nikita.ppv@gmail.com> wrote:
> I have created a proposal for a more consistent and complete variable > syntax for PHP 6: > > https://wiki.php.net/rfc/uniform_variable_syntax > > The RFC is targeted at PHP 6 because it breaks compatibility for some > rarely used variable-variable constructs.
I love this proposal! The behaviour of $$ is non-intuitive at present and has bitten me more than once, and the weird behaviour of :: has also caused me problems. In particular, my miniature web framework didn’t work properly due to this line: self::$views[$path](); It’s easy to fix ($x = self::$views[$path]; $x();) but the fact that didn’t work has bothered me immensely for two years. It seems to me like the RFC would fix this. Would it? If so, you are my hero. On a somewhat more serious note, do we have any idea of how much code this would break? Is the current behaviour widely relied-upon?
-- Andrea Faulds http://ajf.me/

Nikita Popov

12 years ago
On Mon, Jun 9, 2014 at 3:45 PM, Andrea Faulds <ajf@ajf.me> wrote:
> > On 9 Jun 2014, at 14:33, Nikita Popov <nikita.ppv@gmail.com> wrote: > > > I have created a proposal for a more consistent and complete variable > > syntax for PHP 6: > > > > https://wiki.php.net/rfc/uniform_variable_syntax > > > > The RFC is targeted at PHP 6 because it breaks compatibility for some > > rarely used variable-variable constructs. > > I love this proposal! The behaviour of $$ is non-intuitive at present and > has bitten me more than once, and the weird behaviour of :: has also caused > me problems. In particular, my miniature web framework didn’t work properly > due to this line: > > self::$views[$path](); > > It’s easy to fix ($x = self::$views[$path]; $x();) but the fact that > didn’t work has bothered me immensely for two years. It seems to me like > the RFC would fix this. Would it? If so, you are my hero. >
Yes, it would ;)
> On a somewhat more serious note, do we have any idea of how much code this > would break? Is the current behaviour widely relied-upon? >
Quoting https://wiki.php.net/rfc/uniform_variable_syntax#backward_incompatible_changes :
> An analysis of the Zend Framework and Symfony projects > (including standard dependencies) showed that only a single > occurrence of $loader[0]::$loader[1]($className) in the Doctrine > class loader will be affected by this change.
So I think that this will not break much code. It is also easy to detect and fix. (I am using this script to find potential problems: https://gist.github.com/nikic/ffd019ef78b72934c7cc) Nikita

Andrew Faulds

12 years ago
On 9 Jun 2014, at 15:12, Nikita Popov <nikita.ppv@gmail.com> wrote:
> So I think that this will not break much code. It is also easy to detect > and fix. (I am using this script to find potential problems: > https://gist.github.com/nikic/ffd019ef78b72934c7cc)
I like that you have a script. Myself, I’d like to see more of these. Since your PhpParser exists, if we make some major syntax change in PHP6, it might be possible to write a tool that would (semi-)automatically re-write code, similar to what Python’s 2to3 tool does.
-- Andrea Faulds http://ajf.me/

Florian Anderiasch

12 years ago
On 09.06.2014 15:33, Nikita Popov wrote:
> https://wiki.php.net/rfc/uniform_variable_syntax > > The RFC is targeted at PHP 6 because it breaks compatibility for some > rarely used variable-variable constructs.
I am all for consistency, but if I look at this:
>Example of expressions those meaning changes:
> // old meaning // new meaning > $$foo['bar']['baz'] ${$foo['bar']['baz']} ($$foo)['bar']['baz'] > Foo::$bar['baz']() Foo::{$bar['baz']}() (Foo::$bar)['baz']() > $foo->$bar['baz']() $foo->{$bar['baz']}() ($foo->$bar)['baz']()
Those last 2 lines (old meaning) are exactly as I would have read them without thinking. So.. either I just got used to some kind of subliminal rule over all these years or I'm missing something. They're not variable variables, either. Somewhere in the proposal you write "It follows normal left-to-right semantic". This sounds very good in theory, but right now it feels a little unintuitive. Greetings, Florian

Rowan Collins

12 years ago
Florian Anderiasch wrote (on 09/06/2014):
>> Foo::$bar['baz']() Foo::{$bar['baz']}() (Foo::$bar)['baz']() >> >$foo->$bar['baz']() $foo->{$bar['baz']}() ($foo->$bar)['baz']() > Those last 2 lines (old meaning) are exactly as I would have read them > without thinking. So.. either I just got used to some kind of subliminal > rule over all these years or I'm missing something.
I think it's somewhat subjective; it wouldn't have occurred to me that $foo->$bar['baz']() would evaluate $bar['baz'] rather than $foo->$bar. The advantage of the proposed behaviour is that it can be easily explained to *new* users of the language, as it's internally consistent, which appears not to be true of the old - an example in the RFC being |Foo::$bar[1][2][3] vs ||Foo::$bar[1][2][3]()| The ability for any length of expression to be evaluated consistently and according to an easily-explained logic makes this RFC a massive win for me unless anyone can come up with a case it changes that would already be in common use. If this had happened sooner, we wouldn't have needed separate RFCs for some_function()['array_key'] and (new Some_Class)->someMethod()
> They're not variable variables, either.
Technically, $foo->$bar is a "dynamic property access" (resolve the contents of $bar as a string, access that property), but it has a lot in common with what are commonly thought of as "variable variables"; if you have a class with property 'prop1', "normal" access would be via $foo->prop1, just as "normal" access to a variable would be $var1, not $$foo. There are slightly more cases where dynamic property access makes sense than plain variable variables (which can nearly always be replaced with an associative array), but exotic combinations like the ones affected here seem unlikely to be commonplace. Regards,
-- Rowan Collins [IMSoP]

Rowan Collins

12 years ago
Rowan Collins wrote (on 09/06/2014):
> The advantage of the proposed behaviour is that it can be easily > explained to *new* users of the language, as it's internally > consistent, which appears not to be true of the old - an example in > the RFC being |Foo::$bar[1][2][3] vs ||Foo::$bar[1][2][3]()|
A simpler example of the current logic's inconsistencies: $foo = 'foo'; $bar->$foo = array(); $bar->$foo[0] = 42; // $bar now has an array on ->foo, and an integer on ->f http://3v4l.org/pImS3 Not only does this not feel consistent in itself, it's different if you do the same thing with an object: $foo = 'foo'; $bar->$foo = new stdClass; $bar->$foo->x = 42; // $bar now has a single property ->foo, which is an object with property ->x http://3v4l.org/DUaJj Other than "it's always worked this way", I can't think of a good justification for this difference.
-- Rowan Collins [IMSoP]

Adam Harvey

12 years ago
On 9 June 2014 06:33, Nikita Popov <nikita.ppv@gmail.com> wrote:
> I have created a proposal for a more consistent and complete variable > syntax for PHP 6: > > https://wiki.php.net/rfc/uniform_variable_syntax > > The RFC is targeted at PHP 6 because it breaks compatibility for some > rarely used variable-variable constructs.
I like it. A Monday morning, pre-caffeine-kicking-in thought (so it may not be very worthwhile): can we detect the situations that would change with this patch applied within the current parser? If we did go ahead with this for PHP 5++, then we could potentially add E_STRICT warnings in PHP 5.7 notifying users that the behaviour will change in the next major version. Adam

Mike

12 years ago
On 09 06 2014, at 15:33, Nikita Popov <nikita.ppv@gmail.com> wrote:
> Hi internals! > > I have created a proposal for a more consistent and complete variable > syntax for PHP 6: > > https://wiki.php.net/rfc/uniform_variable_syntax
Thank you!

Julien Pauli

12 years ago
On Mon, Jun 9, 2014 at 3:33 PM, Nikita Popov <nikita.ppv@gmail.com> wrote:
> Hi internals! > > I have created a proposal for a more consistent and complete variable > syntax for PHP 6: > > https://wiki.php.net/rfc/uniform_variable_syntax > > The RFC is targeted at PHP 6 because it breaks compatibility for some > rarely used variable-variable constructs. > > Thanks, > Nikita
Nice proposal :-) Julien

Pierre Joye

12 years ago
hi Nikita, On Mon, Jun 9, 2014 at 3:33 PM, Nikita Popov <nikita.ppv@gmail.com> wrote:
> Hi internals! > > I have created a proposal for a more consistent and complete variable > syntax for PHP 6: > > https://wiki.php.net/rfc/uniform_variable_syntax > > The RFC is targeted at PHP 6 because it breaks compatibility for some > rarely used variable-variable constructs.
Very good RFC. Long due and php6 is really the right time to do it. As you said it should have a minimal impact on existing code. If accepted, it would be a good thing to add notices in 5.6 as well, if it does not impact performance too much. Cheers,
-- Pierre @pierrejoye | http://www.libgd.org

Stas Malyshev

12 years ago
Hi!
> If accepted, it would be a good thing to add notices in 5.6 as well, > if it does not impact performance too much.
I wouldn't be that fast with it, since notices are very expensive (compared to regular opcodes), and disabling them via error_level does nothing to mitigate that effect, and may easily lead to breakage in systems which have custom handlers - like unit tests, monitoring, etc. When we're going to 6, it's good to break things we want to change. When we're talking about 5.6, less disruption to existing working code the better.
-- Stanislav Malyshev, Software Architect SugarCRM: http://www.sugarcrm.com/ (408)454-6900 ext. 227

Nikita Popov

12 years ago
On Mon, Jun 9, 2014 at 3:33 PM, Nikita Popov <nikita.ppv@gmail.com> wrote:
> Hi internals! > > I have created a proposal for a more consistent and complete variable > syntax for PHP 6: > > https://wiki.php.net/rfc/uniform_variable_syntax > > The RFC is targeted at PHP 6 because it breaks compatibility for some > rarely used variable-variable constructs. >
Any more feedback on this? Otherwise I'll start the vote sometime soon :) Nikita

Lazare Inepologlou

12 years ago
2014-07-02 17:51 GMT+02:00 Nikita Popov <nikita.ppv@gmail.com>:
> On Mon, Jun 9, 2014 at 3:33 PM, Nikita Popov <nikita.ppv@gmail.com> wrote: > > > Hi internals! > > > > I have created a proposal for a more consistent and complete variable > > syntax for PHP 6: > > > > https://wiki.php.net/rfc/uniform_variable_syntax > > > > The RFC is targeted at PHP 6 because it breaks compatibility for some > > rarely used variable-variable constructs. > > > > Any more feedback on this? Otherwise I'll start the vote sometime soon :) > >
Yes, in the RFC, you mention that this will be possible: ($obj->closure)() While this is very welcome, I was wandering if we could skip the extra parenthesis, like this: $obj->closure() Likewise, this would also be nice: new ClassName->foo() Thanks, Lazare INEPOLOGLOU Ingénieur Logiciel

Andrew Faulds

12 years ago
On 2 Jul 2014, at 17:04, Lazare Inepologlou <linepogl@gmail.com> wrote:
> Yes, in the RFC, you mention that this will be possible: > > ($obj->closure)() > > While this is very welcome, I was wandering if we could skip the extra > parenthesis, like this: > > $obj->closure()
Sadly, it wouldn’t be possible as the two are very different. Properties and methods occupy completely different namespaces, and while methods are case-insentivie, properties are case-sensitive! ($obj->closure)() gets a property then calls it, while $obj->closure() calls a method. Perhaps this might change in future, but the RFC doesn’t propose that.
-- Andrea Faulds http://ajf.me/

Nikita Popov

12 years ago
On Wed, Jul 2, 2014 at 6:04 PM, Lazare Inepologlou <linepogl@gmail.com> wrote:
> > 2014-07-02 17:51 GMT+02:00 Nikita Popov <nikita.ppv@gmail.com>: > > On Mon, Jun 9, 2014 at 3:33 PM, Nikita Popov <nikita.ppv@gmail.com> wrote: >> >> > Hi internals! >> > >> > I have created a proposal for a more consistent and complete variable >> > syntax for PHP 6: >> > >> > https://wiki.php.net/rfc/uniform_variable_syntax >> > >> > The RFC is targeted at PHP 6 because it breaks compatibility for some >> > rarely used variable-variable constructs. >> > >> >> Any more feedback on this? Otherwise I'll start the vote sometime soon :) >> >> > Yes, in the RFC, you mention that this will be possible: > > ($obj->closure)() > > While this is very welcome, I was wandering if we could skip the extra > parenthesis, like this: > > $obj->closure() >
We could skip the extra parenthesis, but that would require changing the meaning of method calls. This discussion turns up every now and then, one of the more recent ones being http://markmail.org/message/3zi53txadno6xrqa. A key problem was always that supporting this would break BC. However that BC break may be acceptable for PHP 6, so the it might be worthwhile to reconsider the previous decisions regarding this issue. However this is not related to variable syntax (it is a question of method lookup semantics), so I would suggest opening a new discussion thread for this (and/or write an RFC for it).
> Likewise, this would also be nice: > > new ClassName->foo() >
This is problematic because the following would be ambiguous: new $className->foo() // could be (_current_ behavior) new ($className->foo)() // or (new $className)->foo() Of course we could resolve the ambiguity (towards the _latter_ interpretation) or special-case the plain-classname case. Both options do not seem very appealing to me. Imho it's better to keep the explicit syntax. Nikita

Rowan Lewis

12 years ago
How would you create a new callable object and then invoke it? Since 'nested' () is now supported: new MagicInvoke()(); Could be the same as: (new MagicInvoke())(); On Wed, Jul 2, 2014 at 7:25 PM, Nikita Popov <nikita.ppv@gmail.com> wrote:

Stas Malyshev

12 years ago
Hi!
> While this is very welcome, I was wandering if we could skip the extra > parenthesis, like this: > > $obj->closure()
The would mean uniting the property and method namespaces on an object, which has pretty big implications and may lead to huge BC issues. I'd rather not go there, it'd require serious change of the whole object model.
-- Stanislav Malyshev, Software Architect SugarCRM: http://www.sugarcrm.com/