Dear all,

this RFC started by me having a problem on these subjects (not only me
I think) :
- namespaced functions and constants loading, or rather not-autoloading,
- interfaces loading (this time, autoloading).

About namespaced functions and constants, the fact that they are not
autoloaded makes them useless for any code that wants some good
packaging. For example I looked at the Doctrine2 code, and (tell me if
I'm wrong) although it's one of the most recently released high
quality code available today, they don't use a single namespaced
function nor constant. Rather, they use public static methods for
namespaced functions, and class consts for namespaced consts. This
way, they get both "namespaced" and autoloaded features. Impossible to
achieve by using native namespaced functions and consts, no downside.

I also have a second strong grief against namespaced functions and
constants : due to their at runtime namespace resolution, static code
analysis is now very hard, even impossible in the general case! It is
impossible to parse a single PHP file and be sure that a call to
"strlen" is really this "strlen" in the global namespace or an
"strlen" defined in the local namespace, but nobody knows where
without scanning the full project's source code, if that's possible.
Of course, your static code analyser could rely on heuristics which
may work for you, but what about a more generic static code
analyser?!...

So, my first proposal for namespaced functions and constants is :
1. Remove namespaced functions and constants at all - promote
namespaced public static methods and class consts instead.

This would fix static code analysis, and the discussion about how to
autoload (I may say "how to package") namespaced functions and
constants would vanish. About backward compatibility, who as written
code relying on namespaced functions or constants? They are useless!
:) To be more realistic, what about triggering E_DEPRECATED? An other
mitigated solution might be namespace initializers, see below.

Now about interfaces in an autoloading world: used on the web, PHP has
this wonderfully successful "run and forget" execution model. That
means that the autoload machinery is generally triggered on every
single request as needed. But for interfaces, this autoloading model
seams too heavy to me: because their _name_ is what matters most to
keep their promise (think of type hints and "instanceof"), their
definition is generally very short. So, on one side, interfaces really
adds semantics to the code, but on the other side, the most interfaces
you add to your code, the most autoload call you will make, for very
small source files. Because intrinsic performance is important, and
because I can generally find other ways around, I tend to dismiss
interfaces. But what's a shame, on the semantic level of my code! When
I really need interfaces, as a workaround, I break my class/interface
naming convention (PEAR style) and put interfaces definitions in one
single file which I know is loaded before they are needed; but this is
an ad hock hack, nothing more. The same reflexion could be made for
small classes, when their name is their most important feature.

Here comes namespace initializers!

My second proposal is :
2. At runtime, when a namespaced identifier is used (lets say
\my\sub\ns\class_interface_constant_or_function), take the namespace
part of the identifier and if any, autoload it as if it were a class,
do not generate any error if the given class name is not found. (ie,
trigger something like class_exists('my\sub\ns', true);).

Benefits :
- reuses existing autoload packaging code to autoload functions and
constants, namespace by namespace (fixes my first point),
- creates a standard source file were all functions and constants
should be defined (mitigates my second point),
- creates a standard source file were all small (and bigger if wanted)
classes and interfaces definition are stored, so autoload is then
bypassed for them (fixes my third point),
- compatible with existing code base: if class "my\sub\ns" already
exists, it is autoloaded - so what :)

Cons :
- none
- well, one : I don't speak C, so I don"t have any patch...

What do you think about that?

Happy New Year!
--
Nicolas Grekas
http://pa.tchwork.com/

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

Reply via email to