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