Daniel Convissor wrote: > On Mon, Sep 22, 2008 at 08:07:10PM +0400, Dmitry Stogov wrote: > >> Yes. Changing :: into any other separator solves the functions/static >> methods and constants ambiguity, but it also breaks intuitive syntax. > > Which is more important? Considering there have been threads upon > threads filled with myriad messages, it seems resolving the ambiguity is > significanly more important than an intuitive syntax. > > Please, let's pick a different operator for namespaces. This will > eliminate the scoping/resolution issues for both the engine and the > humans trying to interpret PHP code. > > [/me searching for the vote tally on which operator people preferred] > [/me alas, can't find it at the moment] > > I recall there being a vote on this. I'm sure some of you have a saved > copy and/or link to it. Can't we pick the operator on that list that got > the second highest vote count?
Hi, The second highest vote was :::, but there was strong objection to this as well from some. The problem, I still believe, is that we are focused on having the same:::stupid:::operator:::between:::everything. The truth is that in source files, there is a clear boundary between namespace definition as in: <?php namespace foo::bar; ?> and the things in the namespace, as in: <?php class bar {} ?> Without context, the above definition of class bar could define literally any class name: bar something::bar another::long::name::bar depending on the namespace declaration at the top of the file. This means that it is an arbitrary choice in the current implementation to use "::" to join the two things (namespace name and class name). In truth, it will be a lot easier to debug code if this is a different separator, as the boundary between namespace and element will be crystal clear. For instance: (current implementation) my::framework::someFunction()->aProperty->someMethod(); is my::framework a class or a namespace? Let's use an arbitrary separator .. to mark the boundary between namespace and class/function (new implementation) my::framework..someFunction()->aProperty->someMethod(); OK, now we know that my::namespace is a namespace, and someFunction is a function. my..framework::someFunction()->aProperty->someMethod(); The above is also clear: my is a namespace, framework is a class name, and someFunction is a static method. This has the advantage that existing code based on PHP 5.3 alpha 1 and 2 won't require very much modification, it is easy to read, and easy to understand what a line of code does without needing any context information. I took my old patch and moved from the -> separator to the .. separator in about 45 minutes of work, so changing the separator will not be difficult. Here's the new patch against PHP_5_3: http://pear.php.net/~greg/ns.element.2.patch.txt Unlike the first patch, it introduces a new token, T_NS_MEMBER, instead of recycling T_OBJECT_OPERATOR. This is also easy to document. Here's how I would do it: Although namespaces can span multiple files, they are similar to static classes. Namespaces are used in PHP to link related classes, functions, and constants much as static classes can be used to link related variables, methods, and constants. The classes, functions, and constants defined in a namespace are called "namespace elements" just as the variables, methods and constants defined in a static class are "static class members" A static class example: <?php class myclass { const one = 1; static public $a; static function show() { echo __METHOD__,"\n"; } } myclass::show(); $variable = myclass::$a; echo myclass::one; ?> Static class members can be accessed using the :: operator, as in "myclass::show()". Here is a namespace example: file1.php: <?php namespace mynamespace; const one = 1; function show() { echo __FUNCTION__,"\n"; } class myclass { function show() { echo __METHOD__,"\n"; } } class mystaticclass { static function show() { echo __METHOD__,"\n"; } } ?> main.php: <?php include 'file1.php'; mynamespace..show(); echo mynamespace..one; $a = new mynamespace..myclass; $a->show(); ?> Namespace elements can be accessed using the .. operator, as in "mynamespace..show()". Another example showing how to access static class members within a namespace: <?php include 'file1.php'; mynamespace..mystaticclass::show(); ?> Namespaces can be nested using the "::" operator as in: file2.php: <?php namespace my::nested::ns; class mystaticclass { static function show() { echo __METHOD__,"\n"; } } ?> The "use" statement allows importing both namespace elements and namespace names into the current scope: <?php include 'file1.php'; incldue 'file2.php'; use mynamespace..mystaticclass; use my::nested::ns; use my::nested; use my::nested::ns..mystaticclass as myclass; mystaticclass::show(); // mynamespace..mystaticclass::show() myclass::show(); // my::nested::ns..mystaticclass::show() ns..mystaticclass::show(); // my::nested::ns..mystaticclass::show() nested::ns..mystaticclass::show(); // my::nested::ns..mystaticclass::show() ?> Nesting of namespaces occurs like so: <?php namespace my::nested; include 'file2.php'; ns..mystaticclass::show(); // my::nested::ns..mystaticclass class someclass extends ns..mystaticclass {} ?> The statement "ns..mystaticclass::show()" is automatically expanded into "my::nested::ns..mystaticclass::show()". Thanks, Greg -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php