Recommend this page to a friend! |
NamespaceSim | > | All threads | > | The future of this package | > | (Un) Subscribe thread alerts |
|
![]() If you're following the developers mailing list, you'll know by now that namespaces maybe coming soon to PHP. Also you may know that through the debate in this list I've come to realize that PHP namespaces are not quite yet.
I tried with this package to provide a namespace solution similar to what has been discussed on the last years in the PHP internals. Now I know they do not follow the "PHP way" (if such a thing ever existed). The reasons are as follows: * Before namespaces, there wasn't either an enforced scope on a statement nor a statement that's implicitly scoped to the file. Namespace related statements do this and only because we're copying Java syntax, and we didn't find a way to avoid the problems of implementing a C++ like syntax. * Namespaces introduction messed up the explicit nature of names resolution that PHP always had. This will harm code debugging and review. This is not cohesive with how PHP handles, for example, function scope resolution (remember having to use $this-> everywhere?) * An organization is enforced by the namespace implementation. The enforcement of scope in the namespace related statement, its almost forcing us to the Java way of organizing code, which I don't think it's bad, at least not for Java, but this is PHP, users should decide how to organize their code, not the compiler/interpreter. ----- Therefore, I'll try my best to complete version 0.6, but that's as far as I'll go with the current implementation. Unluckily, there'll be no 1.0 version, final version, stable, gold or whatever you wish to call it. I wish to put my efforts on a namespace solution that looks more the PHP way. I've currently two solutions in mind: ----- 1) Namespaces as longer class names (what we been doing all along) * :: is the separator for namespaces * classes are defined with the full name: class Foo::Bar { ... } * only classes can be namespaced, to avoid ambiguity caused by using the :: operator: Foo::bar(); // is it namespaced function bar or the member function bar() of Foo? * a namespace must always be present when accessing namespaced elements, so that they're not confused with global access: Foo::Bar::test(); // call test() in class Bar in namespace Foo Bar::test(); // call test() in global class Bar * special namespace package:: is an alias of the namespace of the current class (I still think using "package" as keyword is a better choice since "namespace" will collide with XML namespaces) * namespaces aliases can be declared through the statement use: use Long::Name::Space::Foo; new Foo::Bar; // create a Long::Name::Space::Foo::Bar * aliases are only for namespaces. This is a technical constraint, caused by the fact that namespaced are just name abbreviations, and constructs that exist in different realms than classes, increasing the complexity of the logic required for name resolution. * the use statement can only be used outside global scope. I don't want to enforce a file scope and I want to avoid problems which can be caused by aliases left in global scope (as it happens in C++). Probably the first implementation will only support use in function scope. ----- 2) Namespaces as nested classes * Mostly like (1) but with the following exceptions * Namespaces are actual classes. And these must be declared final (required design constraint. We can't have namespaces being used in inheritance: too complex) * Members of a namespaces must be declared, but not defined, inside the class that works as package. Forward declaration is used: final class IAmAPackage { public class Foo; private class Bar; } // the following can be in another file class IAmAPackage::Foo { ... } class IAmAPackage::Bar { ... } * use IAmAPackage::*; can be used to import everything of a package (we now know what a package holds) * use can alias anything since classes and namespaces and the same thing * a logarithmic order is expected in namespace access (the access has to descend through the classes hierarchy, which is expected to have a normal gaussian distribution). This can be improved by aliases defined be the use statement (the use will be a O(log N) operation, the alias acces an O(1)) * autoloading of class inside a package is deferred to the __autoload() of the class that acts like a package. This will substantially reduce the overhead produced by chained autoloads. The autoloading will occur as follows: $foo = new Long::Name::Space::Foo(); // __autoload('Long'); // Long::__autoload('Name'); // Long::Name::__autoload('Space'); // Long::Name::Space::__autoload('Foo'); $bar = new Long::Name::Space::Bar(); // Long::Name::Space::__autoload('Bar'); ----- (2) is a solution that's too complex to implement as a precompiler, which is what NamespaceSim actually is. It's a solution that's better handled directly by the compiler/interpreter. I'll try to mock up a simulation but I suspect it's just too hard to do it from userland.
![]() I forgot:
Those who have anything to say about this, talk now or forever hold your piece. =D |
info at phpclasses dot org
.