>> at runtime namespace resolution, static code analysis is now very hard > In general case, it always was so. Think of $foo->$bar()
Maybe I was too strong about the term "general case". What I though about is that although variable calls have always been there, they are both statistically rare and their real variability is most often very limited, so analyzing the code won't go very wrong. With namespaced functions, this: rare variability => quite good understandability is reversed to: large variability (any function call is potentially a source of variability) => much lower understandability (much higher risk of going completely wrong). >> 1. Remove namespaced functions and constants at all > This won't happen, for obvious BC reasons. I agree with that, please forget about this part. The idea came up while writing the mail but that was not my first idea, expressed in the other parts of my message... Going back on static call analysis, given that namespaced functions and constants exists, the next step to analyzing them correctly is for me to add some heuristics to the parser - for example: if function exists in the global space assume is has not been overwritten. This can go wrong but will work most of the time. Maybe enough for some rough analysis. If I want to go further, I do have to inform the analyser of some coding convention, to enhance it's capability to know were functions are defined. My RFC for namespace initializers helps on this part : giving a path for developers on where to put these definitions, exactly as autoload does for classes. > Autoloading for functions/constancs don't seem to have enough benefit I agree, autoloading functions for the sake of autoloading functions isn't worth the pain. As you've understood, I mostly don't use functions, so personnaly I'm ok with the current state of PHP on this point. But my proposal isn't restricted solely to solving function autoloading. To sum up my point, it tries to address 3 points : 1. functions and constants autoloading 2. helping static code analyzers 3. cluster functions, constants, classes and interfaces autoloading If you don't care for one point, maybe one of the other two may be enough ? Personally : I don't really care for 1. but I read that others may be interested - I do code analysis so 2. is good - and 3. seems good for performance, because it reduces autoload overhead and helps opcode caches concerning this NOP vs. FETCH_CLASS optimization (thinking about this: http://sb2.info/alternative-php-cache-and-autoload-interoperability/ - not sure for this opcode part - am I wrong ?) So, to get back on the second part of my RFC, taking quotes from Larry Garfield's answer : >> 2. At runtime, when a namespaced identifier is used, take the namespace >> part of the identifier and if any, autoload it as if it were a class > Are you suggesting that: > > use Stuff\Things as Bar; > $foo = new Bar\Baz\Foo() > > should trigger: > autoload('Stuff\Things\Baz\Foo'); > AND > autoload('Stuff\Things\Baz')? Well, yes, but I was thinking about autoloading the namespace before the class. To be more precise, I was thinking about this : >when (_class/interface_ Ns\Foo is need) >{ > // clustered Ns autoloading > autoload('Ns', true) > > // like today > if (class/interface Ns\Foo still not exists) autoload('Ns\Foo', null) > > if (class/interface Ns\Foo still not exists) fatal_error >} >when (_function/constant_ Ns\Foo is need) >{ > // clustered Ns autoloading > autoload('Ns', true) > > if (function/constant Ns\Foo still not exists) fatal_error >} A second parameter to autoload would be need for coders to decide between clustered autoload and regular class. This is necessary to be able to handle nested namespace and clustered autoload recursivity (it being wanted or not wanted by implementations). This led me too this reflexion: this "Ns" then "Ns\Foo" order has one side effect: "Ns\Foo" isn't available while loading "Ns". This may be seen as a BC break because code needing this will get a fatal error. Unlikely is practice ? I don't know. The benefit for autoloading Ns before Ns\Foo is that we give a guarantee to developers: "Ns" is always initialized before any usage of any Ns\Foo. This is the reason I choose this loading order in the first place - and never really though about the reverse order... But this guarantee comes at a price: autoload is now called more often: one more time per namespace. So thinking seriously about the reverse order : autoloading "Ns\Foo" then "Ns". I see it a little bit more complicated, but really interesting, with this algorithm : >// as today: >when (_class/interface_ Ns\Foo is need) >{ > autoload('Ns\Foo', null) > > // clustered Ns autoloading, before today's fatal error > if (class/interface Ns\Foo still not exists) autoload('Ns', true) > > if (class/interface Ns\Foo still not exists) fatal_error >} >when (_function/constant_ Ns\Foo is need) >{ > // clustered Ns autoloading > autoload('Ns', true) > > if (function/constant Ns\Foo still not exists) fatal_error >} This algo doesn't have the previous guarantee but as it plugs before current fatal errors, it is exempt from any BC break, event in term of performance, existing code won't trigger a single more autoload call. Personally, I now prefer this second approach! What about you ? -- Nicolas Grekas http://pa.tchwork.com/ -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php