A language lives and dies by how easy it is for a person to express something within that language. But the ease in expression is much like the type I and type II error rate in a statistical test: as you adjust one to be nearer to where you want it to be, the other gets farther away. So the architects of a language have to choose between adding more keywords and constructs or having longer, but simpler sequences of existing ones.

PHP is a very easy language to learn and use because it has a syntax that is a simplified sampling from C++/Java and Perl. People who use these languages pick up PHP fast, and people who haven’t used any languages often learn PHP with as much ease as they would learn Perl.

A bit about namespaces

Most languages have namespaces in one form or another. A namespace is a lot like a class: it is a named entity that houses functions and classes, whereas a class is a named entity that houses properties and methods. Namespaces are found, in one form or another, in most popular languages. In C++ there are explicit namespaces and the namespace keyword. In Java, since you are allowed to have classes nested within classes, classes act as namespaces. Namespaces make it easier to organize and call your code. If you have a bunch of classes that work together to do something you might name them in a similar way. For example, we here at the Studios sometimes use the following classes:

Canopy_Xml_Document
Canopy_Xml_Document_CDataSection
Canopy_Xml_Document_NodeList
Canopy_Xml_IWritable
Canopy_Xml_Exception

With namespaces, we could define a namespace Canopy, add to it a namespace Xml, and then add classes Document, Exception and interface IWritable. We could also add a Document namespace and add classes CDataSection and NodeList. Then we could just tell PHP that we want to refer to things in a certain namespace. We would simply write:

use Canopy::Xml;
$D = new Document(); //$D is equivalent to a Canopy_Xml_Document

In the beta builds of PHP 5.3, the terminal “::” called the scope resolution operator (SRO) is used to denote namespaces. So, in the same way that one would write Class::staticMethod() one could write NamespaceA::NamespaceB::functionInNamespace(). This is the same operator used in C++, and it is intuitive since it refines a name to a scope where that name belongs.

PHPs SRO problem

Recently, PHP has had to abandon using the SRO, forego the syntax of other languages and has had to make up their own way of denoting a namespace. One reason for this is that bare words in PHP can have multiple meanings. For example, in PHP you can do:

const('A','constant');
function A() { return 'function'; }
class A(){ public _toString(){ return 'class'; } }

such that

echo A; // constant
echo A(); // function
echo new A(); // class

all do what you’d expect. But in namespaces, there’s some ambiguity introduced. Consider rather A::B::C() is namespace A, class B, static method C, or namespace A::B, function C. In C++ you’re not allowed to have a symbol like A, B, or C represent multiple types of things, so using the SRO does not arrive at ambiguity there. (Instead, you get an error.) But since PHP does allow for that type of thing, the internals team had to choose between:

  1. Not allowing namespaces to have functions, but rather only classes, thus raising the ire of the community.
  2. Using some terrible terrible other operator to indicate namespaces, thus raising the ire of the community. (Quoth internals team member: <@CelloG> % is also possible but holy god almighty it is fugly
  3. Put off namespaces until (or if) something decent can be figured out, thus raising the ire of the community.

The team decided on 2, going with the \ character.

What’s that mean for the language?

The discussion was concerned with preventing unanticipated behavior from just making a rule to disambiguate rather a function or static method is called. I feel that throwing an error (or warning and choosing one) whenever that situation arises would be a perfectly acceptable solution. I would also have been happy to see them further follow Java’s lead and allow classes to be nested. Then there is no ambiguity between a static method and a function because they are the same. This would probably require much more work and you would have to allow class definitions across multiple files, but I feel this is a better option than ‘\’. To that end I would have enjoyed option 1 over option 2.

The most cited complaints about PHP is how there is little consistency in function names and in argument order. This new ‘\’ operator adds to the “weird-factor” which makes it more difficult for people to read and use the language. It further marginalizes PHP, adding to a series of minor but obnoxious issues proponents are embarrassed by.

The language is adrift with little direction, trying to address the wants of its developers, and adding a terminal is payment for a lack of planning and a general stubbornness of the internals list to consider namespaces back when the 5 changes were initially being discussed. On one hand I feel like this has ominous portents for PHP, but on the other, I’m really happy to have namespaces. For our domain, it still doesn’t make sense to jump ship to Groovy or Python, and it would take a lot of new terminals to push us over the edge. And while it’d be nice to see PHP not give more ammo to detractors, however menial, the discussion log makes it clear what issues they were struggling with.

Frederik Holmström points out another flaw with the backslash, as well, but many commenters note that the internals team knew there was no perfect solution here.

Posted in: Articles, Development