> old applications could maintain compatibility only
> by adding a simple autoloader that would alias the global
function/constant
> into the calling namespace

So as a side-effect of calling any function, my namespace would get
polluted with all sorts of random names? That sounds like a messy
work-around.

Okay, so take it back for a moment.

The problem case is this, right?

    namespace Foo;
    bar();

If the function Foo\bar() has not already been loaded, we fall back to
bar() in the global namespace.

With a function-autoloader in place, we would need to trigger this for
every function-call from any namespace, and that's unacceptable.

Okay, well, existing code does not expect function autoloading and wouldn't
benefit from it without changes, right?

So what if, instead of trying to autoload everything by default, we make it
opt-in? Something like:

    namespace Foo;
    use namespace Foo;
    bar();

Now, if function Foo\bar() has not been defined yet, and function \bar()
doesn't exist, then start trying trying to autoload them from used
namespaces.

Okay, that may seem a bit redundant - having to explicitly indicate I'd
like to be able to call functions from within the file's own namespace.

But it'll make more sense if you put your functions in a functions-only
namespace:

    namespace Foo;
    use namespace Foo\Functions;
    bar();

This call would prefer Foo\Functions\bar() if it is able to autoload that,
otherwise will try \bar().

Or if you have several function-namespaces:

    namespace Foo;
    use namespace Click, Clack;
    bar();

This would prefer Click\bar(), then Clack\bar(), if any of those can
autoload, otherwise will try \bar().

Now, this is still a lot of autoload queries, e.g. one for every function
called in every file.

It also doesn't address the issue of autoloading constants.

So.

What if we don't autoload functions at all?

What if we autoload namespaces instead?

That reduces the number of autoload queries from one per function to one
per namespace, which might be more acceptable??

It does mean that individual functions and constants cannot be autoloaded -
the smallest unit that can autoload will be a namespace.

I think that's an okay limitation?

For the most part, packages will likely want to ship a set of functions
(and/or constants) as a single file anyway. If a vendor has too many
functions and don't want the overhead of loading them as a single file,
they likely can/should be organized into several (sub) namespaces anyhow,
so maybe that's acceptable.

So by default, there would be no namespace-autoloading for the file's own
namespace - we don't query the namespace-autoloader by default.

As for use function:

    namespace Foo;
    use function Blip\bar();
    bar();

This would trigger namespace auto-loading for Blip when bar() is invoked.

So existing code with function imports could switch to
namespace-autoloading.

Code that currently uses include/require to load functions into a
file-namespace will need to remove their include/require statements, so
needs changes anyhow to use namespace-autoloading - if this code also needs
an added "use namespace" statement to achieve namespace-autoloading, that's
probably okay?

So yeah, this form of autoloading is a bit inconsistent with the name
resolution rules - but it doesn't require any change as drastic as changing
the function name resolution rules, it's pretty simple, and (I think?)
backwards-compatible.

It could also potentially save you a lot of explicit "use function"
statements, since you can replace ranges of function-imports (from the same
namespace) with a single namespace-import. When new functions are added to
imported namespaces, they would be immediately callable, without needing to
add more imports first.

One drawback or risk of this approach, is of files importing multiple
namespaces, e.g.:

    use Foo, Bar;
    baz();

If you're currently calling Bar\baz() and then a function Foo\baz() is
introduced, unwittingly you would now be calling that.

That's a pretty marginal issue though - function name collisions probably
aren't very likely to happen, especially within the same file.

Thoughts?


On Fri, Jan 27, 2017 at 4:29 PM, Wes <netmo....@gmail.com> wrote:

> Importing functions from a static class would equally require to have all
> functions in the same file. I was proposing an alternative to that, not
> "symbol to file" autoloading.
>
> Though, I know that problem well, sadly. I've suggested PHP should just
> deprecate the fallback to root namespace, and remove the feature altogether
> in PHP8.
>
> Imho it's the only way to actually solve this. Some say it would be a huge
> BC break, but in reality old applications could maintain compatibility only
> by adding a simple autoloader that would alias the global function/constant
> into the calling namespace. Roave wrote this
> https://github.com/Roave/FunctionFQNReplacer , PHPStorm is supporting the
> no-fallback referencing:
> https://youtrack.jetbrains.com/issue/WI-27425 (recently implemented)
> https://youtrack.jetbrains.com/issue/WI-34446 (recently implemented)
> https://youtrack.jetbrains.com/issue/WI-34858
> So... it could be the right time to deprecate the fallback to root
> namespace, before PHP8 gets too close.
>

Reply via email to