Become a Patron!

My Amazon wishlist can be found here.

Life Line

No to a Uniform Variable Syntax

As you might have heard, PHP developers voted on an RFC called "Uniform Variable Syntax". This RFC "proposes the introduction of an internally consistent and complete variable syntax". In general, this RFC argues for making PHP's parser more complete for all sorts of variable dereferences. For example:

$foo()['bar']()
[$obj1, $obj2][0]->prop
$foo->bar()()
$foo::$bar::$baz

Thirty people voted for, and one against: Me.

Does that mean that I am against a unified variable syntax? No, I am not. I am actually quite a fan of having a consistent language, but we need to be careful when changes hits existing users.

The already accepted RFC also has some negative aspects, in the form of backwards compatibility (BC) breaks. For example (quoted from the RFC):

// syntax               // 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']()
Foo::$bar['baz']()      Foo::{$bar['baz']}()      (Foo::$bar)['baz']()

This basically says that the RFC author knows there are BC breaks, but choses to ignore how this might annoy users.

Unlike keyword additions, or functions and/or settings being removed, this change in semantics is probably one of the worst BC breaks you can imagine. You can't really write a scanner for it, as the code could already have been converted. A tiny change like this however, can create very hard to debug issues within existing code. And this is exactly why people whine that PHP breaks BC and does not care about its users. In many cases, breaking BC happens by accident, and I'm no stranger to breaking BC due to some oversight. Accidents like this are certainly annoying, but slightly unavoidable as we do not have test cases for everything.

However, when you know for certain that you are going to break BC, there is no excuse. With such a marginal new "feature" as is outlined in this RFC, antagonising our users is not a good thing.

Shortlink

This article has a short URL available: https://drck.me/nobc-b11

Comments

Thank you.

I voted in favor of this RFC knowing full well that it represented a BC break. I was okay with this for one major reason:

The RFC was explicitly offered for inclusion in the next major (PHP6, PHP7, whatever people want to call it).

This is precisely what major versions are for: improvements that might break backwards compatibility in exchange for a better language. Is BC critically important for the success of any language? Absolutely. Is this break justifiable for a major version? In my opinion, absolutely.

If this RFC were offered for any minor version I would have been strenuously against it. Thankfully, that was not the case. Any user upgrading to a new major version with the expectation that all existing code will "just work" is destined for problems regardless. Such users must not be held out as justification for holding back language progress.

Just my two cents on the subject :)

Daniel,

Even for a new major version being able to break BC doesn't mean it's good. Changing BC adds costs to everybody in the environment. Developers having to review the code, IDE developers, tool developers, ...

This case might actually be bad - you have to be very careful in a review to find this and figure out whether the old or new way is expected.

As Bjarne Stroustrup says: "Compatibility is a feature." To existing users who can stay up to date easily as well as to new users who can be assured that their investment is safe. Randomly changing the language doesn't do that. Randomly changing the language tells "be prepared to continuously reviewing your code for breakage" instead of helping them solving their actual issues. Staying up to date should not be an issue for any user.

well, daniel, the thing is, the more BC breaks are in the more legacy you will have aftewards - we now have PHP5 for 10 years, and still there are a few PHP4 users left, because their stuff is not running on PHP5.

Thats a bad thing.

And i'm sorry, but this is not "lets break some minor thing to get a huge benefit", and after just reading this RFC i have to disagree on the "low practical impact" of the BC break.

I agree with you, of course. Historical compatibility is one of PHP's best attributes and must not be discarded lightly. Any BC break must be weighed against the potential havoc it may create in existing codebases. Whether or not a change justifies potential breakage is in the purview of the voting process. The hard part is striking a balance between progress and compatibility. The voting process (in theory) brings the wisdom (hopefully) of the group to bear on this determination.

I don't think anyone wants to see PHP in a Python 3 situation, and for that, Derick's opinion here is 100% valid. Caution and patience are the best antidotes to introducing new WTFs going forward.

Sorry Derick, but i might desagree with your vote.

I'm no expert in the core concepts of PHP, i'm speaking as an user, and as an user that in the past one or two years saw tecnologies like hack, a fork of PHP, being ovacionated just for the fact that they did what PHP was affraid to do, Break BC.

As Daniel Lowrey said and i quote "This is precisely what major versions are for". PHP should evolve and just the fact that some old users with legacy code don't have the courage to grow up and learn how the language evolve in the last 10 years does not change the necessity of evolution that moves the more active community.

In fact i think this is less then the expected but is already a start, i think many more BC breaks should and must be made in order to place the PHP in the new era, or we will loose the train (again).

And you don't need to look too far to see that hungry for change, since this changes doesn't not come from the language itself they grow up widely on the community, the examples are vast, composer, hack, hhvm, FIG and many others are all examples of changes being made on the margins of the language.

Please as an user I ask, bring these changes and this thirsty for changes to the core of the language and stop being so corservatives, lets grow up all together.

Thanks

@Paulo do not confuse new technologies being talked-about on the interwebs with their adoption rate. Do you know many people running today their Wordpress on hhvm?

I was a proponent of the "go-php5" initiative, and I remember how it took a concerted effort of all the major players at the time to get adoption of version 5 kickstarted (which was not, mind you, the abandoning of version 4).

Php is much bigger today, and BC breaks in syntax can not happen unless there is agreement and aoption from:

  • frameworks

  • major apps (cms, etc)

  • operating systems bundling the new version

@gggeek yes, i do know many people running or at least testing wordpress applications, zend framework apps, symfony apps, laravel apps and many more on hhvm, in fact we did a hangout talking just about it, is in portuguese but you can see here: https://www.youtube.com/watch?v=3tGiK4hXDag

And the community arround the most widely used frameworks and applications are exactly the one pushing foward to see new features and changes on PHP, and operating systens will just use the most recent version avaliable on the launch date.

I know that any change is hard to adopt, but they are needed and postpone this changes is not a solution, is just pass the problem ahead, so i rather see this changes now and at once than see it being made in installments.

Hi Derick!

Thank you for writing this post. I think you are right that BC is very important and we should pay attention and try to avoid breaking it as much as possible. But there are things that I disagree with this post. I think main thing I disagree with is that this is a marginal feature. I think the time has come in PHP's life when it's mature enough to try and fix some of the mistakes of its more youthful and careless years. If you look at the meanings table you quote, and hide everything but the leftmost column and forget all BC and just ask yourself - what what I would expect, naively, this to mean - and then open the other two columns again, I think you will discover that in most cases the naive expectation matches the "new" column. Yes, for various reasons, both good and not so good, it was not so in PHP. But we can make it so, and a major version is a good opportunity to do it. Major version is expected to break some things. That does not mean it should, but it is an acceptable price if necessary.

I think it is a big service to our users, most current and future, to try and make their expectations match the reality. Yes, we will have to pay for it, with BC breakage and some temporary pain while moving to PHP.Next. We can ease this pain with tools, etc. but we know we will not be able to avoid it. But once the debt is paid, we'd have much cleaner and consistent language, and I think it is a big win. PHP.Next, which is being started now, is a major opportunity to get such fixes - an opportunity the like of which we probably won't have for another decade or so in PHP. Thus, in my opinion, using this opportunity to fix some of PHP's less appealing parts is not marginal. Compatibility is a feature, yes, but so is cleanness and easiness of use. I think if we have to sacrifice a little of the former to gain a sizeable deal of the latter, it is a worthy investment.

PHP has always been a large collection of inconsistent behavior, even after 14 years of the stuff I still find myself looking up the order of arguments in the manual.

Please please PLEASE vote for every single suggestion that makes it more consistent. Yes that will break BC, but PHP programmers waste a truckload of time trying to deal with the current inconsistencies. It is a lot easier to debug code that has been broken by a newer, more consistent behavior, than by the current inconsistencies.

There is no question that breaking BC, major version or not, can lose you users, and it is always a balancing act. At the same time, not breaking BC can also lose you users.

After more than 10 years of writing PHP and building my entire profressional career on it, I left the community because inconsistencies like this made it impossible to write the kind of functional code that I wanted to write. Frankly, it didn't make sense to me that the language would behave in such an unexpected way, and admittedly I didn't know until recently that the cause was way more fundamental to the internals than I expected.

In any case, this RFC addressed what was easily my biggest complaint about PHP, and I think it is awesome.

Derick, in no way am I upset that you voted against this proposal, but I do hope you consider the benefits of a BC break as well as the hardships. As I said before, it's always a balancing act, but sometimes breaking compatibility is good for the greater community.

Hi Derick,

I really get you point here and being an Obj C developer we have been through a few ugly shifts.

One shift was going from manual reference counting to Automatic Reference Counting. Objective c was pretty good at converting code sometimes but other times not so hot and you have to go fix it.

  1. I do think it would be possible to write a scanner to fix it but the scanner would need to comment the fix so it does not fix it twice. I dont know what the comment would look like but it would mark the function somehow.

  2. With Obj-c we always had a fallback and told the compiler NOT to compile a list of files as ARC and could use the old syntax for this list of files.

For PHP to remain backward compatible I would suggest that a file, names space or directory could be marked as non Uniform Variable Syntax so it would be possible to continue to use these massive libraries that exist today yet have the app code using the new syntax.

John.

Hi Derick, PHP dev here.

I completely agree with you that introducing BC break changes can fall people into problems with existing code.

But think of it another way.

PHP5 was released 10 years ago, but there still are people who write code or libraries that are written in PHP4. Or let's take PHP5.3 which was released 5 years ago, but only recently hosting providers started upgrading PHP version to newer versions.

The point is - upgrading version is always painful and not one-week/month/year thing. People to whom the major version upgrade will cause troubles will either stick to current version or spend some time to fix all BC troubles it caused.

And it's not only about PHP. There're plenty of libraries (no matter what language they're written in) that introduce new changes that are not BC. We always have either to maintain our code to conform them or leave the codebase at some snapshot that is satisfying customer needs.

Just my 2 cents.

Hey Derick

I don't have my own 2 cents to throw in; I just want to say thanks for publicly explaining your opinion. Seeing so many for and one against on the vote made me very curious to know the reasoning.

Thanks

I really understand your point of view. The fact that BC are taken lightly makes me a little bit sad.

In my last few companies, we were always years and years behind the cutting edge. Once your codebase grows to hundreds of thousands of lines of code you are stuck. Any breaking change is a disaster to deal with.

We have just finished migrating rest of our platforms to PHP 5.3 this year and it was a gigantic effort. Doing it all over again with breaking changes? I am not sure if I even want to think of it.

Personally, I could not care less whether I can $foo()['bar']() or not. It has never been an issue for past 10 years and believe me I was pretty busy writing code. If anything, I am a bit worried that people may start abusing it making code an absolute mess.

Thanks for a nice post.

I absolutely can't agree with Derick. This BC break is really not so relevant. As a pretty long time PHP developer I never (attn - NEVER) used such ugly constructions in my code. I guess no major frameworks or quality projects even notice this change.

One of the PHP problems - it has too much of unpredictable "magic". This RFC makes some part of it consistent and logical. If some shit-code relies on tricky behaviour and breaks from such change - this shouldn't stop from making language better for use in real projects.

As I said, I never used such constructions and some examples from "old meaning" look absolutely unlogical for me. If they really now works as mentioned - this SHOULD be changed.

For example: just looking at the code "Foo::$bar['baz']" I can guess this means "get class Foo, found static field $bar in it and get value with index baz from that array". This is the way it works for another languages and I have no idea why this by default should mean "get value from $bar['baz'] and static field with that name from class Foo". If someone want such or some another behaviour - he can use brackets to group identifiers as he want.

Add Comment

Name:
Email:

Will not be posted. Please leave empty instead of filling in garbage though!
Comment:

Please follow the reStructured Text format. Do not use the comment form to report issues in software, use the relevant issue tracker. I will not answer them here.


All comments are moderated