Hi all,
There is a problem in the namespace implementation. This code
demonstrates the issue:
code.inc:
<?php
namespace foo;
class test {
const my = 1;
static function bar(){}
}
namespace foo::test;
const my = 2;
function bar(){}
?>
main.php:
<?php
include 'code.inc';
foo::test::bar(); // always calls namespace function
call_user_func(array('foo::test', 'bar')); // the only way to call
static method
echo foo::test::my; // always 2
$a = new foo::test;
echo $a::my; // the only way to access foo::test::my
?>
There are 5 ways to solve this:
- document it and hope no one uses it [this is the current strategy,
minus the documentation part] - add a fatal error on conflicting names.
http://pear.php.net/~greg/ns_method.func.conflict.patch.txt
Unfortunately, this can only work for methods/functions, as namespace
constants are actually defined at run-time, and so conflicts can't be
detected until then, which does not provide any benefit (you want to
catch this conflict at compile-time).
- create a disambiguation method.
http://pear.php.net/~greg/ns.func_const.patch.txt
This introduces function:: and const:: as prefixes to disambiguate.
<?php
function::foo::test::bar(); // always calls namespace function
foo::test::bar(); // always calls static method if defined, falls back
to ns function if not
const::foo::test::my; // namespace constant
foo::test::my; // class constant
?>
The drawback of this approach is that "foo::test::bar" will always look
for class "foo::test", which means if autoload is defined, it will be
called for all non-prefixed function calls. Unfortunately, the only
other keyword for disambiguating would be "class::" as in
"class::foo::test::bar()" but this is excessively confusing.
- remove functions/constants from namespaces
- a simply syntax change to namespaces, introducing a new concept:
namespace element.
A namespace element is a class, function or constant defined within a
namespace declaration:
<?php
namespace foo;
class bar {} // class element bar in namespace foo
function bar(){} // function element bar in namespace foo
const bar=1; // const element bar in namespace foo
?>
This is similar to class elements:
<?php
class foo {
function bar(){} // method element bar in class foo
const bar=1; // constant element bar in class foo
public $bar=1; // variable element bar in class foo
}
?>
Currently, this code:
<?php
namespace foo::bar;
class buh{}
?>
creates a class named "foo::bar::buh", essentially joining the namespace
"foo::bar" and its class element "buh" with the separator "::". This
turns out to be the root of the problem with the conflicts between class
elements and namespace elements. The last patch introduces a new
namespace element operator to delineate the boundary between namespace
name and element name. For the patch, I recycled T_OBJECT_OPERATOR
(->).
current way:
<?php
foo::bar->test(); // namespace foo::bar, call to function element test()
foo->bar::test(); // namespace foo, call to static method element test()
in class element bar
foo->myconst; // namespace foo constant myconst
foo::myconst; // class foo constant myconst
?>
The patch is at:
http://pear.php.net/~greg/ns.element.patch.txt
This is the most extensive change. The patch preserves :: as global
element accessor (::strlen() calls strlen internal function, for
instance). I'm happy to answer any other questions.
So, these are the choices. I suggest we all take a rational look at the
options, and understand the consequences of each, and make the best
choice possible.
Thanks,
Greg
Hello,
Hi all,
There is a problem in the namespace implementation. This code demonstrates
the issue:code.inc:
<?php
namespace foo;
class test {
const my = 1;
static function bar(){}
}namespace foo::test;
const my = 2;
function bar(){}
?>main.php:
<?php
include 'code.inc';
foo::test::bar(); // always calls namespace function
call_user_func(array('foo::test', 'bar')); // the only way to call static
method
echo foo::test::my; // always 2
$a = new foo::test;
echo $a::my; // the only way to access foo::test::my
?>There are 5 ways to solve this:
- document it and hope no one uses it [this is the current strategy, minus
the documentation part]- add a fatal error on conflicting names.
http://pear.php.net/~greg/ns_method.func.conflict.patch.txt
Unfortunately, this can only work for methods/functions, as namespace
constants are actually defined at run-time, and so conflicts can't be
detected until then, which does not provide any benefit (you want to catch
this conflict at compile-time).
- create a disambiguation method.
http://pear.php.net/~greg/ns.func_const.patch.txt
This introduces function:: and const:: as prefixes to disambiguate.
<?php
function::foo::test::bar(); // always calls namespace function
foo::test::bar(); // always calls static method if defined, falls back to ns
function if not
const::foo::test::my; // namespace constant
foo::test::my; // class constant
?>The drawback of this approach is that "foo::test::bar" will always look for
class "foo::test", which means if autoload is defined, it will be called for
all non-prefixed function calls. Unfortunately, the only other keyword for
disambiguating would be "class::" as in "class::foo::test::bar()" but this
is excessively confusing.
- remove functions/constants from namespaces
- a simply syntax change to namespaces, introducing a new concept:
namespace element.A namespace element is a class, function or constant defined within a
namespace declaration:<?php
namespace foo;
class bar {} // class element bar in namespace foo
function bar(){} // function element bar in namespace foo
const bar=1; // const element bar in namespace foo
?>This is similar to class elements:
<?php
class foo {
function bar(){} // method element bar in class foo
const bar=1; // constant element bar in class foo
public $bar=1; // variable element bar in class foo
}
?>Currently, this code:
<?php
namespace foo::bar;
class buh{}
?>creates a class named "foo::bar::buh", essentially joining the namespace
"foo::bar" and its class element "buh" with the separator "::". This turns
out to be the root of the problem with the conflicts between class elements
and namespace elements. The last patch introduces a new namespace element
operator to delineate the boundary between namespace name and element name.
For the patch, I recycledT_OBJECT_OPERATOR
(->).current way:
<?php
foo::bar->test(); // namespace foo::bar, call to function element test()
foo->bar::test(); // namespace foo, call to static method element test() in
class element bar
foo->myconst; // namespace foo constant myconst
foo::myconst; // class foo constant myconst
?>The patch is at:
http://pear.php.net/~greg/ns.element.patch.txt
This is the most extensive change. The patch preserves :: as global element
accessor (::strlen() calls strlen internal function, for instance). I'm
happy to answer any other questions.So, these are the choices. I suggest we all take a rational look at the
options, and understand the consequences of each, and make the best choice
possible.Thanks,
Greg
Good work, but I (and I'm probably not alone) can't really keep up
with all those namespace threads and proposals for changes and
resolution fixes and this and that,so :
Please use our nice RFC system!
Regards
--
Etienne Kneuss
http://www.colder.ch
Men never do evil so completely and cheerfully as
when they do it from a religious conviction.
-- Pascal
2008/9/20 Etienne Kneuss colder@php.net:
Hello,
Hi all,
There is a problem in the namespace implementation. This code demonstrates
the issue:code.inc:
<?php
namespace foo;
class test {
const my = 1;
static function bar(){}
}namespace foo::test;
const my = 2;
function bar(){}
?>main.php:
<?php
include 'code.inc';
foo::test::bar(); // always calls namespace function
call_user_func(array('foo::test', 'bar')); // the only way to call static
method
echo foo::test::my; // always 2
$a = new foo::test;
echo $a::my; // the only way to access foo::test::my
?>There are 5 ways to solve this:
- document it and hope no one uses it [this is the current strategy, minus
the documentation part]- add a fatal error on conflicting names.
http://pear.php.net/~greg/ns_method.func.conflict.patch.txt
Unfortunately, this can only work for methods/functions, as namespace
constants are actually defined at run-time, and so conflicts can't be
detected until then, which does not provide any benefit (you want to catch
this conflict at compile-time).
- create a disambiguation method.
http://pear.php.net/~greg/ns.func_const.patch.txt
This introduces function:: and const:: as prefixes to disambiguate.
<?php
function::foo::test::bar(); // always calls namespace function
foo::test::bar(); // always calls static method if defined, falls back to ns
function if not
const::foo::test::my; // namespace constant
foo::test::my; // class constant
?>The drawback of this approach is that "foo::test::bar" will always look for
class "foo::test", which means if autoload is defined, it will be called for
all non-prefixed function calls. Unfortunately, the only other keyword for
disambiguating would be "class::" as in "class::foo::test::bar()" but this
is excessively confusing.
- remove functions/constants from namespaces
- a simply syntax change to namespaces, introducing a new concept:
namespace element.A namespace element is a class, function or constant defined within a
namespace declaration:<?php
namespace foo;
class bar {} // class element bar in namespace foo
function bar(){} // function element bar in namespace foo
const bar=1; // const element bar in namespace foo
?>This is similar to class elements:
<?php
class foo {
function bar(){} // method element bar in class foo
const bar=1; // constant element bar in class foo
public $bar=1; // variable element bar in class foo
}
?>Currently, this code:
<?php
namespace foo::bar;
class buh{}
?>creates a class named "foo::bar::buh", essentially joining the namespace
"foo::bar" and its class element "buh" with the separator "::". This turns
out to be the root of the problem with the conflicts between class elements
and namespace elements. The last patch introduces a new namespace element
operator to delineate the boundary between namespace name and element name.
For the patch, I recycledT_OBJECT_OPERATOR
(->).current way:
<?php
foo::bar->test(); // namespace foo::bar, call to function element test()
foo->bar::test(); // namespace foo, call to static method element test() in
class element bar
foo->myconst; // namespace foo constant myconst
foo::myconst; // class foo constant myconst
?>The patch is at:
http://pear.php.net/~greg/ns.element.patch.txt
This is the most extensive change. The patch preserves :: as global element
accessor (::strlen() calls strlen internal function, for instance). I'm
happy to answer any other questions.So, these are the choices. I suggest we all take a rational look at the
options, and understand the consequences of each, and make the best choice
possible.Thanks,
GregGood work, but I (and I'm probably not alone) can't really keep up
with all those namespace threads and proposals for changes and
resolution fixes and this and that,so :Please use our nice RFC system!
Regards
--
Etienne Kneuss
http://www.colder.chMen never do evil so completely and cheerfully as
when they do it from a religious conviction.
-- Pascal--
How feasible would it be to use # as the namespace separator. I know #
is used for comments, but with /* */ and // that all seems covered.
namespace#function() vs class::static()
Seems like a winner. Just a whole ton of BC though for those using #
for comments.
Regards,
Richard.
--
Richard Quadling
Zend Certified Engineer : http://zend.com/zce.php?c=ZEND002498&r=213474731
"Standing on the shoulders of some very clever giants!"
Seems like a winner. Just a whole ton of BC though for those using #
for comments.
Yep, so forget it. Or were you doing a Jani? ;)
- Steph
I can't see how this can break existing code... '#' is usually used at the
beginning of a line or after ';'
<?php
comment
$foo = "bar"; # comment $_this->will->not->be->evaluated()
?>
Regards,
Seems like a winner. Just a whole ton of BC though for those using #
for comments.
Yep, so forget it. Or were you doing a Jani? ;)
- Steph
--
--
Diego Feitosa
www.dnfeitosa.com
Caelum - Ensino e Soluções em Java
diego.feitosa@caelum.com.br
www.caelum.com.br
Steph Fox schreef:
Seems like a winner. Just a whole ton of BC though for those using #
for comments.Yep, so forget it. Or were you doing a Jani? ;)
It seems to hav escaped everyone that Greg's latest proposal doesn't change
the namespace seperator token, instead it comes with a new concept of namespace
member [token].
ambiguity related to the 'use' statements remains regardless of what the namespace
seperator is ... therefore the proposal for a new operator that allows to explicitly
reference namespace members:
<?php
use my#funky#namespace#strlen; // is this aliasing a class, function or namespace?
strlen()
; // is this interal strlen()
or namespaced function?
?>
and obviously BC dictates that '#' cannot be considered, but that's moot anyhow.
- Steph
Hi Jochem,
It seems to hav escaped everyone that Greg's latest proposal doesn't
change
the namespace seperator token, instead it comes with a new concept of
namespace
member [token].
No, that didn't escape me at all. I was responding to the OP.
To be clear, I have worked with Greg. The experience left me with large
amounts of respect for his creativity and analytical abilities. They exceed
mine by a number of quadzillions.
That doesn't mean Greg's always in the right, but it does mean he's always
worth hearing. I know for sure I'm not the only person on this list who sees
him that way, and most of the others have far more influence than I do.
Next time, perhaps you and I should both let sleeping dogs lie ;)
- Steph
Steph Fox schreef:
Hi Jochem,
It seems to hav escaped everyone that Greg's latest proposal doesn't
change
the namespace seperator token, instead it comes with a new concept of
namespace
member [token].No, that didn't escape me at all.
oh, good!
I was responding to the OP.
To be clear, I have worked with Greg. The experience left me with large
amounts of respect for his creativity and analytical abilities. They
exceed mine by a number of quadzillions.
I've been conversing with him over the last couple of weeks regarding namespaces
off-list and have every reason to second that thought.
That doesn't mean Greg's always in the right, but it does mean he's
always worth hearing. I know for sure I'm not the only person on this
list who sees him that way, and most of the others have far more
influence than I do.
which makes it all the more sad that the only person taking a real interest
in his [latest namespace] proposal is the one person who's completely
adamant that there is nothing in the current namespace implementation that
needs addressing (all issues come down to 'your using it wrong')
Next time, perhaps you and I should both let sleeping dogs lie ;)
I don't get the use of that idiom in this context. I think the 'namespace' dog
has been up and about for a while already, granted some would like to see it
put down permanently :-)
- Steph
On Saturday 20 September 2008 6:43:41 pm Richard Quadling wrote:
- a simply syntax change to namespaces, introducing a new concept:
namespace element.A namespace element is a class, function or constant defined within a
namespace declaration:<?php
namespace foo;
class bar {} // class element bar in namespace foo
function bar(){} // function element bar in namespace foo
const bar=1; // const element bar in namespace foo
?>This is similar to class elements:
<?php
class foo {
function bar(){} // method element bar in class foo
const bar=1; // constant element bar in class foo
public $bar=1; // variable element bar in class foo
}
?>Currently, this code:
<?php
namespace foo::bar;
class buh{}
?>creates a class named "foo::bar::buh", essentially joining the namespace
"foo::bar" and its class element "buh" with the separator "::". This
turns out to be the root of the problem with the conflicts between class
elements and namespace elements. The last patch introduces a new
namespace element operator to delineate the boundary between namespace
name and element name. For the patch, I recycledT_OBJECT_OPERATOR
(->).current way:
<?php
foo::bar->test(); // namespace foo::bar, call to function element test()
foo->bar::test(); // namespace foo, call to static method element test()
in class element bar
foo->myconst; // namespace foo constant myconst
foo::myconst; // class foo constant myconst
?>The patch is at:
http://pear.php.net/~greg/ns.element.patch.txt
This is the most extensive change. The patch preserves :: as global
element accessor (::strlen() calls strlen internal function, for
instance). I'm happy to answer any other questions.So, these are the choices. I suggest we all take a rational look at the
options, and understand the consequences of each, and make the best
choice possible.Thanks,
GregGood work, but I (and I'm probably not alone) can't really keep up
with all those namespace threads and proposals for changes and
resolution fixes and this and that,so :Please use our nice RFC system!
Regards
--
Etienne Kneuss
http://www.colder.chMen never do evil so completely and cheerfully as
when they do it from a religious conviction.
-- Pascal--
How feasible would it be to use # as the namespace separator. I know #
is used for comments, but with /* */ and // that all seems covered.namespace#function() vs class::static()
Seems like a winner. Just a whole ton of BC though for those using #
for comments.
I agree that #5 seems like the best solution. The problem is caused by the
double meaning of ::. All of the other solutions feel like bandaids.
Of course, the problem then is finding a symbol that is not already used. I
don't think reusing -> is any wiser than reusing ::. # would be great if it
wasn't already in use, but that sort of change is really not appropriate for
5.3. What other symbols are available or could be created? (::: has been
suggested and would give the opportunity to introduce more Hebrew into the
language parser...)
--
Larry Garfield
larry@garfieldtech.com
Larry Garfield wrote:
On Saturday 20 September 2008 6:43:41 pm Richard Quadling wrote:
- a simply syntax change to namespaces, introducing a new concept:
namespace element.A namespace element is a class, function or constant defined within a
namespace declaration:<?php
namespace foo;
class bar {} // class element bar in namespace foo
function bar(){} // function element bar in namespace foo
const bar=1; // const element bar in namespace foo
?>This is similar to class elements:
<?php
class foo {
function bar(){} // method element bar in class foo
const bar=1; // constant element bar in class foo
public $bar=1; // variable element bar in class foo
}
?>Currently, this code:
<?php
namespace foo::bar;
class buh{}
?>creates a class named "foo::bar::buh", essentially joining the namespace
"foo::bar" and its class element "buh" with the separator "::". This
turns out to be the root of the problem with the conflicts between class
elements and namespace elements. The last patch introduces a new
namespace element operator to delineate the boundary between namespace
name and element name. For the patch, I recycledT_OBJECT_OPERATOR
(->).current way:
<?php
foo::bar->test(); // namespace foo::bar, call to function element test()
foo->bar::test(); // namespace foo, call to static method element test()
in class element bar
foo->myconst; // namespace foo constant myconst
foo::myconst; // class foo constant myconst
?>The patch is at:
http://pear.php.net/~greg/ns.element.patch.txt
This is the most extensive change. The patch preserves :: as global
element accessor (::strlen() calls strlen internal function, for
instance). I'm happy to answer any other questions.
[snip]
I agree that #5 seems like the best solution. The problem is caused by the
double meaning of ::. All of the other solutions feel like bandaids.Of course, the problem then is finding a symbol that is not already used. I
don't think reusing -> is any wiser than reusing ::. # would be great if it
Let's be clear. Here is a sample of code with the new syntax:
<?php
namespace name::still::has::double::colon;
const oscopy = 1;
class blow{
const byblow = 1;
static function hard(){}
}
namespace another::name;
use name::still::has::double::colon;
// fully qualified name:
// note that -> is only used once
// to specify the boundary between namespace name and namespace member.
$a = new name::still::has::double::colon->blow;
$a = new colon->blow;
// static method call
colon->blow::hard();
// or
name::still::has::double::colon->blow::hard();
// ns constant
echo colon->oscopy;
namespace blow;
function hard(){}
namespace a::third::name;
// demonstrate importing a class name
// which is different from importing a namespace name
use name::still::has::double::colon->blow;
// class static method
blow::hard();
// namespace function
::blow->hard();
// class constant
echo blow::byblow;
?>
Two important things to note:
- ambiguity between namespace name and class name is eliminated
<?php
namespace foo;
class test{
}
namespace foo::test;
class test{}
namespace third;
use foo::test;
$a = new test; // this is namespace foo, class test
$a = new test::test; // this is namespace foo::test, class test
?> - this separator is self-documenting. One does not need to grep source
code to determine whether blah->thing is a namespaced function or a
static method of class blah. The same is true of use statements. It is
crystal clear whether we are importing a namespace or a class name.
This will make debugging someone else's code a lot easier than it
otherwise would be.
Jochem has informed me he is taking care of the wiki RFC for this stuff.
I am allergic to wikis, unfortunately.
Thanks,
Greg
Larry Garfield a écrit :
I agree that #5 seems like the best solution. The problem is caused by the
double meaning of ::. All of the other solutions feel like bandaids.
They are not a double meaning : it is a scope resolver. Like in C++.
So please all stop this war about namespaces, and look where it was
resolved in other languages. It will be wisely :)
--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
Lupus Michaelis a écrit :
look where it was resolved in other languages.
I mean « how » and not « where », of course, sorry :-/
--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
Lupus Michaelis wrote:
Larry Garfield a écrit :
I agree that #5 seems like the best solution. The problem is caused
by the double meaning of ::. All of the other solutions feel like
bandaids.They are not a double meaning : it is a scope resolver. Like in C++.
So please all stop this war about namespaces, and look where it was
resolved in other languages. It will be wisely :)
Hi,
Amazingly enough, this work has already been done. The first thing
noticed is that C++ is a compiling language, and PHP isn't. Therefore
at compile time, it is possible to know every single file that will be
available, every single class, and so on. This enables all kinds of
clever resolution such as importing ns::* and it actually works with
full performance.
PHP, on the other hand, is a dynamic language, and it is impossible to
know in advance which files, which classes, which namespaces will be
defined. Other dynamic languages that have implemented namespaces have
solved the problems mentioned via run-time resolution, which is much slower.
One key difference from C++ is that namespaces do not define scope in
PHP. The only constructs that define scope different from global scope
are functions and now closures (as I understand them from reading the
mailing list).
I suppose I should have mentioned option #6: do all class, function and
constant resolution at run-time, "obsoleting" all opcode caches and make
PHP 5.3 an unusable release for any high traffic websites.
Greg
Hi Greg,
Greg Beaver wrote:
Lupus Michaelis wrote:
Larry Garfield a écrit :
I agree that #5 seems like the best solution. The problem is caused
by the double meaning of ::. All of the other solutions feel like
bandaids.They are not a double meaning : it is a scope resolver. Like in C++.
So please all stop this war about namespaces, and look where it was
resolved in other languages. It will be wisely :)Hi,
Amazingly enough, this work has already been done. The first thing
noticed is that C++ is a compiling language, and PHP isn't. Therefore
at compile time, it is possible to know every single file that will be
available, every single class, and so on. This enables all kinds of
clever resolution such as importing ns::* and it actually works with
full performance.PHP, on the other hand, is a dynamic language, and it is impossible to
know in advance which files, which classes, which namespaces will be
defined. Other dynamic languages that have implemented namespaces have
solved the problems mentioned via run-time resolution, which is much slower.One key difference from C++ is that namespaces do not define scope in
PHP. The only constructs that define scope different from global scope
are functions and now closures (as I understand them from reading the
mailing list).I suppose I should have mentioned option #6: do all class, function and
constant resolution at run-time, "obsoleting" all opcode caches and make
PHP 5.3 an unusable release for any high traffic websites.
Please check your suggestions before publishing them.
<?php
class Foo {
function bar() {
}
}
function simplecall() {
for ($i = 0; $i < 1000000; $i++) {
Foo::bar();
Foo::bar();
Foo::bar();
Foo::bar();
Foo::bar();
Foo::bar();
Foo::bar();
Foo::bar();
Foo::bar();
Foo::bar();
}
}
simplecall();
?>
$ time php5.2/CGI-RELEASE/sapi/cli/php -n bench.php
real 0m7.458s
user 0m7.416s
sys 0m0.007s
$ time php5.3/CGI-RELEASE/sapi/cli/php -n bench.php
real 0m7.337s
user 0m7.252s
sys 0m0.002s
As you can see 5.3 is faster.
Of course it could be faster, but it's a winer anyway :)
I really don't see a reason to change namespace syntax into a less
intuitive way. Your speed degradation argument isn't truth. The
ambiguity problem exists, but it is just an ability to use php in a
wrong way. Just don't create conflicting names.
I would recommend option #1 (stay it as is + document)
Thanks. Dmitry.
Dmitry Stogov schreef:
Hi Greg,
Greg Beaver wrote:
...
I really don't see a reason to change namespace syntax into a less
intuitive way.
I don't think the current implementation is intuitive, the ambiguity issues,
(and possibly the name resolution order, although I can't grok what the current
state of that is) are rather large WTFs.
Your speed degradation argument isn't truth. The
ambiguity problem exists, but it is just an ability to use php in a
wrong way. Just don't create conflicting names.
which begs the question, what was namespaces created for?
(that's a serious question because your statement has me truly confused)
we can "Just not create conflicting names" without namespaces and
Stas has mentioned numerous times that namespace were not designed
just to avoid having to repeatedly type long symbol names.
another thing, the ability to use php the wrong way is an argument
that has been used lately both to:
-
advocate leaving functionality as it is and putting the
burden of responsibility on the developer to do the right thing. -
advocate changing functionality (or making the functionality illegal)
in order to protect the user from doing something stupid.
.. not exactly consistent.
BTW, not creating conflicting names doesn't make the problem
completely dissappear, code is still vulnerable breakage due to
addition of new functions or classes in future version of the
engine.
I would recommend option #1 (stay it as is + document)
It would seem that it's yours' and Stas' responsibility to
properly document how namespaces should be used because everyone
else either doesn't care much about it or has, according to you,
completely the wrong end of the stick with regard to the how/why/what
of namespaces.
Can we at least count on you [both] to provide that documentation?
Hi Jochem,
Jochem Maas wrote:
Dmitry Stogov schreef:
Hi Greg,
Greg Beaver wrote:
...
I really don't see a reason to change namespace syntax into a less
intuitive way.I don't think the current implementation is intuitive, the ambiguity
issues,
(and possibly the name resolution order, although I can't grok what the
current
state of that is) are rather large WTFs.Your speed degradation argument isn't truth. The
ambiguity problem exists, but it is just an ability to use php in a
wrong way. Just don't create conflicting names.which begs the question, what was namespaces created for?
(that's a serious question because your statement has me truly confused)we can "Just not create conflicting names" without namespaces and
Stas has mentioned numerous times that namespace were not designed
just to avoid having to repeatedly type long symbol names.another thing, the ability to use php the wrong way is an argument
that has been used lately both to:
advocate leaving functionality as it is and putting the
burden of responsibility on the developer to do the right thing.advocate changing functionality (or making the functionality illegal)
in order to protect the user from doing something stupid... not exactly consistent.
BTW, not creating conflicting names doesn't make the problem
completely dissappear, code is still vulnerable breakage due to
addition of new functions or classes in future version of the
engine.
Right. Any touch of code can break something :)
Personally, I don't like inconsistencies and I would remove them if
possible. It wouldn't be a problem if PHP language was designed to
support namespaces, but it wasn't. Now we have to support backward
compatibility and provide new features without speed degradation and to
do it sometimes we have to make compromises because absolutely
consistent decisions are not possible in real life.
I would recommend option #1 (stay it as is + document)
It would seem that it's yours' and Stas' responsibility to
properly document how namespaces should be used because everyone
else either doesn't care much about it or has, according to you,
completely the wrong end of the stick with regard to the how/why/what
of namespaces.Can we at least count on you [both] to provide that documentation?
README.namespaces was committed into PHP_5_3 about year ago.
Thanks. Dmitry.
hi Dmirty,
I really don't see a reason to change namespace syntax into a less
intuitive way.
I don't think the current implementation is intuitive, the ambiguity
issues,
(and possibly the name resolution order, although I can't grok what the
current
state of that is) are rather large WTFs.Your speed degradation argument isn't truth. The
ambiguity problem exists, but it is just an ability to use php in a
wrong way. Just don't create conflicting names.
which begs the question, what was namespaces created for?
(that's a serious question because your statement has me truly confused)
you didn't answer the question (and AFAIC the readme doesn't either).
README.namespaces was committed into PHP_5_3 about year ago.
a 14 month old document which doesn't cover the status quo,
and begins with a disingenuous statement about the problem namespaces try to
solve (is that really all there is to namespaces? to avoid typing long class names?
most people have auto-complete features in their editor to take care of that 'problem'
and it really doesn't explain why constants or functions exist in namespaces at all.)
Jochem Maas wrote:
hi Dmirty,
I really don't see a reason to change namespace syntax into a less
intuitive way.
I don't think the current implementation is intuitive, the ambiguity
issues,
(and possibly the name resolution order, although I can't grok what the
current
state of that is) are rather large WTFs.Your speed degradation argument isn't truth. The
ambiguity problem exists, but it is just an ability to use php in a
wrong way. Just don't create conflicting names.
which begs the question, what was namespaces created for?
(that's a serious question because your statement has me truly confused)you didn't answer the question (and AFAIC the readme doesn't either).
The main reason of namespaces is resolution of name conflicts and
ability to use the same names in different scopes.
README.namespaces was committed into PHP_5_3 about year ago.
a 14 month old document which doesn't cover the status quo,
and begins with a disingenuous statement about the problem namespaces
try to
solve (is that really all there is to namespaces? to avoid typing long
class names?
Yes, you are right. It's need to be adopted to current situation which
might be changed once again...
most people have auto-complete features in their editor to take care of
that 'problem'
and it really doesn't explain why constants or functions exist in
namespaces at all.)
I see you point, and you might be satisfied with decision which is going
to be final, however from my point of view function and constants must
be allowed in namesapaces just because they are parts of the language.
Thanks. Dmitry.
hi Dmirty,
I really don't see a reason to change namespace syntax into a less
intuitive way.
I don't think the current implementation is intuitive, the ambiguity
issues,
(and possibly the name resolution order, although I can't grok what the
current
state of that is) are rather large WTFs.Your speed degradation argument isn't truth. The
ambiguity problem exists, but it is just an ability to use php in a
wrong way. Just don't create conflicting names.
which begs the question, what was namespaces created for?
(that's a serious question because your statement has me truly confused)you didn't answer the question (and AFAIC the readme doesn't either).
The main reason of namespaces is resolution of name conflicts and
ability to use the same names in different scopes.
thank you for confirming this explicitly.
README.namespaces was committed into PHP_5_3 about year ago.
a 14 month old document which doesn't cover the status quo,
and begins with a disingenuous statement about the problem namespaces
try to
solve (is that really all there is to namespaces? to avoid typing long
class names?Yes, you are right. It's need to be adopted to current situation which
might be changed once again...
okay :-) ... I did actually promise Lukas that I'd write a guideline/best-practices
doc regarding namespaces ... I still intend to give that a shot, It will require
that people like you and Stas (amongst others) give a little time to vet the
doc for accuracy, do you see this as a problem?
most people have auto-complete features in their editor to take care of
that 'problem'
and it really doesn't explain why constants or functions exist in
namespaces at all.)I see you point, and you might be satisfied with decision which is going
to be final, however from my point of view function and constants must
be allowed in namesapaces just because they are parts of the language.
I would prefer to have functions and constants in namespaces, but I think the
current implementation requires greg's patch in order to make it work.
additionally I think autoloading for functions (and actually anything namespace
related) should be seriously considered. the fact that it's only classes that can
be autoloaded and namespaced is of itself consistent. there is something to be said
for this kind of clearly defined 'limitation' - you know where you are!
that said I think dropping functions (and constants) is the only real alternative
to allowing greg's patch. dropping them may mean an incomplete namespace implementation,
but in this case it's a good thing ... it allows people to start using namespaces
and allows you (php devs) to work out a means to solve the ambiguity issues
surrounding NS funcs/constants without worrying (as much?) about BC issues and
without a barrage of 'wtf' type bug reports and questions (users will
push namespaces to the edge and beyond if you give them the chance, not
introducing funcs/constants means they can't simply can't do certain things for now)
in the long run functions and constants will be added to namespaces ... and then
the ambiguity issues will have to be dealt with. I believe Greg's namespace member
concept will be required even if the syntax is/must/should/will changed to
something everyone finds acceptable.
rgds,
Jochem
Jochem Maas wrote:
in the long run functions and constants will be added to namespaces ...
and then
the ambiguity issues will have to be dealt with. I believe Greg's
namespace member
concept will be required even if the syntax is/must/should/will changed to
something everyone finds acceptable.
Did you really mean to say that.
Push namespaces out now - incomplete - and then change them again later?
Why should we even bother using them if they don't do the whole job and are
going to change again. Things like PHPEclipse and phpdocumentor need some
major work to support this extra level, and that can't start until the format
has been fixed - and now even that is not certain ?
--
Lester Caine - G8HFL
Contact - http://lsces.co.uk/lsces/wiki/?page=contact
L.S.Caine Electronic Services - http://lsces.co.uk
EnquirySolve - http://enquirysolve.com/
Model Engineers Digital Workshop - http://medw.co.uk//
Firebird - http://www.firebirdsql.org/index.php
Lester Caine schreef:
Jochem Maas wrote:
in the long run functions and constants will be added to namespaces
... and then
the ambiguity issues will have to be dealt with. I believe Greg's
namespace member
concept will be required even if the syntax is/must/should/will
changed to
something everyone finds acceptable.Did you really mean to say that.
funnily enough yes.
Push namespaces out now - incomplete - and then change them again later?
it's not imcomplete anymore than autoload() is incomplete (autoload() also
doesn't cater for functions). and it's not change later but extend later
whereas if one would roll out the currently implementation with functions/constants
you would have to change it later to fix the ambiguity issues (which is hard to
do in a way that satisfies anyone, see reactions to Greg's namespace member
proposal as a perfect example of the ammount of friction that one needs to
overcome). changing it later implies that people will have to fix their code
upon a new release of php at some point because they have been using
namespaced functions/constants.
if they can't use something then they don't have to change the code that
doesn't use it either.
Why should we even bother using them if they don't do the whole job and
are going to change again.
not changed but extended. it seems obvious that BC dictates that stuff put
out the door shouldn't be broken willy nilly. granted this will probably make
it more difficult to come up with an alternative to Greg's proposal that also
satisfies the ambiguities issues yet does not force syntax changes on developers
using namespaces with released versions of php ... but that's not your f***ing problem
is it? that'll be up to people like Stas, Greg, Dmitry et al to actually hammer
out a solution.
Things like PHPEclipse and phpdocumentor need
some major work to support this extra level, and that can't start until
the format has been fixed - and now even that is not certain ?
... same argument as above.
I'll grant that my argument/opinion may be incorrect but I'll leave it up to
the guys who build php to call me out on that.
Dmitry Stogov wrote:
<snip>Hi Greg,
Greg Beaver wrote:
Lupus Michaelis wrote:
Larry Garfield a écrit :
I agree that #5 seems like the best solution. The problem is caused
by the double meaning of ::. All of the other solutions feel like
bandaids.They are not a double meaning : it is a scope resolver. Like in C++.
So please all stop this war about namespaces, and look where it was
resolved in other languages. It will be wisely :)Hi,
Amazingly enough, this work has already been done. The first thing
noticed is that C++ is a compiling language, and PHP isn't. Therefore
at compile time, it is possible to know every single file that will be
available, every single class, and so on. This enables all kinds of
clever resolution such as importing ns::* and it actually works with
full performance.PHP, on the other hand, is a dynamic language, and it is impossible to
know in advance which files, which classes, which namespaces will be
defined. Other dynamic languages that have implemented namespaces have
solved the problems mentioned via run-time resolution, which is much slower.One key difference from C++ is that namespaces do not define scope in
PHP. The only constructs that define scope different from global scope
are functions and now closures (as I understand them from reading the
mailing list).I suppose I should have mentioned option #6: do all class, function and
constant resolution at run-time, "obsoleting" all opcode caches and make
PHP 5.3 an unusable release for any high traffic websites.Please check your suggestions before publishing them.
<?php
class Foo {
function bar() {
}
}function simplecall() {
for ($i = 0; $i < 1000000; $i++) {
Foo::bar();
Foo::bar();
Foo::bar();
Foo::bar();
Foo::bar();
Foo::bar();
Foo::bar();
Foo::bar();
Foo::bar();
Foo::bar();
}
}simplecall();
?>
hi Dmitry,
Let me quote myself from right above your reply:
"option #6: do all class, function and constant resolution at run-time"
This would be slow and eliminate most of the benefit of opcode caches.
The script you posted does not demonstrate option #6 because that's not
how PHP works or has ever worked. Which suggestion are you trying to
debunk?
I was never saying the current implementation is slow, only that it is
broken. Without changes, it is dangerous in PHP's namespace
implementation to
- ever use short names inside a namespace declaration for any class in
the same namespace not defined in the same file - mix functions and classes in the same project with hierarchical
namespace declarations, or mix namespace constants with class constants
#1 makes namespaces essentially more verbose than the existing situation
(:: is longer than _), and #2 requires users to perform more diligence
than they would have to before namespaces. In both cases, this either
introduces more chance for subtle logic failure compared to PHP prior to
namespaces, or requires longer class names. I highly doubt that is the
intention.
Returning to the original debate, if you really believe this conflict is
not an issue, then why was the first user note published last December a
note about this conflict?
http://us3.php.net/manual/en/language.namespaces.php#80035
Greg
Gregory Beaver wrote:
Dmitry Stogov wrote:
<snip>Hi Greg,
Greg Beaver wrote:
Lupus Michaelis wrote:
Larry Garfield a écrit :
I agree that #5 seems like the best solution. The problem is caused
by the double meaning of ::. All of the other solutions feel like
bandaids.They are not a double meaning : it is a scope resolver. Like in C++.
So please all stop this war about namespaces, and look where it was
resolved in other languages. It will be wisely :)Hi,
Amazingly enough, this work has already been done. The first thing
noticed is that C++ is a compiling language, and PHP isn't. Therefore
at compile time, it is possible to know every single file that will be
available, every single class, and so on. This enables all kinds of
clever resolution such as importing ns::* and it actually works with
full performance.PHP, on the other hand, is a dynamic language, and it is impossible to
know in advance which files, which classes, which namespaces will be
defined. Other dynamic languages that have implemented namespaces have
solved the problems mentioned via run-time resolution, which is much slower.One key difference from C++ is that namespaces do not define scope in
PHP. The only constructs that define scope different from global scope
are functions and now closures (as I understand them from reading the
mailing list).I suppose I should have mentioned option #6: do all class, function and
constant resolution at run-time, "obsoleting" all opcode caches and make
PHP 5.3 an unusable release for any high traffic websites.Please check your suggestions before publishing them.
<?php
class Foo {
function bar() {
}
}function simplecall() {
for ($i = 0; $i < 1000000; $i++) {
Foo::bar();
Foo::bar();
Foo::bar();
Foo::bar();
Foo::bar();
Foo::bar();
Foo::bar();
Foo::bar();
Foo::bar();
Foo::bar();
}
}simplecall();
?>hi Dmitry,
Let me quote myself from right above your reply:
"option #6: do all class, function and constant resolution at run-time"
This would be slow and eliminate most of the benefit of opcode caches.
The script you posted does not demonstrate option #6 because that's not
how PHP works or has ever worked.
The script I posted calls static methods and does two cache lookups in
5.3 because of runtime resolution. However it does quick cache lookups
without cache-value calculating. As you can see they work faster then
single hash lookup in 5.2.
Which suggestion are you trying to debunk?
Sorry, I probably misunderstood you, I thought you had talked about
speed of current implementation. Anyway, php resolves names at run-time now.
I was never saying the current implementation is slow, only that it is
broken. Without changes, it is dangerous in PHP's namespace
implementation to
I wouldn't say it broken, I would say it has some ambiguity problems.
- ever use short names inside a namespace declaration for any class in
the same namespace not defined in the same file
why is it dangerous?
- mix functions and classes in the same project with hierarchical
namespace declarations, or mix namespace constants with class constants#1 makes namespaces essentially more verbose than the existing situation
(:: is longer than _), and #2 requires users to perform more diligence
than they would have to before namespaces. In both cases, this either
introduces more chance for subtle logic failure compared to PHP prior to
namespaces, or requires longer class names. I highly doubt that is the
intention.Returning to the original debate, if you really believe this conflict is
not an issue, then why was the first user note published last December a
note about this conflict?
I could add nothing. The problem exists, but proposed solution make
language even worse. Having A::B->foo() and ->foo() or ::foo() and
A::B->C::foo() is much more inconsistent from my point of view.
It would be better to change static class separator from :: to ->, but
it's a BC break
Thanks. Dmitry.
Returning to the original debate, if you really believe this
conflict is
not an issue, then why was the first user note published last
December a
note about this conflict?I could add nothing. The problem exists, but proposed solution make
language even worse. Having A::B->foo() and ->foo() or ::foo() and
A::B->C::foo() is much more inconsistent from my point of view.
It would be better to change static class separator from :: to ->, but
it's a BC break
Again, not speaking as an RM, I personally feel we really do have to
solve this ambiguity problem. I do not agree that this only affects
"namespace abusers".
That being said we have to stay realistic. What Greg proposes is
realistic imho. Its essentially reusing an existing OO syntax. The
same is what we have today with the double colon. While I agree that
it would not be my natural choice, it seems it solves our real problem
of the frequently mentioned ambiguity problem. So from that perspetive
its a step forward from the current syntax.
I know we are getting dangerously close (or are we already back in
it?) to the namespace separator discussion. I remember back then a lot
of people were saying lets get the implementation done first and then
worry about the syntax. I guess we are more or less at this point now.
regards,
Lukas Kahwe Smith
mls@pooteeweet.org
Lukas Kahwe Smith wrote:
Returning to the original debate, if you really believe this conflict is
not an issue, then why was the first user note published last December a
note about this conflict?I could add nothing. The problem exists, but proposed solution make
language even worse. Having A::B->foo() and ->foo() or ::foo() and
A::B->C::foo() is much more inconsistent from my point of view.
It would be better to change static class separator from :: to ->, but
it's a BC breakAgain, not speaking as an RM, I personally feel we really do have to
solve this ambiguity problem. I do not agree that this only affects
"namespace abusers".That being said we have to stay realistic. What Greg proposes is
realistic imho. Its essentially reusing an existing OO syntax. The same
is what we have today with the double colon. While I agree that it would
not be my natural choice, it seems it solves our real problem of the
frequently mentioned ambiguity problem. So from that perspetive its a
step forward from the current syntax.
Yes. Changing :: into any other separator solves the functions/static
methods and constants ambiguity, but it also breaks intuitive syntax.
Thanks. Dmitry.
I know we are getting dangerously close (or are we already back in it?)
to the namespace separator discussion. I remember back then a lot of
people were saying lets get the implementation done first and then worry
about the syntax. I guess we are more or less at this point now.regards,
Lukas Kahwe Smith
mls@pooteeweet.org
Dmitry Stogov schreef:
Lukas Kahwe Smith wrote:
Returning to the original debate, if you really believe this conflict is
not an issue, then why was the first user note published last December a
note about this conflict?http://us3.php.net/manual/en/language.namespaces.php#80035
I could add nothing. The problem exists, but proposed solution make
language even worse. Having A::B->foo() and ->foo() or ::foo() and
A::B->C::foo() is much more inconsistent from my point of view.
it's unfair to call it inconsistent, the syntax is consistent in it's own
right and uses an operator which is known to mean 'member' in a pre-existing
context.
if it truly can be considered inconsistent then that is only because Greg
proposal avoids BC breakage, inconsistency was inherent because two different
operators were chosen for class scope operator ('->' and '::') which your following
comment demonstrates is technically unnecessary.
It would be better to change static class separator from :: to ->, but
it's a BC breakAgain, not speaking as an RM, I personally feel we really do have to
solve this ambiguity problem. I do not agree that this only affects
"namespace abusers".That being said we have to stay realistic. What Greg proposes is
realistic imho. Its essentially reusing an existing OO syntax. The same
is what we have today with the double colon. While I agree that it would
not be my natural choice, it seems it solves our real problem of the
frequently mentioned ambiguity problem. So from that perspetive its a
step forward from the current syntax.Yes. Changing :: into any other separator solves the functions/static
methods and constants ambiguity, but it also breaks intuitive syntax.
a, it doesn't actually solve all the ambiguity issues, Greg has tried to
point this out. I actually hammered Greg a number of times about the
:: seperator and the fact that changing it fixes the ambiguities ... after
careful consideration he came back to me and pointed out that most of
the ambiguities are resolved but not all, simply because (for one) it's still not
possible to distinguish between an aliased namespace and an aliases namespace
name.
b, the presumption that the current syntax is intuitive is completely
subjective. imho it's not intuitive specifically because it's
open to intepretation as to what code refers to (aka ambiguous).
Thanks. Dmitry.
I know we are getting dangerously close (or are we already back in it?)
to the namespace separator discussion. I remember back then a lot of
people were saying lets get the implementation done first and then worry
about the syntax. I guess we are more or less at this point now.regards,
Lukas Kahwe Smith
mls@pooteeweet.org
Hi.
Dmitry Stogov wrote:
Yes. Changing :: into any other separator solves the functions/static
methods and constants ambiguity, but it also breaks intuitive syntax.
Well, I'd say those having problems to grok the syntax will have
problems getting the whole concept of namespaces. :)
That being said: rather learn some syntax than constantly wonder about
name resolution and ambiguity.
Regards,
Karsten
Returning to the original debate, if you really believe this conflict is
not an issue, then why was the first user note published last December a
note about this conflict?I could add nothing. The problem exists, but proposed solution make
language even worse. Having A::B->foo() and ->foo() or ::foo() and
A::B->C::foo() is much more inconsistent from my point of view.
It would be better to change static class separator from :: to ->, but
it's a BC breakAgain, not speaking as an RM, I personally feel we really do have to solve
this ambiguity problem. I do not agree that this only affects "namespace
abusers".That being said we have to stay realistic. What Greg proposes is realistic
imho. Its essentially reusing an existing OO syntax. The same is what we
have today with the double colon. While I agree that it would not be my
natural choice, it seems it solves our real problem of the frequently
mentioned ambiguity problem. So from that perspetive its a step forward from
the current syntax.
The syntax proposed by Greg seems ok to me. While it is a bit
"unintuitive" at first, it is easily learnable and does it's work
I know we are getting dangerously close (or are we already back in it?) to
the namespace separator discussion. I remember back then a lot of people
were saying lets get the implementation done first and then worry about the
syntax. I guess we are more or less at this point now.
--
Alexey Zakhlestin
http://blog.milkfarmsoft.com/
On Monday 22 September 2008 10:45:33 am Lukas Kahwe Smith wrote:
Returning to the original debate, if you really believe this
conflict is
not an issue, then why was the first user note published last
December a
note about this conflict?I could add nothing. The problem exists, but proposed solution make
language even worse. Having A::B->foo() and ->foo() or ::foo() and
A::B->C::foo() is much more inconsistent from my point of view.
It would be better to change static class separator from :: to ->, but
it's a BC breakAgain, not speaking as an RM, I personally feel we really do have to
solve this ambiguity problem. I do not agree that this only affects
"namespace abusers".That being said we have to stay realistic. What Greg proposes is
realistic imho. Its essentially reusing an existing OO syntax. The
same is what we have today with the double colon. While I agree that
it would not be my natural choice, it seems it solves our real problem
of the frequently mentioned ambiguity problem. So from that perspetive
its a step forward from the current syntax.I know we are getting dangerously close (or are we already back in
it?) to the namespace separator discussion. I remember back then a lot
of people were saying lets get the implementation done first and then
worry about the syntax. I guess we are more or less at this point now.
I think we are already back in it, especially if we're talking about dropping
functions from namespaces in order to preserve the operator. I don't find
reusing a second symbol to be a step up, though. I can see it making it
harder to read, not easier, to reuse both characters from object resolution
in a different context. That just makes my brain hurt even more than
reusing :: does.
I'd argue there's nothing uniquely intuitive about :: as a namespace operator
other than the current 5.3 alpha uses it.
--
Larry Garfield
larry@garfieldtech.com
Having conflicting names of namespaces and classes is a idea bad from
the ground, and it should not be allowed. PHP should trigger a fatal
error when it sees it. Having two things with the same name is
unnatural and unneeded.
Syntax with -> is unnatural and unreadable. -> is for working with
objects, not for doing such odd things with namespaces. If you will do
this change in PHP, I will never use namespaces in PHP, and I will
start to look for a new language. Probably not only me.
Janusz Lewandowski
Hi all,
There is a problem in the namespace implementation. This code demonstrates
the issue:code.inc:
<?php
namespace foo;
class test {
const my = 1;
static function bar(){}
}namespace foo::test;
const my = 2;
function bar(){}
?>main.php:
<?php
include 'code.inc';
foo::test::bar(); // always calls namespace function
call_user_func(array('foo::test', 'bar')); // the only way to call static
method
echo foo::test::my; // always 2
$a = new foo::test;
echo $a::my; // the only way to access foo::test::my
?>There are 5 ways to solve this:
- document it and hope no one uses it [this is the current strategy, minus
the documentation part]- add a fatal error on conflicting names.
Uh, if we don't have functions in namespaces, then the second "function
bar(){}" would define the bar function in the global scope only and not
as part of the foo::test namespace... so one more reason to remove
functions (and constants) from namespaces?
regards,
Derick
HEAD before 5_3!: http://tinyurl.com/6d2esb
http://derickrethans.nl | http://ezcomponents.org | http://xdebug.org
Derick Rethans schreef:
Hi all,
There is a problem in the namespace implementation. This code demonstrates
the issue:code.inc:
<?php
namespace foo;
class test {
const my = 1;
static function bar(){}
}namespace foo::test;
const my = 2;
function bar(){}
?>main.php:
<?php
include 'code.inc';
foo::test::bar(); // always calls namespace function
call_user_func(array('foo::test', 'bar')); // the only way to call static
method
echo foo::test::my; // always 2
$a = new foo::test;
echo $a::my; // the only way to access foo::test::my
?>There are 5 ways to solve this:
- document it and hope no one uses it [this is the current strategy, minus
the documentation part]- add a fatal error on conflicting names.
Uh, if we don't have functions in namespaces, then the second "function
bar(){}" would define the bar function in the global scope only and not
as part of the foo::test namespace... so one more reason to remove
functions (and constants) from namespaces?
I don't follow the logic. if we don't have functions in namespaces the second
"function bar(){}" would be a parse error, no?
regards,
Derick