RFC: Arguments (and suggestions) against the current implementation of namespaces

php.internals

Martin Alterisio

18 years ago
1) Lack of cohesiveness of name resolution rules Why is this an argument against: name resolution rules with namespaces change completely the way names are resolved in PHP. How does it affects: this breaks the explicitness of names in PHP. It will affect code debugging and review. Example: <?php . . . // many lines before this foo(); // is it a global function or a namespaced function? A::foo(); // is it a member function? a namespaced function? a global class? a namespaced class? ?> Suggestions: a) Introduce a special name to refer to the current namespace (as self:: works for the current class). All namespace access should be explicit: <?php . . . // many lines before this foo(); // a call to global foo() and nothing else namespace::foo(); // a call to foo() in the current namespace ?> b) Name aliasing with use should only generate namespaces aliases: <?php use Really::Long::Namespace as Short; $object = new Short::AClass(); use Really::Long::Namespace::AClass; // should make AClass an alias to a namespace, not a class $object = new AClass(); // should look for global AClass ?> c) Solve ambiguity generated by using :: as namespace separator (see following argument) ---- 2) Using :: as namespace separator generates ambiguity Why is this an argument against: :: is also used for static member access and becomes ambiguous when used together How does it affects: same as (1). Example: <?php ... Foo::test(); // a member function? a namespaced function? ?> Suggestions: a) find a way to clearly distinguish the namespace part of a name (I've currently no suggestions on what operator to use without seriously harming readability). b) OR restrict the namespace application to classes (if only classes can be namespaced there is no ambiguity, although I must admit I don't like this option). ---- 3) Enforcing a scope is something that has no precedence in the PHP language What: the namespace statement and the import statement (use) has an enforced scope to the file. Why is this an argument against: there was not a construct that works as this one in PHP. How does it affects: it changes the way we work with code. We now how to be conscious of declarations enforced on the whole file, not because we messed up with scopes but because we didn't have a choice. Suggestions: a) Allow the before mentioned statements to have scope managed by the coder. b) Disallow the scopeless use of those statements (which is implicitly scoped to the file). c) If bracketed namespaces are a no-go, consider the possibility of declaring the full name of the namespaced element in its definition: <?php class Name::Space::ClassName { ... } ?> Which should work as: <?php namespace Name::Space { class ClassName { ... } } ?>

Stanislav Malyshev

18 years ago
> a) Introduce a special name to refer to the current namespace (as self:: > works for the current class).
namespace::
> All namespace access should be explicit:
Consequence: nobody uses namespaces, as it's too annoying.
> b) Name aliasing with use should only generate namespaces aliases:
See no reason for that limitation. Used in moderation, class aliasing is OK. Main thing is not to rely on it for everything.
> 2) Using :: as namespace separator generates ambiguity
Would that be 20th reincarnation of "let's find weirdest namespace separator" thread? :)
> <?php > ... > Foo::test(); // a member function? a namespaced function? > ?>
Sometimes you need context. When you just take $foo->bar() it doesn't give you much - you should know what $foo is and what bar() does.
> Why is this an argument against: there was not a construct that works as > this one in PHP.
This is not an argument - each construct works as needed for it to work to achieve its purpose.
> c) If bracketed namespaces are a no-go, consider the possibility of > declaring the full name of the namespaced element in its definition:
Which would lead to people routinely mixing different namespaces inside one file. Bad idea. Also would kill namespaced functions and constants, which would make organizing libraries using those impossible.
-- Stanislav Malyshev, Zend Software Architect stas@zend.com http://www.zend.com/ (408)253-8829 MSN: stas@zend.com

Martin Alterisio

18 years ago
2007/12/10, Stanislav Malyshev <stas@zend.com>:
> > > All namespace access should be explicit: > > Consequence: nobody uses namespaces, as it's too annoying.
Putting $this-> and self:: is annoying , that didn't stop anybody from using objects in PHP.
> b) Name aliasing with use should only generate namespaces aliases: > > See no reason for that limitation. Used in moderation, class aliasing is > OK. Main thing is not to rely on it for everything.
Maybe, but then I'll suggest that these aliases are accessed through namespace:: or similar.
> 2) Using :: as namespace separator generates ambiguity > > Would that be 20th reincarnation of "let's find weirdest namespace > separator" thread? :)
Please no. Just find the right one.
> <?php > > ... > > Foo::test(); // a member function? a namespaced function? > > ?> > > Sometimes you need context. When you just take $foo->bar() it doesn't > give you much - you should know what $foo is and what bar() does.
But you still know that $foo->bar is a member function call. That information only makes code review and debugging a lot easier. The current implementation of namespaces introduces a lot of uncertainty. I do not need to tell you how hard and time consuming it is to debug or review C++ code. I beg you, please do not make PHP a language that's as harder to debug or review. And even if you say "sometimes you need context", be prepared to be asked "why now?". Why context was not applied inside a class definition? Why do I have to use $this-> or self::? Why is there no with ($object) { ... } ?
> Why is this an argument against: there was not a construct that works as > > this one in PHP. > > This is not an argument - each construct works as needed for it to work > to achieve its purpose.
So, every construct of a language works as a distinct unit? There's no need to keep cohesiveness with how other constructs behave? We'll have to accept that now there'll be statements that enforces a scope? No problem then, I'll start training my brain to remember the namespaces and imports of each file. Maybe it makes sense in a language like Java that also enforces a directory structure, but PHP?
> c) If bracketed namespaces are a no-go, consider the possibility of > > declaring the full name of the namespaced element in its definition: > > Which would lead to people routinely mixing different namespaces inside > one file. Bad idea. Also would kill namespaced functions and constants, > which would make organizing libraries using those impossible.
Why would it lead to people routinely mixing different namespaces inside one file? Why is this bad in the first place? Why is it the language the one to decide which is the better way to organize code? Also, that would not kill neither namespaced functions nor constants: <?php function namespaced::foo() { ... } const namespaced::CONST = "I'm namespaced!"; ?>

Martin Alterisio

18 years ago
2007/12/10, Martin Alterisio <malterisio777@gmail.com>:
> > > > 2) Using :: as namespace separator generates ambiguity > > > > Would that be 20th reincarnation of "let's find weirdest namespace > > separator" thread? :) > > > Please no. Just find the right one. >
PS: Wasn't : (one colon) used as namespace separator in early stages of PHP5?

Martin Alterisio

18 years ago
2007/12/10, Martin Alterisio <malterisio777@gmail.com>:
> > > > c) If bracketed namespaces are a no-go, consider the possibility of > > > declaring the full name of the namespaced element in its definition: > > > > Which would lead to people routinely mixing different namespaces inside > > one file. Bad idea. Also would kill namespaced functions and constants, > > which would make organizing libraries using those impossible. > > > Why would it lead to people routinely mixing different namespaces inside > one file? > Why is this bad in the first place? > Why is it the language the one to decide which is the better way to > organize code? > > Also, that would not kill neither namespaced functions nor constants: > > <?php > function namespaced::foo() { > ... > } > const namespaced::CONST = "I'm namespaced!"; > ?>
PS: An example of an organization model that wouldn't be possible with the current implementation of namespaces: Imagine that I'm writing a small module for my app. Just a main class, some helper classes and exceptions. For the purposes of this module I just find more organized to keep everything in a one file. Also, I expect exceptions only to be raised in most exceptional cases, therefore I see that is best to keep them in a subordinated but different namespace. I have two namespaces, e.g.: MyModule and MyModule:Exceptions, but I can't keep them in the same file. I don't see the point on having the exceptions in a different file, and I really prefer to keep the main namespace of my module as clean as possible. The language just took away the possibility to decide which organization schema I prefer.

Sam Barrow

18 years ago
Agreed. I don't see any point in this limitation. As for confusion, debugging would not be too hard (just echo __NAMESPACE__), or brackets would solve that problem. On Mon, 2007-12-10 at 16:59 -0300, Martin Alterisio wrote: