On Fri, 2024-08-23 at 09:16 +0100, Rowan Tommins [IMSoP] wrote:
On 23 August 2024 01:42:38 BST, Nick Lockheart <lists@ageofdream.com>
wrote:
>
> >
> > BUT, if people already complain about "\" being ugly, having to
> > write
> > "namespace\" is going to make them REALLY grumpy...
> > So maybe at the same time (or, probably, in advance) we need to
> > come
> > up with a nicer syntax for explicitly referencing the current
> > namespace.
>
> namespace foo using global functions;
>
> - or -
>
> namespace foo using local functions;
>
>
> Tell PHP what you want at the per-file level.
This doesn't seem mutually exclusive to me. If you have a file where
you've opted for "using global functions", you might want a way to
reference a function in the current namespace.
Correct, so if you use the example:
namespace foo using global functions;
you can write:
array_key_exists();
and it will be resolved as global without a namespace lookup and will
use the dedicated opcode.
But if you need to use a local function you can do:
\foo\sort();
The proposed global/local declaration as part of the namespace
declaration just turns off namespace lookups and sets the default
resolution for **unqualified** names.
Fully qualified names are not affected.
It also doesn't address my other point, that having global as the
default mode (even if we provide an option for local) is much less
disruptive to existing code.
They are compatible, but related decisions.
I think it would be easier for people to accept a new PHP version where
unqualified names were always global, if we also had an option to make
local/namespaced the default resolution for *unqualified* names, on a
per-file basis, for those who need that.
Thus, there are multiple decision points:
1. Should we do namespace lookups on unqualified function calls at all?
2. If yes to 1, should we lookup in global first or local first?
3. Regardless of 1 or 2, should we let developers explicitly specify a
behavior for unqualified calls in the namespace declaration?
4. If yes to 1, should the behavior of namespace lookups change for
user-defined functions vs PHP built-in function names?
These aren't mutually exclusive, but they all work together to create a
complete behavior.
There are several ways that the above options could be combined:
### OPTION ONE ###
Using a regular namespace declaration still does an NS lookup, in the
same order, just like it normally works now.
That means that code that uses:
namespace foo;
will behave exactly the same as today, with no BC breaks.
Developers using the new PHP version could opt-in to explicit namespace
behavior with:
namespace foo using global functions;
or
namespace foo using local functions;
In both cases, *fully-qualified* names still work the same.
Only *unqualified* names are affected by this directive, and they use
local only or global only, depending on the declaration.
### OPTION TWO ###
Namespace lookup is removed from a future version of PHP.
Code that uses the current namespace declaration:
namespace foo;
will assume that all unqualified function calls are global scope.
To use a function in the local namespace, it can be fully qualified
with:
\foo\MyFunction();
But, developers could also write:
namespace foo using local functions;
And all unqualified function names would be resolved to local at
compile time. Global functions could still be accessed with a `\` if
this directive was used:
\array_key_exists();
### OPTION THREE ###
Namespace lookup is removed from a future version of PHP.
Code that uses the current namespace declaration:
namespace foo;
...will assume that an *unqualified* function name is a global function
*IF* it is a PHP built-in function.
Otherwise, *unqualified* function names that are *not* PHP built-in
functions will be presumed to be local to the namespace.
With Option Three, developers can still fully-qualify their functions:
\foo\array_key_exists();
...to override a built-in name with a user function in the current
namespace.
Likewise, a fully-qualified:
\MyFunction();
called from inside a namespace will still call the global function.
Only unqualified names are affected.
As an additional optional feature of Option Three, developers can
change this behavior with:
namespace foo using global functions;
or
namespace foo using local functions;
Only *unqualified* names are affected by this directive, and they use
local only or global only, depending on the namespace declaration.
In both cases, *fully-qualified* names still work the same.
Of course, there are many other possibilities that can be mixed-and-
matched.