SitePoint Sponsor

User Tag List

Results 1 to 23 of 23
  1. #1
    SitePoint Zealot
    Join Date
    Feb 2003
    Location
    Virginia
    Posts
    143
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Namespaces - solutions to the problem

    I got the new 'Core PHP Programming' with Zeev Suraski and Leon Atkinson last week. I just finished it up and I have to say its was well written and to the point. I was somewhat pieved though as I got to page 132 with Namespaces though. There were examples and everything - as if it was going to be in the engine. I saw the Namespace seciton and thought again - this NEEDS to bein PHP5. The LongAsClassNamesThatDontConflict are getting out of hand so I decided to investigate the problem and come up with some posible solutions.

    After reading this post, http://www.sitepoint.com/forums/show...5&postcount=34 and this post http://www.zend.com/lists/engine2/200303/msg00181.html and this listing.. The last mention.. http://www.zend.com/lists/engine2/200303/mail2.html. Where do we begin?

    Whats keeping namespaces back? What logic puzzle remains to make the damn thing work as simple as class statements?

    What can we do to get namespaces included in PHP5?

    Res

  2. #2
    No. Phil.Roberts's Avatar
    Join Date
    May 2001
    Location
    Nottingham, UK
    Posts
    1,142
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Apparently the problem with Namespaces was mainly due to scoping issues, and the fact that said issues made it next to impossible to get the "import" command to work properly. And without the import command namespaces were next to useless.

    Many people put forward many idea's but they were ultimatly rejected simply because they couldn't be implemented without adding excessive demands on system resources (such as too much disk I/O when scanning namespace scopes). And Zeev Suraski has pretty much said that as far as he's concerned, Namespaces are gone for good.

    As Andi Gutmans said:
    So import System.Object means there is a subdirectory in System/ called Object/. But class Something extends System.Object ignores the folder called Object and looks for (and errors our on the lack of) a file called Object.php in the folder System/.
    So, you got disk lookup on each 'extends' statement? No good.

    Whatever syntax you use is a minor point, be it the traditional DOT reference or your : or :: reference.
    As a side point, dot reference is no more traditional than ':' or '::'.

    I have tried to follow your issues about namespaces, and I have to say I am afraid this email may not have addressed the issues adequately. But I hope there might be some sort of use in this idea that would resurrect the use of namespaces.
    Your idea, as I see it, lies in the field of packaging implementation.
    Namespaces is not the same as packaging, though the former can be used in the latter. The problems with namespaces were not 'how do we locate this
    class on disk', but how to implement scoping and scope importing in logical, efficient and easy-to-use way. The decision was reached that the way we have is not ripe for putting it into the language, so it was removed..

  3. #3
    SitePoint Zealot
    Join Date
    Feb 2003
    Location
    Virginia
    Posts
    143
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    So import System.Object means there is a subdirectory in System/ called Object/. But class Something extends System.Object ignores the folder called Object and looks for (and errors our on the lack of) a file called Object.php in the folder System/.
    Ok. My question is WHY is import even needed?

    ok.. I did quite a bit of reading and I think I understand what is being debated in context to namespaces.
    Last edited by Resolution; Feb 3, 2004 at 19:13.

  4. #4
    SitePoint Zealot
    Join Date
    Feb 2003
    Location
    Virginia
    Posts
    143
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Solution: #1

    Namespaces should not be nestable like classes.

    Reason:
    It causes too many problems - like here. http://www.zend.com/lists/engine2/200304/msg00171.html
    All sorts of namespace polution issues come into play and things get confusing for even the most experienced developers.

    Keeping namespaces non nestable allows one to allways know the behavior of any given namespace.

  5. #5
    SitePoint Zealot
    Join Date
    Feb 2003
    Location
    Virginia
    Posts
    143
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Solution: #2

    Import should not be included in the namespace implementation.

    Reason:
    PHP is about keeps development simple. Import (AFAIK) complicates PHP's main directive by enforcing a rigid filestructure, it breaks solution 1 and it would seem that making it function as advertised would require an engine rewrite.

  6. #6
    SitePoint Zealot
    Join Date
    Feb 2003
    Location
    Virginia
    Posts
    143
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Solution: #3

    Namespaces should not be able to merge - they should allways keep thier own memory spaces and they should be insted reference like objects and varibles.
    $N_dbase = Namespace PEAR:dbase;
    $record_set = new $N_dbase::RecordSet();
    This synatx or one similar would allow Namespace to cleanly partition code and keep class implementations seperate.

    Another idea for solution: http://www.zend.com/lists/engine2/200304/msg00232.html


    Reason:
    This prevents namespace polution. No more http://www.zend.com/lists/engine2/200304/msg00171.html issues like this and simplifies the code needed to implement namespaces on the engine side.
    Last edited by Resolution; Feb 3, 2004 at 20:46.

  7. #7
    No. Phil.Roberts's Avatar
    Join Date
    May 2001
    Location
    Nottingham, UK
    Posts
    1,142
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Resolution
    Solution: #2

    Import should not be included in the namespace implementation.

    Reason:
    PHP is about keeps development simple. Import (AFAIK) complicates PHP's main directive by enforcing a rigid filestructure, it breaks solution 1 and it would seem that making it function as advertised would require an engine rewrite.
    Without import you would have to call the entire namespace chain every time you wanted to instantiate a class, for example:

    bleh = new System.IO.Blah.Whatever.Cabbages;
    fnar = new System.IO.Blah.Whatever.Grapes;

    Instead of

    import System.IO.Blah.Whatever;

    bleh = new Cabbages;
    fnar = new Grapes;

    Can you really say that makes anything simple? You may as well not bother having namespaces at all if thats what you're forced into doing.

  8. #8
    SitePoint Zealot
    Join Date
    Feb 2003
    Location
    Virginia
    Posts
    143
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Phil,

    Thanks for responding. Please refer to Solution 3. I forsaw that question and tried to head it off. If you see any other potential questions Namespaces raise please do ask them.

    Res

  9. #9
    No. Phil.Roberts's Avatar
    Join Date
    May 2001
    Location
    Nottingham, UK
    Posts
    1,142
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Solution #3 isn't really namespaces at all. You could implement a similar system in PHP4 using a classloader mechanism and singleton patterns.

  10. #10
    SitePoint Zealot
    Join Date
    Feb 2003
    Location
    Virginia
    Posts
    143
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'm curious then,

    How would you define Namespaces and what solution is it to what problem?

    Since PHP is not a compiled language we must take different aproach to namespaces, as Zeev, Andy and others have stated. I don't really see another way around the problem but to simplify Namespaces. This will increase organization which should increase code reusability.

    In the end I see PHP being eclipsed by java, .NET (C#, ASP) and Python unless more steps are taken to increase the quality of the language. OOP is a good start but besides low server requirments and a high user install base what's going to keep the language afloat for the next 2/3 years?

    Mabey compiled PHP, shared space persistance, and default script caching is the next direction? Until then I don;t see PHP as having the longevity that it needs to compete. .NET and Java are looking more attractive all the time. Or at least they do when I catch myself whistling.
    <rant/>

    Res

  11. #11
    No. Phil.Roberts's Avatar
    Join Date
    May 2001
    Location
    Nottingham, UK
    Posts
    1,142
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Namespaces are basically nothing more than syntactical sugar. They make a specific task (name conflict elimination and object packaging) simpler and more automated, but ultimatly they arn't really anything special.

    Any you make the assumption that one day PHP will die out simply because it refuses to become more and more OO-centric. Which I think is false. PHP's simplicity and ability to handle both procedural and OO styles is it's strength.

    If your prediction were true then why has Python not already overtaken PHP? It has always had a far richer object model. Perl has had both multiple inheritence and namespaces for years, yet is rapidly becoming the dinosaur of the 'net. But PHP continues to grow in popularity and shows no sign of slowing down.

  12. #12
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by Phil.Roberts
    Namespaces are basically nothing more than syntactical sugar.
    In general terms they are actually an essential part of language construction and are already part of PHP by way of variable scope.

    What's needed is an extension by one level to avoid class and function name clashes when you bring in a library that used the same names as you did. The simplest to me would be...
    PHP Code:
    require_once_with_prefix('DB.php''pear_stuff_'); 
    Then you could use...
    PHP Code:
    $connection = &pear_stuff_DB::connect(...) 
    The name remapping applies to every class and function and could occour when the script was parsed. That way run time overhead would be eliminated.

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  13. #13
    SitePoint Zealot
    Join Date
    Feb 2003
    Location
    Virginia
    Posts
    143
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Marcus,

    Thx for the comment.

    Doesn't your solution imply nesting though? For instance what if DB.php in the example you provided had it's own require_once_with_prefix? Does that nest the prefixes?

    Your soloution seems similar to solution #3 - as in, reference the namespace to a varible and call with object or call namespace and object together.

    However things get done, namespaces should allways stay 1 level deep. I'l lgive an example if that doesn;t make 100% sense.

    Res

  14. #14
    Non-Member
    Join Date
    Jan 2004
    Location
    Planet Earth
    Posts
    1,764
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    We may not actually have Namespaces now, though it wouldn't be too difficult to roll your own ?

    For example,

    PHP Code:
    System.IO.Blah.Whatever.Cabbages 
    You'd have a directory structure, such as,

    PHP Code:
    System
    |--- IO
    |------ Blah
    |--------- Whatever
    |--- etc etc 
    So, for example if you have a custom function called IMPORT yes ? And used,

    PHP Code:
     Import'System.IO' ); 
    Then all files within the IO directory and below it would be INCLUDED ? What'd you think of this idea, wouldn't be too difficult to implement either I think

  15. #15
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by Resolution
    Doesn't your solution imply nesting though? For instance what if DB.php in the example you provided had it's own require_once_with_prefix? Does that nest the prefixes?
    That wasn't what I was thinking. I was thinking that pear_stuff_DB would still be called by that name and already tagged files would not be double tagged. So utilities.php...
    PHP Code:
    class Hammer { } 
    toolbox.php...
    PHP Code:
    require_once_with_prefix('utilities.php''ToolboxUtility');

    class 
    toolbox {
        ...
        function &
    getHammer() {
            return new 
    ToolboxUtilityHammer();
        }

    my_script.php...
    PHP Code:
    require_once_with_prefix('toolbox.php''My');

    $toolbox = &new MyToolbox();
    $hammer = &new ToolboxUtilityHammer();  // You would never do this. 
    What I am trying to do is to invert the logic. I am trying to push nameclashes out of the global namespace by tagging, rather than import things into the namespace under unique names. I think that this is a much easier problem to solve.

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  16. #16
    Non-Member coo_t2's Avatar
    Join Date
    Feb 2003
    Location
    Dog Street
    Posts
    1,819
    Mentioned
    1 Post(s)
    Tagged
    1 Thread(s)
    Quote Originally Posted by Widow Maker
    We may not actually have Namespaces now, though it wouldn't be too difficult to roll your own ?

    For example,

    PHP Code:
    System.IO.Blah.Whatever.Cabbages 
    You'd have a directory structure, such as,

    PHP Code:
    System
    |--- IO
    |------ Blah
    |--------- Whatever
    |--- etc etc 
    So, for example if you have a custom function called IMPORT yes ? And used,

    PHP Code:
     Import'System.IO' ); 
    Then all files within the IO directory and below it would be INCLUDED ? What'd you think of this idea, wouldn't be too difficult to implement either I think
    That might be a nice way of including all the files in a particular directory, but it still doesn't offer any protection from name clashes, does it?

    --ed

  17. #17
    Non-Member
    Join Date
    Jan 2004
    Location
    Planet Earth
    Posts
    1,764
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    does it?
    This would be something simular to Java's packages I think, and that has no clashes

    But I see your point though, there is room for fault

  18. #18
    eschew sesquipedalians silver trophy sweatje's Avatar
    Join Date
    Jun 2003
    Location
    Iowa, USA
    Posts
    3,749
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by lastcraft
    What I am trying to do is to invert the logic. I am trying to push nameclashes out of the global namespace by tagging, rather than import things into the namespace under unique names. I think that this is a much easier problem to solve.
    I think you are probably assuming a level of coupling that TDD drives, is in the library you are including. If in their code:
    PHP Code:
    require_once TOOL_LIB.'Nail.php';
    class 
    Hammer {
      function 
    Perform() {
        
    $foo =& new Nail;
      }

    Would now clash because it really should be trying to instanciate ToolboxUtilityNail, right?
    Jason Sweat ZCE - jsweat_php@yahoo.com
    Book: PHP Patterns
    Good Stuff: SimpleTest PHPUnit FireFox ADOdb YUI
    Detestable (adjective): software that isn't testable.

  19. #19
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by sweatje
    IWould now clash because it really should be trying to instanciate ToolboxUtilityNail, right?
    I am assuming that the act of PHP compilation would carry out the renaming a bit like a macro. Untagged included files would be tagged with the current tag name, but previously tagged ones wouldn't. Assuming each library chooses a unique name to pull it's dependents in I think it is OK. I haven't actually thought it all through though, so there are probably cases that can break it .

    One nasty case. If they have tests for hard coded class names using get_class(), then there would have to be a method get_current_prefix() that they can add to prefix the test to make it work. Not that I would want to encourage such things as hard coded classes...

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  20. #20
    eschew sesquipedalians silver trophy sweatje's Avatar
    Join Date
    Jun 2003
    Location
    Iowa, USA
    Posts
    3,749
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by lastcraft
    One nasty case. If they have tests for hard coded class names using get_class(), then there would have to be a method get_current_prefix() that they can add to prefix the test to make it work. Not that I would want to encourage such things as hard coded classes...
    Interestingly, I have already had to deal with similar issues with Mocks...I ended up with code like:
    PHP Code:
     if (!(is_object($poWiz) && false !== strpos(get_class($poWiz), 'wizard'))) {
    ... 
    basically, allowing that the name of the class I expect is anywhere in the get_class string, not just == the string.

    HTH

  21. #21
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by sweatje
    Interestingly, I have already had to deal with similar issues with Mocks...
    This was another reason for having a MethodExistenceExpectation class. Code should only test interfaces rather than implementation details like class names, and I beginning to think that test code should too.

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  22. #22
    SitePoint Zealot
    Join Date
    Feb 2003
    Location
    Virginia
    Posts
    143
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by lastcraft
    That wasn't what I was thinking. I was thinking that pear_stuff_DB would still be called by that name and already tagged files would not be double tagged.
    What do you mean by double tagged?

    Quote Originally Posted by lastcraft
    So utilities.php...
    PHP Code:
    class Hammer { } 
    toolbox.php...
    PHP Code:
    require_once_with_prefix('utilities.php''ToolboxUtility');
     
    class 
    toolbox {
    ...
    function &
    getHammer() {
    return new 
    ToolboxUtilityHammer();
    }

    my_script.php...
    PHP Code:
    require_once_with_prefix('toolbox.php''My');
     
    $toolbox = &new MyToolbox();
    $hammer = &new ToolboxUtilityHammer(); // You would never do this. 
    What I am trying to do is to invert the logic. I am trying to push nameclashes out of the global namespace by tagging, rather than import things into the namespace under unique names. I think that this is a much easier problem to solve.
    Perhaps, but there is a problem with your solution. It requires only one class per file which become a problem in itself, and I believe 1 class per file has been ruled out as not friendly.

    Also, the syntax is the same or similar. As solution #3 except that unique namespaces would be needed. In my understanding this makes the problem easier. Since the GLOBAL namespace IS a namespace it would simply need to housed in an array with the other namespaces and used as the default namespace. Get it? So this way the engine only needs to be changed slightly and we still get the benifits of a more organized class structure.

    Hope that makes sense.
    Res

  23. #23
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by Resolution
    What do you mean by double tagged?
    I mean no nesting. Basically not tag1_tag2_MyClass.

    Quote Originally Posted by Resolution
    Perhaps, but there is a problem with your solution. It requires only one class per file which become a problem in itself, and I believe 1 class per file has been ruled out as not friendly.
    I don't see how one class per file is required? I am certainly not suggesting this. The idea is that you import a library in such a way that any classes and functions coming from that library have had their names changes with a prefix for that library, unless they have also used another library in which case the dependent library can still be referred to by just the prefix chosen by the first library. Ideally the first library would not expose it's dependent, or if it did it would have imported it globally so that it gets the same prefix when imported by the app.

    I am referring to whole bunches of stuff though.

    Quote Originally Posted by Resolution
    Since the GLOBAL namespace IS a namespace it would simply need to housed in an array with the other namespaces and used as the default namespace.
    That is one implementation. By doing it at the import stage the lookups are uneccessary as the components will all be in the global namespace, albeit with modified names. Zero performance penalty.

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •