On Fri, 2024-08-23 at 09:16 +0100, Rowan Tommins [IMSoP] wrote:
>
>
> On 23 August 2024 01:42:38 BST, Nick Lockheart <[email protected]>
> 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.