Re: AW: [PHP-DEV] A rebuttal to Re: RFC: Dropping Namespace

2007-12-09 Thread Jessie Hernandez
I thought global names were considered in the patch, but now that I 
re-read Dmitry's post, only symbols in the namespace and internal 
symbols are considered.


I read through most of the posts regarding namespaces, but could not 
find a reason why global names are not looked up. Classes/functions 
should first be looked up in the current namespace, if not found, then 
they should be looked up in the global namespace, and if it is not found 
there either, then there should be a check to see if there is an 
internal class/function with the same name.


Dmitry, what's the reason this lookup logic wasn't used in your patch?


Regards,

Jessie

Gregory Beaver wrote:

Jessie Hernandez wrote:

Hi Greg,

How about this: any non-namespaced file that uses use statements is
implicitly put into the __php__ namespace (or whatever other name is
chosen, or having the namespace name be the path of the file)? With
this, use will never import any symbols into the global namespace. 

Hi Jessie,

Imagine how that would affect this code:

file1.php:
?php
function doSomething() {}
?

PEAR2/DB.php: hypothetical
?php
namespace PEAR2;
class DB {}
?

file2.php:
?php
include 'file1.php';
include 'PEAR2/DB.php';
use PEAR2::DB;
$a = new DB;
$b = doSomething();
?

In file2.php, because there is a use statement, the rest of the file
is assumed to be in the __php__ namespace.  As such, the file can be
expanded into this code:

new_file2.php:
?php
namespace __php__;
include 'file1.php';
include 'file2.php';
$a = new PEAR2::DB;
$b = doSomething();
?

On the last line, when PHP calls doSomething(), it first checks to see
if the function doSomething is available as an internal function. 
Then, it tries __php__::doSomething() and fails on a fatal error because

the function does not exist.  The only way that your idea would work is
if the check for doSomething consisted of checking for any
non-namespaced function (not just internal functions), but the sole
purpose of the fall-through is to allow users to call internal
functions/classes without explicitly specifying ::strlen or ::count and
so on.  Allowing fall-through to any global class/function would serve
to dilute the namespacing effect, but perhaps this is a good thing?  I
have not thought about this long enough to have a definitive opinion yet.

I think one safe way to handle this might be to have an E_STRICT if
class/function/const is declared in the __php__ namespace, so that PHP
provides a clear mechanism for enforcing the convention.  Users wishing
to avoid this E_STRICT need only use another namespace name or adhere to
the coding convention of only putting stuff that uses code into the
__php__ namespace.

Greg


--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: AW: [PHP-DEV] A rebuttal to Re: RFC: Dropping Namespace

2007-12-09 Thread Sam Barrow
I agree with this 100%, is this something that could be changed? I don't
see a reason behind it.

On Sun, 2007-12-09 at 16:24 -0500, Jessie Hernandez wrote:
 
 internal class/function with the same name.
 
 Dmitry, what's the reason this lookup logic wasn't used in your patch?
 

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: AW: [PHP-DEV] A rebuttal to Re: RFC: Dropping Namespace

2007-12-09 Thread Dmitry Stogov



Jessie Hernandez wrote:
I thought global names were considered in the patch, but now that I 
re-read Dmitry's post, only symbols in the namespace and internal 
symbols are considered.


I read through most of the posts regarding namespaces, but could not 
find a reason why global names are not looked up. 

 Classes/functions  should first be looked up in the current namespace,

right.


if not found, then they should be looked up in the global namespace,


never. I have no idea why do you think they should look there...

and if it is not found 
there either, then there should be a check to see if there is an 
internal class/function with the same name.


Today all internal classes/functions are in the global namespace.
We allowed usage of internal names in namespaces, because it would be 
terrible to prefix each usage of internal function like strlen(), write().


Dmitry.


Dmitry, what's the reason this lookup logic wasn't used in your patch?


Regards,

Jessie

Gregory Beaver wrote:

Jessie Hernandez wrote:

Hi Greg,

How about this: any non-namespaced file that uses use statements is
implicitly put into the __php__ namespace (or whatever other name is
chosen, or having the namespace name be the path of the file)? With
this, use will never import any symbols into the global namespace. 

Hi Jessie,

Imagine how that would affect this code:

file1.php:
?php
function doSomething() {}
?

PEAR2/DB.php: hypothetical
?php
namespace PEAR2;
class DB {}
?

file2.php:
?php
include 'file1.php';
include 'PEAR2/DB.php';
use PEAR2::DB;
$a = new DB;
$b = doSomething();
?

In file2.php, because there is a use statement, the rest of the file
is assumed to be in the __php__ namespace.  As such, the file can be
expanded into this code:

new_file2.php:
?php
namespace __php__;
include 'file1.php';
include 'file2.php';
$a = new PEAR2::DB;
$b = doSomething();
?

On the last line, when PHP calls doSomething(), it first checks to see
if the function doSomething is available as an internal function. 
Then, it tries __php__::doSomething() and fails on a fatal error because

the function does not exist.  The only way that your idea would work is
if the check for doSomething consisted of checking for any
non-namespaced function (not just internal functions), but the sole
purpose of the fall-through is to allow users to call internal
functions/classes without explicitly specifying ::strlen or ::count and
so on.  Allowing fall-through to any global class/function would serve
to dilute the namespacing effect, but perhaps this is a good thing?  I
have not thought about this long enough to have a definitive opinion yet.

I think one safe way to handle this might be to have an E_STRICT if
class/function/const is declared in the __php__ namespace, so that PHP
provides a clear mechanism for enforcing the convention.  Users wishing
to avoid this E_STRICT need only use another namespace name or adhere to
the coding convention of only putting stuff that uses code into the
__php__ namespace.

Greg




--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] A rebuttal to Re: RFC: Dropping Namespace

2007-12-08 Thread Steph Fox

Hi Matthias,


Let alone __php__. If you just put all of your code into namespace Mylib,
you're not safe because according to the name resolution rules, internal
classes come after imported ones but before trying to find classes in the
current namespace.


I'd missed that :-( and from what I gather, there's no way to safely change
it either.

OK, apologies for the noise.

- Steph

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: AW: [PHP-DEV] A rebuttal to Re: RFC: Dropping Namespace

2007-12-08 Thread Gregory Beaver
Matthias Pigulla wrote:
 Von: Gregory Beaver [mailto:[EMAIL PROTECTED]
 
 Exactly - which is why you should never put classes, functions or 
 constants in the __php__ namespace.  The convention I am proposing
 is to only use __php__ for code that *uses* re-usable components,
 not *declares* them.
 
 Let alone __php__. If you just put all of your code into namespace
 Mylib, you're not safe because according to the name resolution
 rules, internal classes come after imported ones but before trying to
 find classes in the current namespace.

Right, but as long as you know this, it is not so bad for two reasons,
see below.  Even if you *don't* know this, the chance of a name
collision is extremely unlikely - the most common collision will be
Exception.

 1) library code is always explicitly used 2) name conflicts are
 impossible
 
 1) is the crucial one because that puts your classes ahead of the
 internal ones in the resolution list. That is not only library code
 you explicitly use, but also all code from your own namespace.
 Having to explicitly enumerate all classes you use in your own
 namespace in every file may be tedious.
 
 So just to get that straight: Having a namespace statement and no
 use (because all you use is from your library) is a discouraged
 practise?

To be clear - this *only* affects users who are relying on autoload.  In
other words, this code works the same way 100% of the time regardless of
load order:

file1.php:
?php
namespace foo;
class Exception {}
?

file2.php:
?php
namespace foo;
include 'file1.php';
$a = new Exception('hi');
echo get_class($a); // foo::Exception
?

So, if your code explicitly loads external files using include/require,
you need not worry about this issue.

Library authors who are in fact relying upon autoload do need to
explicitly use the classes they import as unqualified names, but this is
far less onerous than it seems on initial thought.

Let's say you're using 10 classes from your own project.  The first
instinct is that you then have to have 10 use lines - what a pain!
However, this is not necessary.  Here's a realistic sample from
PEAR2_Pyrus's package.xml validator class,
PEAR2::Pyrus::PackageFile::v2::Validator.

?php
namespace PEAR2::Pyrus::PackageFile::v2;
use PEAR2::Pyrus::PackageFile as pf;
use PEAR2::Pyrus::PackageFile::Exception as _ex
use PEAR2::Pyrus as me;
class Validator {...} // details removed for brevity :)
?

With the above use statements, I can access these classes:

PEAR2::Pyrus::PackageFile::v2
PEAR2::Pyrus::Validate
PEAR2::Pyrus::PackageFile::Exception
PEAR2::Pyrus::ChannelRegistry
PEAR2::Pyrus::Installer::Role
PEAR2::Pyrus::Config
PEAR2::Pyrus::Config::Exception
PEAR2::Pyrus::Task
PEAR2::Pyrus::Log
PEAR2::Pyrus::Package::Tar

with these shortcuts:

pf::v2
me::Validate
_ex
me::ChannelRegistry
me::Installer::Role
me::Config
me::Config::Exception
me::Task
me::Log
me::Package::Tar

Note that it would be possible to shorten the longer names like
me::Config::Exception, but these classnames are only used once in the
file.  The most commonly used classname is
PEAR2::Pyrus::PackageFile::Exception, and so I would choose that as the
shortest name.  When one examines these things from a practical
standpoint, having the 4 extra characters me:: definitely increases
maintainability, as it makes it obvious that this class is from our
library, and not an internal class.

I do think it would be worth putting future internal classes into the
PHP namespace, and it would be a good idea to reserve that namespace
now.  The reservation can always be dropped later if necessary.

Greg

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: AW: [PHP-DEV] A rebuttal to Re: RFC: Dropping Namespace

2007-12-08 Thread Jessie Hernandez

Hi Greg,

How about this: any non-namespaced file that uses use statements is 
implicitly put into the __php__ namespace (or whatever other name is 
chosen, or having the namespace name be the path of the file)? With 
this, use will never import any symbols into the global namespace.



Regards,

Jessie


Ford, Mike wrote:

On 07 December 2007 17:36, Gregory Beaver wrote:


The suggestion to make namespace __php__; implicit is very
interesting, but would defeat its purpose, which is to separate
declarations from use. 


Oh, I missed that little wrinkle -- I did say I was only skimming! I guess it 
could still be done, but at somewhat greater cost in the engine than I was 
imagining, which probably isn't worthwhile.


Cheers!

Mike

-
Mike Ford,  Electronic Information Services Adviser,
JG125, The Headingley Library,
James Graham Building, Leeds Metropolitan University,
Headingley Campus, LEEDS,  LS6 3QS,  United Kingdom
Email: [EMAIL PROTECTED]
Tel: +44 113 812 4730  Fax:  +44 113 812 3211 





To view the terms under which this email is distributed, please go to 
http://disclaimer.leedsmet.ac.uk/email.htm


--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: AW: [PHP-DEV] A rebuttal to Re: RFC: Dropping Namespace

2007-12-08 Thread Gregory Beaver
Jessie Hernandez wrote:
 Hi Greg,

 How about this: any non-namespaced file that uses use statements is
 implicitly put into the __php__ namespace (or whatever other name is
 chosen, or having the namespace name be the path of the file)? With
 this, use will never import any symbols into the global namespace. 
Hi Jessie,

Imagine how that would affect this code:

file1.php:
?php
function doSomething() {}
?

PEAR2/DB.php: hypothetical
?php
namespace PEAR2;
class DB {}
?

file2.php:
?php
include 'file1.php';
include 'PEAR2/DB.php';
use PEAR2::DB;
$a = new DB;
$b = doSomething();
?

In file2.php, because there is a use statement, the rest of the file
is assumed to be in the __php__ namespace.  As such, the file can be
expanded into this code:

new_file2.php:
?php
namespace __php__;
include 'file1.php';
include 'file2.php';
$a = new PEAR2::DB;
$b = doSomething();
?

On the last line, when PHP calls doSomething(), it first checks to see
if the function doSomething is available as an internal function. 
Then, it tries __php__::doSomething() and fails on a fatal error because
the function does not exist.  The only way that your idea would work is
if the check for doSomething consisted of checking for any
non-namespaced function (not just internal functions), but the sole
purpose of the fall-through is to allow users to call internal
functions/classes without explicitly specifying ::strlen or ::count and
so on.  Allowing fall-through to any global class/function would serve
to dilute the namespacing effect, but perhaps this is a good thing?  I
have not thought about this long enough to have a definitive opinion yet.

I think one safe way to handle this might be to have an E_STRICT if
class/function/const is declared in the __php__ namespace, so that PHP
provides a clear mechanism for enforcing the convention.  Users wishing
to avoid this E_STRICT need only use another namespace name or adhere to
the coding convention of only putting stuff that uses code into the
__php__ namespace.

Greg

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] A rebuttal to Re: RFC: Dropping Namespace

2007-12-07 Thread Sam Barrow
I agree with everything here, especially the solution to multiple
namespaces per file (allow but discourage), but i don't agree with the
__php__ namespace. If any separation of core php and extensions into
namespaces happens, it should be kept as simple as possible, with root
namespaces like php:: and ext::. The application should be allowed
to define its own root namespace, or use a namespace such as app::.
Besides that I think all of your other suggestions are the best ones.

On Thu, 2007-12-06 at 19:36 -0600, Gregory Beaver wrote:
 Hi Derick,
 
 I've been thinking a *lot* about your provocative email in the past
 couple of days, and have come to a different conclusion from my original
 reply (which, as a reminder stated I saw no problem with removing
 namespaces as long as we kept the import facility to alias classes via
 use).  After a few hours of thinking practically about the
 implementation, I realized that this would be impossible for the same
 reasons as your first argument.  So, I set out to find a solution that
 keeps namespaces and solves the problems.
 
 I have found the solutions to every problem I could find, and to my
 surprise, even after crafting a new patch to solve some of them, have
 found a way to solve all of the problems within the existing
 implementation (with a few tweaks, but nothing major changed) or by
 specifying new coding conventions.
 
 Summary:
 
 1) recommend all global non-namespaced code that wishes to import
 namespaced code via use Namespace::Classname add a namespace
 __php__; at the top of the file, and that the __php__ namespace be
 reserved for use by end-user applications.
 2) use Name::*; is technically impossible without some kind of
 autoloading mechanism, but can be reasonably approximated by importing a
 long namespace name as a shorter one.  use PEAR2::Really::Long::Name as
 a; then allows referring to PEAR2::Really::Long::Name::Classname as
 a::Classname, and PEAR2::Really::Long::Subnamespace::Classname as
 a::Subnamespace::Classname.
 3) multiple namespaces per file should be allowed, but strongly
 discouraged as a coding practice of last resort for most users.
 4) brackets for namespaces is most necessary for hierarchical namespace
 implementations.  This is not such an implementation, and as such
 brackets do not add clarity but do slow down the implementation.
 5) namespaces provide these benefits that are not available in PHP:
a) short, unqualified descriptive class names can be used without
 fear of conflicting with an internal class
b) a clear, uniform coding convention on how to avoid conflicts
 between your code and others that will help those who have to maintain
 the code of others.
c) a way to alias longer names to increase readability and
 maintainability of code.
 6) There are some dangers when using namespaces with autoload, but
 simple ways of thwarting those dangers.  Also dangerous is trusting
 external code that is in the same namespace, as functions can be redefined.
 
 Detailed answers:
 
 Derick Rethans wrote:
  1. As it is impossible to do use XXX as NativeClass we get to the 
 snip
 extension (DateTime, DateTimeZone). However introducing the new class
 DateTimeSpan might break people's code that do things like:
  
  ?php
  use myNamespace::DateTimeZone as DateTimeZone;
  ?
 
 This is indeed the biggest problem.  However, it only exists in the
 global namespace (non-namespaced code).  An example script using the
 non-existing hypothetical PEAR2::DateTime class:
 
 ?php
 include 'PEAR2/Autoload.php';
 use PEAR2::DateTime; // fatal error - use name conflicts with internal class
 $a = new DateTime;
 ?
 
 However, the answer is simple and elegant.  PHP applications that take
 advantage of namespaces should use a namespace *in the application
 global code* that is reserved for application code, like __php__.
 
 ?php
 namespace __php__;
 include 'PEAR2/Autoload.php';
 use PEAR2::DateTime;
 $a = new DateTime; // $a is an object of class PEAR2::DateTime after
 autoloading, or if a previously included file has declared class
 DateTime in namespace PEAR
 ?
 
 Note that the only difference here is the addition of 1 line of code at
 the top of the file.  On the same token, this code:
 
 ?php
 namespace __php__;
 $a = new DateTime; // $a is an object of class ::DateTime
 ?
 
 works as expected, accessing the internal DateTime class directly.
 
 In other words, 1 line of code is needed to take advantage of
 namespace's full protection and ability to import conflicting class
 names into the global (in this case unqualified, not containing :: in
 the name) scope, while at the same time preserving BC with existing code
 (no modification needed beyond addition of namespace __php__;).
 
 I recommend that the manual specify this convention, and will happily
 take on the documentation of it.
 
  2. You have to import every class yourself. You can currently not do:
 
  use myNamespace::* as *; // or similar 

Re: [PHP-DEV] A rebuttal to Re: RFC: Dropping Namespace

2007-12-07 Thread Derick Rethans
On Thu, 6 Dec 2007, Gregory Beaver wrote:

 I've been thinking a *lot* about your provocative email in the past
 couple of days, and have come to a different conclusion from my original
 reply (which, as a reminder stated I saw no problem with removing
 namespaces as long as we kept the import facility to alias classes via
 use).  After a few hours of thinking practically about the
 implementation, I realized that this would be impossible for the same
 reasons as your first argument.  So, I set out to find a solution that
 keeps namespaces and solves the problems.

Right, that was the idea behind the mail :) As yours is pretty long, I'm 
only going to respond to the main points.

 1) recommend all global non-namespaced code that wishes to import
 namespaced code via use Namespace::Classname add a namespace
 __php__; at the top of the file, and that the __php__ namespace be
 reserved for use by end-user applications.

 2) use Name::*; is technically impossible without some kind of
 autoloading mechanism, but can be reasonably approximated by importing a
 long namespace name as a shorter one.  use PEAR2::Really::Long::Name as
 a; then allows referring to PEAR2::Really::Long::Name::Classname as
 a::Classname, and PEAR2::Really::Long::Subnamespace::Classname as
 a::Subnamespace::Classname.

Yeah, I know... I don't really care about this myself anyway - it's just 
something that I heard in discussions.

[snip]
 
 Detailed answers:
 
 Derick Rethans wrote:
  1. As it is impossible to do use XXX as NativeClass we get to the 
 snip
 extension (DateTime, DateTimeZone). However introducing the new class
 DateTimeSpan might break people's code that do things like:
  
  ?php
  use myNamespace::DateTimeZone as DateTimeZone;
  ?
 
 This is indeed the biggest problem.  However, it only exists in the
 global namespace (non-namespaced code).  An example script using the
 non-existing hypothetical PEAR2::DateTime class:
 
 ?php
 include 'PEAR2/Autoload.php';
 use PEAR2::DateTime; // fatal error - use name conflicts with internal class
 $a = new DateTime;
 ?
 
 However, the answer is simple and elegant.  PHP applications that take
 advantage of namespaces should use a namespace *in the application
 global code* that is reserved for application code, like __php__.
 
 ?php
 namespace __php__;
 include 'PEAR2/Autoload.php';
 use PEAR2::DateTime;
 $a = new DateTime; // $a is an object of class PEAR2::DateTime after
 autoloading, or if a previously included file has declared class
 DateTime in namespace PEAR
 ?
 
 Note that the only difference here is the addition of 1 line of code at
 the top of the file.  On the same token, this code:
 
 ?php
 namespace __php__;
 $a = new DateTime; // $a is an object of class ::DateTime
 ?
 
 works as expected, accessing the internal DateTime class directly.
 
 In other words, 1 line of code is needed to take advantage of
 namespace's full protection and ability to import conflicting class
 names into the global (in this case unqualified, not containing :: in
 the name) scope, while at the same time preserving BC with existing code
 (no modification needed beyond addition of namespace __php__;).
 
 I recommend that the manual specify this convention, and will happily
 take on the documentation of it.

  2. You have to import every class yourself. You can currently not do:
 
  use myNamespace::* as *; // or similar syntax

[snip]
 
 There are ways of simulating use myNamespace::* as *; that are almost
 as complete and are actually better for long-term maintenance.  For
 instance, let's say you want to use several classes from
 PEAR2::Ultra::Long::Package::Name.  You don't need to use each class
 individually, you can import the entire namespace:
 
 ?php
 namespace __php__;
 use PEAR2::Ultra::Long::Package::Name;
 $a = new Name::ExampleClass;
 $b = new Name::SecondThing;
 $c = new Name::ThirdThing;
 ?

Sounds like a good idea.

 I have no strong opinion on {}, but I do see a compelling argument in
 favor of not using {} for performance reasons if you're only going to
 use 1 namespace per file except in extraordinary circumstances.

The only thing that in the case you *have* a multi-namespace file, using 
braces would editors allow to the start and end of a namespace easily 
(f.e. VIM's %).

 A larger danger is this example:
 
 ?php
 namespace foo;
 echo strlen('hi');
 include 'maliciousfile.php';
 echo strlen('hi');
 ?
 
 maliciousfile.php:
 ?php
 namespace foo;
 function strlen($a)
 {
 // do bad stuff
 echo I'm evil
 return ::strlen($a);
 }
 ?
 
 The above script outputs 2I'm evil2 - foo::strlen() is called for the
 second call to strlen().

I thought only constants and classes could be parts of namespaces?

regards,
Derick

-- 
Derick Rethans
http://derickrethans.nl | http://ezcomponents.org | http://xdebug.org

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



RE: [PHP-DEV] A rebuttal to Re: RFC: Dropping Namespace

2007-12-07 Thread Ford, Mike
On 07 December 2007 01:36, Gregory Beaver wrote:

[...snip...]

 In other words, 1 line of code is needed to take advantage of
 namespace's full protection and ability to import conflicting class
 names into the global (in this case unqualified, not
 containing :: in
 the name) scope, while at the same time preserving BC with
 existing code
 (no modification needed beyond addition of namespace __php__;).
 
 I recommend that the manual specify this convention, and will happily
 take on the documentation of it.

I've only been skimming the namespace argument, so forgive me if this is 
totally non-sensible, but if such usage is fully BC, and has only upsides with 
no downside, would there be any mileage in making it implicit rather than 
explicit -- i.e., any code not explicitly namespaced is automatically in the 
reserved namespace __php__?  Such usage could be completely invisible to your 
everyday PHP user, and only need explaining in an intro to namespaces section.

Cheers!

Mike


Mike Ford,  Electronic Information Services Adviser,
JG125, The Headingley Library
James Graham Building, Headingley Campus
Tel: extn 24730Fax: extn 23211 


To view the terms under which this email is distributed, please go to 
http://disclaimer.leedsmet.ac.uk/email.htm


Re: AW: [PHP-DEV] A rebuttal to Re: RFC: Dropping Namespace

2007-12-07 Thread Gregory Beaver
Matthias Pigulla wrote:
 1) recommend all global non-namespaced code that wishes to import 
 namespaced code via use Namespace::Classname add a namespace 
 __php__; at the top of the file, and that the __php__ namespace be
  reserved for use by end-user applications.
 
 
 5) namespaces provide these benefits that are not available in PHP:
  a) short, unqualified descriptive class names can be used without 
 fear of conflicting with an internal class
 
 Interesting as I was not aware before that when a namespace is active
 the import goes into that namespace and not into global scope
 (clashing with core classes there).
 
 But please consider:
 
 -- Date.php -- ?php namespace __php__; class Date {} ?
 
 -- test.php -- ?php namespace __php__; require_once('autoload.php');
 // assume it would require Date.php when asked to do so print
 get_class(new Date()); ?
 
 Although this code has been future-proofed by adding the namespace
 __php__, it will break if the core introduces a class named Date
 (will use the wrong class!). It also breaks without the namespace,
 and maybe it is a mistake to rely on autload here. But this is a case
 where using namespaces does not protect you from surprises unless you
 explicitly import (use) all the classes you need. But that is not
 as simple as putting a namespace statement on top of all your files
 to be save.
 
 If new, future core extensions showed up in a reserved PHP::
 namespace, you would be :-).

Exactly - which is why you should never put classes, functions or
constants in the __php__ namespace.  The convention I am proposing is to
only use __php__ for code that *uses* re-usable components, not
*declares* them.  In this case, your example would be revised as:

?php
namespace Mylib;
class Date {}
?

?php
namespace __php__;
use Mylib::Date;
include 'autoload.php'; // note - require_once and () just slow things down
$a = new Date();
?

This convention serves two purposes

1) library code is always explicitly used
2) name conflicts are impossible

The suggestion to make namespace __php__; implicit is very
interesting, but would defeat its purpose, which is to separate
declarations from use.

Another off-list suggestion was to make use outside of a namespace
declaration an error, as this is generally a bad idea that can lead to
many gotchas.

Greg

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] A rebuttal to Re: RFC: Dropping Namespace

2007-12-07 Thread Steph Fox

Hi Greg,


1) recommend all global non-namespaced code that wishes to import
namespaced code via use Namespace::Classname add a namespace
__php__; at the top of the file, and that the __php__ namespace be
reserved for use by end-user applications.


That answers my main concern, but I'd make it stronger than a 
recommendation. I'd make it impossible to import namespaced code into the 
global space.


- Steph 


--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



AW: [PHP-DEV] A rebuttal to Re: RFC: Dropping Namespace

2007-12-07 Thread Matthias Pigulla

 1) recommend all global non-namespaced code that wishes to import
 namespaced code via use Namespace::Classname add a namespace
 __php__; at the top of the file, and that the __php__ namespace be
 reserved for use by end-user applications.


 5) namespaces provide these benefits that are not available in PHP:
a) short, unqualified descriptive class names can be used without
 fear of conflicting with an internal class

Interesting as I was not aware before that when a namespace is active the 
import goes into that namespace and not into global scope (clashing with core 
classes there).

But please consider:

-- Date.php --
?php
namespace __php__;
class Date {}
?

-- test.php --
?php
namespace __php__;
require_once('autoload.php'); // assume it would require Date.php when 
asked to do so
print get_class(new Date());
?

Although this code has been future-proofed by adding the namespace __php__, 
it will break if the core introduces a class named Date (will use the wrong 
class!). It also breaks without the namespace, and maybe it is a mistake to 
rely on autload here. But this is a case where using namespaces does not 
protect you from surprises unless you explicitly import (use) all the classes 
you need. But that is not as simple as putting a namespace statement on top of 
all your files to be save.

If new, future core extensions showed up in a reserved PHP:: namespace, you 
would be :-).

-mp.




Re: AW: [PHP-DEV] A rebuttal to Re: RFC: Dropping Namespace

2007-12-07 Thread Larry Garfield
On Friday 07 December 2007, Gregory Beaver wrote:

  If new, future core extensions showed up in a reserved PHP::
  namespace, you would be :-).

 Exactly - which is why you should never put classes, functions or
 constants in the __php__ namespace.  The convention I am proposing is to
 only use __php__ for code that *uses* re-usable components, not
 *declares* them.  In this case, your example would be revised as:

 ?php
 namespace Mylib;
 class Date {}
 ?

 ?php
 namespace __php__;
 use Mylib::Date;
 include 'autoload.php'; // note - require_once and () just slow things down
 $a = new Date();
 ?

 This convention serves two purposes

 1) library code is always explicitly used
 2) name conflicts are impossible

 The suggestion to make namespace __php__; implicit is very
 interesting, but would defeat its purpose, which is to separate
 declarations from use.

 Another off-list suggestion was to make use outside of a namespace
 declaration an error, as this is generally a bad idea that can lead to
 many gotchas.

 Greg

Doesn't strict C++ also have a requirement for a global namespace definition?  
It has been a very long time since I did any C++, but I seem to recall a 
requirement for a use std or something like that directive that I never 
actually understood. :-)

If there is a named global namespace __php__, then requiring it in order to 
import anything makes sense.  It's one extra line of code and doesn't break 
BC anymore than using the use keyword does.  

Another observation, if one takes the position that library code and running 
code should always be separated, this setup would encourage that best 
practice but does not absolutely require it.  That fits with the doing 
something dumb should be hard, but not impossible philosophy. :-)  That 
recommendation would definitely need to be well-documented.

I overall like this concept.  Kudos to Greg, as others have said.  One 
question I would have is what is the performance hit of braces over a 
keyword?  (Not a challenge; I genuinely don't know what the C implementation 
differences would be that would make a difference.)  

-- 
Larry Garfield  AIM: LOLG42
[EMAIL PROTECTED]   ICQ: 6817012

If nature has made any one thing less susceptible than all others of 
exclusive property, it is the action of the thinking power called an idea, 
which an individual may exclusively possess as long as he keeps it to 
himself; but the moment it is divulged, it forces itself into the possession 
of every one, and the receiver cannot dispossess himself of it.  -- Thomas 
Jefferson

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



AW: [PHP-DEV] A rebuttal to Re: RFC: Dropping Namespace

2007-12-07 Thread Matthias Pigulla
 Von: Gregory Beaver [mailto:[EMAIL PROTECTED]

 Exactly - which is why you should never put classes, functions or
 constants in the __php__ namespace.  The convention I am proposing is
 to
 only use __php__ for code that *uses* re-usable components, not
 *declares* them. 

Let alone __php__. If you just put all of your code into namespace Mylib, 
you're not safe because according to the name resolution rules, internal 
classes come after imported ones but before trying to find classes in the 
current namespace.

 1) library code is always explicitly used
 2) name conflicts are impossible

1) is the crucial one because that puts your classes ahead of the internal ones 
in the resolution list. That is not only library code you explicitly use, but 
also all code from your own namespace. Having to explicitly enumerate all 
classes you use in your own namespace in every file may be tedious. 

So just to get that straight: Having a namespace statement and no use 
(because all you use is from your library) is a discouraged practise?

Thanks!
-mp.




Re: [PHP-DEV] A rebuttal to Re: RFC: Dropping Namespace

2007-12-07 Thread Roman Borschel

Great work!

+1 from me for your proposals, too!

Roman

On Dec 7, 2007, at 2:36 AM, Gregory Beaver wrote:


Hi Derick,

I've been thinking a *lot* about your provocative email in the past
couple of days, and have come to a different conclusion from my  
original

reply (which, as a reminder stated I saw no problem with removing
namespaces as long as we kept the import facility to alias classes via
use).  After a few hours of thinking practically about the
implementation, I realized that this would be impossible for the same
reasons as your first argument.  So, I set out to find a solution that
keeps namespaces and solves the problems.

I have found the solutions to every problem I could find, and to my
surprise, even after crafting a new patch to solve some of them, have
found a way to solve all of the problems within the existing
implementation (with a few tweaks, but nothing major changed) or by
specifying new coding conventions.

Summary:

1) recommend all global non-namespaced code that wishes to import
namespaced code via use Namespace::Classname add a namespace
__php__; at the top of the file, and that the __php__ namespace be
reserved for use by end-user applications.
2) use Name::*; is technically impossible without some kind of
autoloading mechanism, but can be reasonably approximated by  
importing a
long namespace name as a shorter one.  use  
PEAR2::Really::Long::Name as

a; then allows referring to PEAR2::Really::Long::Name::Classname as
a::Classname, and PEAR2::Really::Long::Subnamespace::Classname as
a::Subnamespace::Classname.
3) multiple namespaces per file should be allowed, but strongly
discouraged as a coding practice of last resort for most users.
4) brackets for namespaces is most necessary for hierarchical  
namespace

implementations.  This is not such an implementation, and as such
brackets do not add clarity but do slow down the implementation.
5) namespaces provide these benefits that are not available in PHP:
  a) short, unqualified descriptive class names can be used without
fear of conflicting with an internal class
  b) a clear, uniform coding convention on how to avoid conflicts
between your code and others that will help those who have to maintain
the code of others.
  c) a way to alias longer names to increase readability and
maintainability of code.
6) There are some dangers when using namespaces with autoload, but
simple ways of thwarting those dangers.  Also dangerous is trusting
external code that is in the same namespace, as functions can be  
redefined.


Detailed answers:

Derick Rethans wrote:

1. As it is impossible to do use XXX as NativeClass we get to the

snip
  extension (DateTime, DateTimeZone). However introducing the new  
class

  DateTimeSpan might break people's code that do things like:

?php
use myNamespace::DateTimeZone as DateTimeZone;
?


This is indeed the biggest problem.  However, it only exists in the
global namespace (non-namespaced code).  An example script using the
non-existing hypothetical PEAR2::DateTime class:

?php
include 'PEAR2/Autoload.php';
use PEAR2::DateTime; // fatal error - use name conflicts with  
internal class

$a = new DateTime;
?

However, the answer is simple and elegant.  PHP applications that take
advantage of namespaces should use a namespace *in the application
global code* that is reserved for application code, like __php__.

?php
namespace __php__;
include 'PEAR2/Autoload.php';
use PEAR2::DateTime;
$a = new DateTime; // $a is an object of class PEAR2::DateTime after
autoloading, or if a previously included file has declared class
DateTime in namespace PEAR
?

Note that the only difference here is the addition of 1 line of code  
at

the top of the file.  On the same token, this code:

?php
namespace __php__;
$a = new DateTime; // $a is an object of class ::DateTime
?

works as expected, accessing the internal DateTime class directly.

In other words, 1 line of code is needed to take advantage of
namespace's full protection and ability to import conflicting class
names into the global (in this case unqualified, not containing ::  
in
the name) scope, while at the same time preserving BC with existing  
code

(no modification needed beyond addition of namespace __php__;).

I recommend that the manual specify this convention, and will happily
take on the documentation of it.


2. You have to import every class yourself. You can currently not do:

   use myNamespace::* as *; // or similar syntax


Actually, ::* would only be deterministic if use performed some kind  
of

autoloading, it's not a question of runtime versus compile-time - it's
simply not possible to determine which class is intended if more than
one ::* is used unless the answer is determined by code loading,  
this is
why Java/Python import actually loads code as well as aliasing  
identifiers.


There are ways of simulating use myNamespace::* as *; that are  
almost

as complete and are actually better for long-term 

[PHP-DEV] A rebuttal to Re: RFC: Dropping Namespace

2007-12-06 Thread Gregory Beaver
Hi Derick,

I've been thinking a *lot* about your provocative email in the past
couple of days, and have come to a different conclusion from my original
reply (which, as a reminder stated I saw no problem with removing
namespaces as long as we kept the import facility to alias classes via
use).  After a few hours of thinking practically about the
implementation, I realized that this would be impossible for the same
reasons as your first argument.  So, I set out to find a solution that
keeps namespaces and solves the problems.

I have found the solutions to every problem I could find, and to my
surprise, even after crafting a new patch to solve some of them, have
found a way to solve all of the problems within the existing
implementation (with a few tweaks, but nothing major changed) or by
specifying new coding conventions.

Summary:

1) recommend all global non-namespaced code that wishes to import
namespaced code via use Namespace::Classname add a namespace
__php__; at the top of the file, and that the __php__ namespace be
reserved for use by end-user applications.
2) use Name::*; is technically impossible without some kind of
autoloading mechanism, but can be reasonably approximated by importing a
long namespace name as a shorter one.  use PEAR2::Really::Long::Name as
a; then allows referring to PEAR2::Really::Long::Name::Classname as
a::Classname, and PEAR2::Really::Long::Subnamespace::Classname as
a::Subnamespace::Classname.
3) multiple namespaces per file should be allowed, but strongly
discouraged as a coding practice of last resort for most users.
4) brackets for namespaces is most necessary for hierarchical namespace
implementations.  This is not such an implementation, and as such
brackets do not add clarity but do slow down the implementation.
5) namespaces provide these benefits that are not available in PHP:
   a) short, unqualified descriptive class names can be used without
fear of conflicting with an internal class
   b) a clear, uniform coding convention on how to avoid conflicts
between your code and others that will help those who have to maintain
the code of others.
   c) a way to alias longer names to increase readability and
maintainability of code.
6) There are some dangers when using namespaces with autoload, but
simple ways of thwarting those dangers.  Also dangerous is trusting
external code that is in the same namespace, as functions can be redefined.

Detailed answers:

Derick Rethans wrote:
 1. As it is impossible to do use XXX as NativeClass we get to the 
snip
extension (DateTime, DateTimeZone). However introducing the new class
DateTimeSpan might break people's code that do things like:
 
   ?php
   use myNamespace::DateTimeZone as DateTimeZone;
   ?

This is indeed the biggest problem.  However, it only exists in the
global namespace (non-namespaced code).  An example script using the
non-existing hypothetical PEAR2::DateTime class:

?php
include 'PEAR2/Autoload.php';
use PEAR2::DateTime; // fatal error - use name conflicts with internal class
$a = new DateTime;
?

However, the answer is simple and elegant.  PHP applications that take
advantage of namespaces should use a namespace *in the application
global code* that is reserved for application code, like __php__.

?php
namespace __php__;
include 'PEAR2/Autoload.php';
use PEAR2::DateTime;
$a = new DateTime; // $a is an object of class PEAR2::DateTime after
autoloading, or if a previously included file has declared class
DateTime in namespace PEAR
?

Note that the only difference here is the addition of 1 line of code at
the top of the file.  On the same token, this code:

?php
namespace __php__;
$a = new DateTime; // $a is an object of class ::DateTime
?

works as expected, accessing the internal DateTime class directly.

In other words, 1 line of code is needed to take advantage of
namespace's full protection and ability to import conflicting class
names into the global (in this case unqualified, not containing :: in
the name) scope, while at the same time preserving BC with existing code
(no modification needed beyond addition of namespace __php__;).

I recommend that the manual specify this convention, and will happily
take on the documentation of it.

 2. You have to import every class yourself. You can currently not do:

 use myNamespace::* as *; // or similar syntax

Actually, ::* would only be deterministic if use performed some kind of
autoloading, it's not a question of runtime versus compile-time - it's
simply not possible to determine which class is intended if more than
one ::* is used unless the answer is determined by code loading, this is
why Java/Python import actually loads code as well as aliasing identifiers.

There are ways of simulating use myNamespace::* as *; that are almost
as complete and are actually better for long-term maintenance.  For
instance, let's say you want to use several classes from
PEAR2::Ultra::Long::Package::Name.  You don't need to use each class

Re: [PHP-DEV] A rebuttal to Re: RFC: Dropping Namespace

2007-12-06 Thread Ken Stanley
Holy wow. That was fantastic! Not to downplay anything that Stas and the
other developers have done -- because let's face it, they've done a
fantastic job themselves -- you have definitely risen above and beyond the
call of duty and really come up with some very compelling counter-arguments.
This really makes me look forward to using namespaces, and to reading your
guides. Thank you for all of the time and effort you, and those who have
spent time helping you, have put into this feature. :)


RE: [PHP-DEV] A rebuttal to Re: RFC: Dropping Namespace

2007-12-06 Thread Andi Gutmans
Hi Greg,

Thanks for the detailed thoughts.
Guides  examples regarding use-cases will definitely be important for the 
community. I am sure just this email has already been very helpful to many on 
this list.

Andi

 -Original Message-
 From: Gregory Beaver [mailto:[EMAIL PROTECTED]
 Sent: Thursday, December 06, 2007 5:36 PM
 To: Derick Rethans
 Cc: PHP Developers Mailing List
 Subject: [PHP-DEV] A rebuttal to Re: RFC: Dropping Namespace
 
 Hi Derick,
 
 I've been thinking a *lot* about your provocative email in the past
 couple of days, and have come to a different conclusion from my
 original
 reply (which, as a reminder stated I saw no problem with removing
 namespaces as long as we kept the import facility to alias classes via
 use).  After a few hours of thinking practically about the
 implementation, I realized that this would be impossible for the same
 reasons as your first argument.  So, I set out to find a solution that
 keeps namespaces and solves the problems.
 
 I have found the solutions to every problem I could find, and to my
 surprise, even after crafting a new patch to solve some of them, have
 found a way to solve all of the problems within the existing
 implementation (with a few tweaks, but nothing major changed) or by
 specifying new coding conventions.
 
 Summary:
 
 1) recommend all global non-namespaced code that wishes to import
 namespaced code via use Namespace::Classname add a namespace
 __php__; at the top of the file, and that the __php__ namespace be
 reserved for use by end-user applications.
 2) use Name::*; is technically impossible without some kind of
 autoloading mechanism, but can be reasonably approximated by importing
 a
 long namespace name as a shorter one.  use PEAR2::Really::Long::Name
 as
 a; then allows referring to PEAR2::Really::Long::Name::Classname as
 a::Classname, and PEAR2::Really::Long::Subnamespace::Classname as
 a::Subnamespace::Classname.
 3) multiple namespaces per file should be allowed, but strongly
 discouraged as a coding practice of last resort for most users.
 4) brackets for namespaces is most necessary for hierarchical namespace
 implementations.  This is not such an implementation, and as such
 brackets do not add clarity but do slow down the implementation.
 5) namespaces provide these benefits that are not available in PHP:
a) short, unqualified descriptive class names can be used without
 fear of conflicting with an internal class
b) a clear, uniform coding convention on how to avoid conflicts
 between your code and others that will help those who have to maintain
 the code of others.
c) a way to alias longer names to increase readability and
 maintainability of code.
 6) There are some dangers when using namespaces with autoload, but
 simple ways of thwarting those dangers.  Also dangerous is trusting
 external code that is in the same namespace, as functions can be
 redefined.
 
 Detailed answers:
 
 Derick Rethans wrote:
  1. As it is impossible to do use XXX as NativeClass we get to the
 snip
 extension (DateTime, DateTimeZone). However introducing the new
 class
 DateTimeSpan might break people's code that do things like:
 
  ?php
  use myNamespace::DateTimeZone as DateTimeZone;
  ?
 
 This is indeed the biggest problem.  However, it only exists in the
 global namespace (non-namespaced code).  An example script using the
 non-existing hypothetical PEAR2::DateTime class:
 
 ?php
 include 'PEAR2/Autoload.php';
 use PEAR2::DateTime; // fatal error - use name conflicts with internal
 class
 $a = new DateTime;
 ?
 
 However, the answer is simple and elegant.  PHP applications that take
 advantage of namespaces should use a namespace *in the application
 global code* that is reserved for application code, like __php__.
 
 ?php
 namespace __php__;
 include 'PEAR2/Autoload.php';
 use PEAR2::DateTime;
 $a = new DateTime; // $a is an object of class PEAR2::DateTime after
 autoloading, or if a previously included file has declared class
 DateTime in namespace PEAR
 ?
 
 Note that the only difference here is the addition of 1 line of code at
 the top of the file.  On the same token, this code:
 
 ?php
 namespace __php__;
 $a = new DateTime; // $a is an object of class ::DateTime
 ?
 
 works as expected, accessing the internal DateTime class directly.
 
 In other words, 1 line of code is needed to take advantage of
 namespace's full protection and ability to import conflicting class
 names into the global (in this case unqualified, not containing :: in
 the name) scope, while at the same time preserving BC with existing
 code
 (no modification needed beyond addition of namespace __php__;).
 
 I recommend that the manual specify this convention, and will happily
 take on the documentation of it.
 
  2. You have to import every class yourself. You can currently not do:
 
  use myNamespace::* as *; // or similar syntax
 
 Actually, ::* would only be deterministic if use performed some kind

Re: [PHP-DEV] A rebuttal to Re: RFC: Dropping Namespace

2007-12-06 Thread Jeremy Privett

Hi Greg,

I'm speechless. All of your points are sound and you've obviously done 
your homework, here. I agree with Ken in that you've gone above and 
beyond on the research and arguments you've presented here.


Excellent work and a hearty +1 to all of your points.

Jeremy

Gregory Beaver wrote:

Hi Derick,

I've been thinking a *lot* about your provocative email in the past
couple of days, and have come to a different conclusion from my original
reply (which, as a reminder stated I saw no problem with removing
namespaces as long as we kept the import facility to alias classes via
use).  After a few hours of thinking practically about the
implementation, I realized that this would be impossible for the same
reasons as your first argument.  So, I set out to find a solution that
keeps namespaces and solves the problems.

I have found the solutions to every problem I could find, and to my
surprise, even after crafting a new patch to solve some of them, have
found a way to solve all of the problems within the existing
implementation (with a few tweaks, but nothing major changed) or by
specifying new coding conventions.

Summary:

1) recommend all global non-namespaced code that wishes to import
namespaced code via use Namespace::Classname add a namespace
__php__; at the top of the file, and that the __php__ namespace be
reserved for use by end-user applications.
2) use Name::*; is technically impossible without some kind of
autoloading mechanism, but can be reasonably approximated by importing a
long namespace name as a shorter one.  use PEAR2::Really::Long::Name as
a; then allows referring to PEAR2::Really::Long::Name::Classname as
a::Classname, and PEAR2::Really::Long::Subnamespace::Classname as
a::Subnamespace::Classname.
3) multiple namespaces per file should be allowed, but strongly
discouraged as a coding practice of last resort for most users.
4) brackets for namespaces is most necessary for hierarchical namespace
implementations.  This is not such an implementation, and as such
brackets do not add clarity but do slow down the implementation.
5) namespaces provide these benefits that are not available in PHP:
   a) short, unqualified descriptive class names can be used without
fear of conflicting with an internal class
   b) a clear, uniform coding convention on how to avoid conflicts
between your code and others that will help those who have to maintain
the code of others.
   c) a way to alias longer names to increase readability and
maintainability of code.
6) There are some dangers when using namespaces with autoload, but
simple ways of thwarting those dangers.  Also dangerous is trusting
external code that is in the same namespace, as functions can be redefined.

Detailed answers:

Derick Rethans wrote:
  
1. As it is impossible to do use XXX as NativeClass we get to the 


snip
  

   extension (DateTime, DateTimeZone). However introducing the new class
   DateTimeSpan might break people's code that do things like:

?php
use myNamespace::DateTimeZone as DateTimeZone;
?



This is indeed the biggest problem.  However, it only exists in the
global namespace (non-namespaced code).  An example script using the
non-existing hypothetical PEAR2::DateTime class:

?php
include 'PEAR2/Autoload.php';
use PEAR2::DateTime; // fatal error - use name conflicts with internal class
$a = new DateTime;
?

However, the answer is simple and elegant.  PHP applications that take
advantage of namespaces should use a namespace *in the application
global code* that is reserved for application code, like __php__.

?php
namespace __php__;
include 'PEAR2/Autoload.php';
use PEAR2::DateTime;
$a = new DateTime; // $a is an object of class PEAR2::DateTime after
autoloading, or if a previously included file has declared class
DateTime in namespace PEAR
?

Note that the only difference here is the addition of 1 line of code at
the top of the file.  On the same token, this code:

?php
namespace __php__;
$a = new DateTime; // $a is an object of class ::DateTime
?

works as expected, accessing the internal DateTime class directly.

In other words, 1 line of code is needed to take advantage of
namespace's full protection and ability to import conflicting class
names into the global (in this case unqualified, not containing :: in
the name) scope, while at the same time preserving BC with existing code
(no modification needed beyond addition of namespace __php__;).

I recommend that the manual specify this convention, and will happily
take on the documentation of it.

  

2. You have to import every class yourself. You can currently not do:
   
use myNamespace::* as *; // or similar syntax



Actually, ::* would only be deterministic if use performed some kind of
autoloading, it's not a question of runtime versus compile-time - it's
simply not possible to determine which class is intended if more than
one ::* is used unless the answer is determined by code loading, this is
why Java/Python import