[PHP-DEV] [RFC][DISCUSSION] Deprecation of fallback to root scope

  101745
February 3, 2018 08:27 netmo.php@gmail.com (Wes)
Hello PHPeople. I just published the RFC "Deprecation of fallback to root
scope".

It is quite a substantial change, but as you can read in the RFC, can be a
(basically) transparent one.
I'm referring to the possibility to shim it in userland. Essentially, this
would move the feature from core to userland.

I hope you like it. Let me know what you think.

https://wiki.php.net/rfc/fallback-to-root-scope-deprecation
  101746
February 3, 2018 08:32 ocramius@gmail.com (Marco Pivetta)
Overall, huge improvement, and also simplifies things quite a lot from a
developer PoV by requiring to add explicit references, so this is 100%
thumbs up.

Marco Pivetta

http://twitter.com/Ocramius

http://ocramius.github.com/

On Sat, Feb 3, 2018 at 9:27 AM, Wes php@gmail.com> wrote:

> Hello PHPeople. I just published the RFC "Deprecation of fallback to root > scope". > > It is quite a substantial change, but as you can read in the RFC, can be a > (basically) transparent one. > I'm referring to the possibility to shim it in userland. Essentially, this > would move the feature from core to userland. > > I hope you like it. Let me know what you think. > > https://wiki.php.net/rfc/fallback-to-root-scope-deprecation >
  101749
February 3, 2018 10:15 me@kelunik.com (Niklas Keller)
+1

Why should it emit an E_NOTICE instead of E_DEPRECATED?

The code for the shim should probably use define() for constants instead of
eval().

Regards, Niklas
  101750
February 3, 2018 10:22 netmo.php@gmail.com (Wes)
No idea, I'm not really sure what's the difference between E_STRICT and
E_DEPRECATED.
Yeah the shim is just a rough POC (completely forgot that define() can
define in namespaces).
Nicolas Grekas on twitter also suggested that we should introduce
function_alias() that works like class_alias().
With that the shim would be literally a couple of lines long.
  101753
February 3, 2018 16:31 levim@php.net (Levi Morrison)
On Sat, Feb 3, 2018 at 3:22 AM, Wes php@gmail.com> wrote:
> No idea, I'm not really sure what's the difference between E_STRICT and > E_DEPRECATED. > Yeah the shim is just a rough POC (completely forgot that define() can > define in namespaces). > Nicolas Grekas on twitter also suggested that we should introduce > function_alias() that works like class_alias(). > With that the shim would be literally a couple of lines long.
From our manual:
> E_NOTICE : Run-time notices. Indicate that the script encountered something that could indicate an error, but could also happen in the normal course of running a script. > E_DEPRECATED: Run-time notices. Enable this to receive warnings about code that will not work in future versions. > E_STRICT: Enable to have PHP suggest changes to your code which will ensure the best interoperability and forward compatibility of your code.
In my opinion we should emit E_STRICT until we know when the feature will be removed. At that point we can promote it to E_DEPRECATED and specifically cite when it will be removed. In any case, E_NOTICE does not seem appropriate.
  101756
February 3, 2018 17:04 pollita@php.net (Sara Golemon)
On Sat, Feb 3, 2018 at 11:31 AM, Levi Morrison <levim@php.net> wrote:
> In my opinion we should emit E_STRICT until we know when the feature > will be removed. At that point we can promote it to E_DEPRECATED and > specifically cite when it will be removed. In any case, E_NOTICE does > not seem appropriate. > I like the three phase approach. Gives frameworks/libraries/users
ridiculous amounts of time to clean up their code, the route to clean code is clear and the updates are scriptable (I'll bet PHPCS can do this already), and at the end, we'll be able to have a better engine and make certain assumptions in the optimizer. +1 -Sara
  101757
February 3, 2018 17:12 aaron@trowski.com (Aaron Piotrowski)
> On Feb 3, 2018, at 11:04 AM, Sara Golemon <pollita@php.net> wrote: >> > I like the three phase approach. Gives frameworks/libraries/users > ridiculous amounts of time to clean up their code, the route to clean > code is clear and the updates are scriptable (I'll bet PHPCS can do > this already), and at the end, we'll be able to have a better engine > and make certain assumptions in the optimizer.
Yep, PHP-CS-Fixer can do this, see the native_function_invocation option. I also like the three phase approach and would be excited to see the possibility for function autoloading and further optimizations. +1 Aaron Piotrowski
  101758
February 4, 2018 08:50 netmo.php@gmail.com (Wes)
I just want to add: vote is not very obvious - non internals people are
getting too excited about this :P Please consider:

People that don't have an IDE that handles the imports automatically, will
be effectively forced to prefix \ to everything, which is really ugly.

But again, prefixing \ is not even the end of the world. I bet that if
fallback to global scope didn't exist from the beginning, we wouldn't care
anymore about prefixing \.

PHP has tons of global symbols, it's not like other languages that have
functions organized in classes.
Doing the most basic array and string operations will easily  require 4-5
imports, probably more. If all I had to do was `use String;` and all the
string functions were available as methods on strings, then it would be
completely fine.

On the other hand, string functions are rarely used, and arrays can be
replaced by oop collections like spl, ds, or even userland ones.

Function autoloading is almost a development feature only, since in a few
years we'll all likely use opcache, which doesn't need autoloading.
  101754
February 3, 2018 16:46 marcio.web2@gmail.com (Marcio Almada)
2018-02-03 6:27 GMT-02:00 Wes php@gmail.com>:

> Hello PHPeople. I just published the RFC "Deprecation of fallback to root > scope". > > It is quite a substantial change, but as you can read in the RFC, can be a > (basically) transparent one. > I'm referring to the possibility to shim it in userland. Essentially, this > would move the feature from core to userland. > > I hope you like it. Let me know what you think. > > https://wiki.php.net/rfc/fallback-to-root-scope-deprecation > > > Personally, I'm a +1 on this. I just can't see a 3/2 majority voting yes on
this proposal. But the odds could be a little better with a "batteries included" RFC offering a tool to automatically update code by adding the necessary use statements for core functions, constants, and classes. Good luck, Márcio Almada https://github.com/marcioAlmada
  101755
February 3, 2018 16:59 marcio.web2@gmail.com (Marcio Almada)
2018-02-03 14:46 GMT-02:00 Marcio Almada web2@gmail.com>:

> > 2018-02-03 6:27 GMT-02:00 Wes php@gmail.com>: > >> Hello PHPeople. I just published the RFC "Deprecation of fallback to root >> scope". >> >> It is quite a substantial change, but as you can read in the RFC, can be a >> (basically) transparent one. >> I'm referring to the possibility to shim it in userland. Essentially, this >> would move the feature from core to userland. >> >> I hope you like it. Let me know what you think. >> >> https://wiki.php.net/rfc/fallback-to-root-scope-deprecation >> >> >> > Personally, I'm a +1 on this. I just can't see a 3/2 majority voting yes > on this proposal. But the odds could be a little better with > a "batteries included" RFC offering a tool to automatically update code by > adding the necessary use statements for core functions, > constants, and classes. > > Good luck, > Márcio Almada > > https://github.com/marcioAlmada > > Heh, I meant 2/3 of course :x
  101759
February 4, 2018 09:07 smalyshev@gmail.com (Stanislav Malyshev)
Hi!

> I hope you like it. Let me know what you think. > > https://wiki.php.net/rfc/fallback-to-root-scope-deprecation
I do not see how this makes sense. This RFC claims there's no BC breakage, while it deprecates one of the most widely used functions of the language (using unqualified global functions from inside namespaces) and adds warnings which will break a lot of existing code (and yes, notice and warning are basically the same). I do not see how it makes sense to force people to use \strlen everywhere (since most of the code in large apps uses namespaces now) for a tiny and rare possibility that someone would override strlen. Unless I serously misunderstand what this RFC is proposing, I am absolutely against it and think doing something like this would be harmful to PHP. Am I missing something here? -- Stas Malyshev smalyshev@gmail.com
  101761
February 4, 2018 14:03 rowan.collins@gmail.com (Rowan Collins)
On 3 February 2018 08:27:18 GMT+00:00, Wes php@gmail.com> wrote:
>Hello PHPeople. I just published the RFC "Deprecation of fallback to >root >scope". > >It is quite a substantial change, but as you can read in the RFC, can >be a >(basically) transparent one. >I'm referring to the possibility to shim it in userland.
I'm torn on this one. On the one hand, I think in hindsight this is how functions in namespaces should have worked when they were introduced in PHP 6, I mean 5.3. \foo isn't the prettiest syntax, but people soon got used to writing class names that way, including built in ones like \DateTime. It would make function autoloading simpler, lead to less ambiguous code, and make namespaces work consistently across token types, rather than one way for classes and a different way for functions and constants. On the other hand, the BC break of moving to that now (or committing ourselves to in the future) is significant, and even raising a notice of whatever level could be highly disruptive. A lot of code bases will issue this message hundreds or thousands of times; I wouldn't be surprised if just the code to format the string and pass it to an active error handler might result in a measurable performance impact in some cases. Crucially, the proposed shim can't actually be written yet, so the only way to suppress these notices will be to edit every single source file, which even if perfectly automated creates a lot of noise in version control. I think some less invasive way would need to be found to make existing code run the same way, without notices, before and after the change. For instance, if you could opt into the old behaviour by writing "import global functions" at the top of a file, or opt into the new behaviour by writing "namespace only Foo", or since autoloading is a key benefit, "namespace Foo with autoload". It wouldn't be ideal, because it means the engine has to support both modes, but it would be far less painful than adding \ into thousands of lines of existing code. Regards, -- Rowan Collins [IMSoP]
  101762
February 4, 2018 21:00 kontakt@beberlei.de (Benjamin Eberlei)
On Sat, Feb 3, 2018 at 9:27 AM, Wes php@gmail.com> wrote:

> Hello PHPeople. I just published the RFC "Deprecation of fallback to root > scope". > > It is quite a substantial change, but as you can read in the RFC, can be a > (basically) transparent one. > I'm referring to the possibility to shim it in userland. Essentially, this > would move the feature from core to userland. > > I hope you like it. Let me know what you think. > > https://wiki.php.net/rfc/fallback-to-root-scope-deprecation
To get the same benefits (jit and such) wouldn't it be better to introduce a "use function root;" or similar statement or a declare() to specify this file imports all root functions? I am with stas that this will go towards a huge BC break if the deprecation was acted on at any time in the future. and in addition people will silence the notices on global error reporting level, because violations would happen on a massive scale, inclusing the cost of them being raised dragging performance down. This will be a problem since other notices will go unnoticed.
  101763
February 4, 2018 21:56 smalyshev@gmail.com (Stanislav Malyshev)
Hi!

> To get the same benefits (jit and such) wouldn't it be better to introduce > a "use function root;" or similar statement or a declare() to specify this > file imports all root functions?
We already have this right now, and realistically speaking, who wouldn't do that in their code instead of writing weird \strlen() code? Everybody would configure their IDEs and so to insert this automatically. So we're talking about RFC to make people work harder for what they already have now and then end up in the same place we are already right now.
> was acted on at any time in the future. and in addition people will silence > the notices on global error reporting level, because violations would
And note also that we can't silence just this warning. Which means people would have to silence *all* warnings, thus making all other messages useless. This is not a good development and this is not what we should be training users to do - saying "well, it's a warning, just silence it" is the worth idea we could have. If we create a warning, recommendation should be "it's important enough so we call your attention to it, please deal with it", not "just silence it". If it's OK in most cases (as opposed to rare exceptional cases) for it to be silenced, it shouldn't be there in the first place. -- Stas Malyshev smalyshev@gmail.com
  101764
February 4, 2018 22:43 levim@php.net (Levi Morrison)
On Sun, Feb 4, 2018 at 2:56 PM, Stanislav Malyshev <smalyshev@gmail.com> wrote:
> Hi! > >> To get the same benefits (jit and such) wouldn't it be better to introduce >> a "use function root;" or similar statement or a declare() to specify this >> file imports all root functions? > > We already have this right now, and realistically speaking, who wouldn't > do that in their code instead of writing weird \strlen() code? Everybody > would configure their IDEs and so to insert this automatically. So we're > talking about RFC to make people work harder for what they already have > now and then end up in the same place we are already right now.
I agree with Stas that this "use function root;" or whatever is pointless.
>> was acted on at any time in the future. and in addition people will silence >> the notices on global error reporting level, because violations would > > And note also that we can't silence just this warning. Which means > people would have to silence *all* warnings, thus making all other > messages useless. This is not a good development and this is not what we > should be training users to do - saying "well, it's a warning, just > silence it" is the worth idea we could have. If we create a warning, > recommendation should be "it's important enough so we call your > attention to it, please deal with it", not "just silence it". If it's OK > in most cases (as opposed to rare exceptional cases) for it to be > silenced, it shouldn't be there in the first place.
We have nearly zero E_STRICT warnings right now. Simply configure your error reporting level to omit E_STRICT if you don't want them. You are blowing this out of proportion.
  101772
February 5, 2018 14:09 cmbecker69@gmx.de ("Christoph M. Becker")
On 04.02.2018 at 22:56, Stanislav Malyshev wrote:

>> To get the same benefits (jit and such) wouldn't it be better to introduce >> a "use function root;" or similar statement or a declare() to specify this >> file imports all root functions? > > We already have this right now, […]
Do we? AFAIK, it is not possible to import *all* functions (or even all symbols, for that matter) of a namespace, without explicitly mentioning them. -- Christoph M. Becker
  101773
February 5, 2018 14:28 tendoaki@gmail.com (Michael Morris)
May I propose a compromise?

If I understand what I've read over, the default of functions and constants
to global scope is the primary blocking issue for creating an autoloader
for these elements. Where that not PHP's behavior this functionality could
have been implemented by now.

The problem is that behavior has been around so long that any attempt to
change it would incur a massive amount of changes. Using the E_STRICT
notice level instead of E_DEPRECATED has been floated as one fix for this,
but this doesn't change the fact that major applications and frameworks,
such as Drupal, pride themselves in being able to pass all tests even with
E_STRICT enabled. The maintainers of these projects would be annoyed to say
the least to need to fix thousands of lines of code to get back to that
point, and downstream projects such as Drupal could end up waiting years
for all their upstream libraries to get their act together.

Since the two issues are somewhat tied, why not bind them to a
configuration flag following the pattern that was used to ultimately remove
register_globals functionality from the language?  At this point let it be
known that when constant/function overloaders hit a php.ini config option
will be added to turn them on -- and turning them on will turn global
scoping for functions off.

This solution isn't perfect.  From where Drupal stands, even if all it's
own code stopped using global functions the packages it relies on likely
will continue to do so for some time. Even if they don't, there may be
compatibility issues with the newer version.

A slightly better solution would be to allow this to be set on a per
namespace basis, but as PHP has no true notion of a namespace I don't think
this can be implemented.  The declare() statement might allow it to be done
on a per file basis, but that's going to get messy fast.

Still, I feel it is a workable approach despite the drawbacks.  If anything
this problem highlights another problem elsewhere in PHP - the inability to
isolate package configuration, or configure packages at all.  But that's a
topic for another RFC, one I won't be starting cause I have no idea how to
fix it.

On Mon, Feb 5, 2018 at 8:09 AM, Christoph M. Becker <cmbecker69@gmx.de>
wrote:

> On 04.02.2018 at 22:56, Stanislav Malyshev wrote: > > >> To get the same benefits (jit and such) wouldn't it be better to > introduce > >> a "use function root;" or similar statement or a declare() to specify > this > >> file imports all root functions? > > > > We already have this right now, […] > > Do we? AFAIK, it is not possible to import *all* functions (or even all > symbols, for that matter) of a namespace, without explicitly mentioning > them. > > -- > Christoph M. Becker > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > >
  101774
February 5, 2018 14:33 ocramius@gmail.com (Marco Pivetta)
On Mon, Feb 5, 2018 at 3:28 PM, Michael Morris <tendoaki@gmail.com> wrote:

> The problem is that behavior has been around so long that any attempt to > change it would incur a massive amount of changes. Using the E_STRICT > notice level instead of E_DEPRECATED has been floated as one fix for this, > but this doesn't change the fact that major applications and frameworks, > such as Drupal, pride themselves in being able to pass all tests even with > E_STRICT enabled. The maintainers of these projects would be annoyed to say > the least to need to fix thousands of lines of code to get back to that > point, and downstream projects such as Drupal could end up waiting years > for all their upstream libraries to get their act together. >
Much like any upgrade requiring patches for full compliance with newer PHP versions, it needs work. The typical workflow is: * add PHP.NEXT to the CI setup * run everything through the tests again, figure out how much has broken * fix it In this case, we even *already* have *multiple* tools that automatically fix this problem in one shot. Since the two issues are somewhat tied, why not bind them to a
> configuration flag following the pattern that was used to ultimately remove > register_globals functionality from the language? At this point let it be > known that when constant/function overloaders hit a php.ini config option > will be added to turn them on -- and turning them on will turn global > scoping for functions off. >
Argh Marco Pivetta http://twitter.com/Ocramius http://ocramius.github.com/
  101775
February 5, 2018 14:39 tendoaki@gmail.com (Michael Morris)
On Mon, Feb 5, 2018 at 8:33 AM, Marco Pivetta <ocramius@gmail.com> wrote:

> > On Mon, Feb 5, 2018 at 3:28 PM, Michael Morris <tendoaki@gmail.com> wrote: > >> The problem is that behavior has been around so long that any attempt to >> change it would incur a massive amount of changes. Using the E_STRICT >> notice level instead of E_DEPRECATED has been floated as one fix for this, >> but this doesn't change the fact that major applications and frameworks, >> such as Drupal, pride themselves in being able to pass all tests even with >> E_STRICT enabled. The maintainers of these projects would be annoyed to >> say >> the least to need to fix thousands of lines of code to get back to that >> point, and downstream projects such as Drupal could end up waiting years >> for all their upstream libraries to get their act together. >> > > Much like any upgrade requiring patches for full compliance with newer > PHP versions, it needs work. > > The typical workflow is: > > * add PHP.NEXT to the CI setup > * run everything through the tests again, figure out how much has broken > * fix it > > In this case, we even *already* have *multiple* tools that automatically > fix this problem in one shot. > > Since the two issues are somewhat tied, why not bind them to a >> configuration flag following the pattern that was used to ultimately >> remove >> register_globals functionality from the language? At this point let it be >> known that when constant/function overloaders hit a php.ini config option >> will be added to turn them on -- and turning them on will turn global >> scoping for functions off. >> > > Argh > > Agreed, but you can't just pull the rug out from under people. It's
painful, but it's better to let people opt in to such a major change than to "break" their code.
  101776
February 5, 2018 14:43 ocramius@gmail.com (Marco Pivetta)
On Mon, Feb 5, 2018 at 3:39 PM, Michael Morris <tendoaki@gmail.com> wrote:

> > > On Mon, Feb 5, 2018 at 8:33 AM, Marco Pivetta <ocramius@gmail.com> wrote: > >> >> On Mon, Feb 5, 2018 at 3:28 PM, Michael Morris <tendoaki@gmail.com> >> wrote: >> >>> The problem is that behavior has been around so long that any attempt to >>> change it would incur a massive amount of changes. Using the E_STRICT >>> notice level instead of E_DEPRECATED has been floated as one fix for >>> this, >>> but this doesn't change the fact that major applications and frameworks, >>> such as Drupal, pride themselves in being able to pass all tests even >>> with >>> E_STRICT enabled. The maintainers of these projects would be annoyed to >>> say >>> the least to need to fix thousands of lines of code to get back to that >>> point, and downstream projects such as Drupal could end up waiting years >>> for all their upstream libraries to get their act together. >>> >> >> Much like any upgrade requiring patches for full compliance with newer >> PHP versions, it needs work. >> >> The typical workflow is: >> >> * add PHP.NEXT to the CI setup >> * run everything through the tests again, figure out how much has broken >> * fix it >> >> In this case, we even *already* have *multiple* tools that automatically >> fix this problem in one shot. >> >> Since the two issues are somewhat tied, why not bind them to a >>> configuration flag following the pattern that was used to ultimately >>> remove >>> register_globals functionality from the language? At this point let it >>> be >>> known that when constant/function overloaders hit a php.ini config option >>> will be added to turn them on -- and turning them on will turn global >>> scoping for functions off. >>> >> >> Argh >> >> > Agreed, but you can't just pull the rug out from under people. It's > painful, but it's better to let people opt in to such a major change than > to "break" their code. >
We're talking about a deprecation, not removal of a feature. First of all, it doesn't remove the feature, which means that everything keeps working as-is, and second, we already have a way to configure error reporting for deprecations ("configuration") ;-) The point of deprecations is precisely to give downstream time to adjust and release the adapted code, which we do all the time anyway. Marco Pivetta http://twitter.com/Ocramius http://ocramius.github.com/
  101791
February 6, 2018 19:35 smalyshev@gmail.com (Stanislav Malyshev)
Hi!

> We're talking about a deprecation, not removal of a feature.
There's no point of deprecating if the goal isn't to remove.
> First of all, it doesn't remove the feature, which means that everything > keeps working as-is, and second, we already have a way to configure error > reporting for deprecations ("configuration") ;-)
Configuration removes deprecation messages as a whole class, which is usually not what you want.
> The point of deprecations is precisely to give downstream time to adjust > and release the adapted code, which we do all the time anyway.
In this case, this would mean "edit every file (that uses standard PHP functions, which is probably nearly every file in the codebase)", to no benefit to the user. This is a huge imposition on existing users without any benefit to them. The fact that they will have time is irrelevant - they always would have all the time in the world but not upgrading - the point is that this change is bad for them. -- Stas Malyshev smalyshev@gmail.com
  101790
February 6, 2018 19:31 smalyshev@gmail.com (Stanislav Malyshev)
Hi!

>>> To get the same benefits (jit and such) wouldn't it be better to introduce >>> a "use function root;" or similar statement or a declare() to specify this >>> file imports all root functions? >> >> We already have this right now, […] > > Do we? AFAIK, it is not possible to import *all* functions (or even all > symbols, for that matter) of a namespace, without explicitly mentioning > them.
We are talking about global namespace aka standard PHP functions, so it works out of the box. If you're talking about non-global namespace, there's no such thing as "all functions of a namespace" at all, and even if there were, in most cases it's the wrong thing (excepting some rare cases like you want to override all PHP function for testing, etc.) to do. Namespaces are meant to keep things separate, so blanket imports just put us back into a pre-namespace world with all the problems that existed there. Granted, there are rare cases - as overriding whole extension or whole standard library - but they are rare. In overwhelming majority of cases, this is not what should be done and if you do it, you usually get in trouble. -- Stas Malyshev smalyshev@gmail.com
  101805
February 7, 2018 17:42 cmbecker69@gmx.de ("Christoph M. Becker")
On 06.02.2018 at 20:31, Stanislav Malyshev wrote:

>> Do we? AFAIK, it is not possible to import *all* functions (or even all >> symbols, for that matter) of a namespace, without explicitly mentioning >> them. > > We are talking about global namespace aka standard PHP functions, so it > works out of the box. […]
Ah, I see. :) -- Christoph M. Becker
  101857
February 13, 2018 12:18 ua.san.alex@gmail.com ("S.A.N")
If you implement scalar objects:
https://github.com/nikic/scalar_objects

Then 80% of global functions (array_*, str_*) will be localized using
scalar object methods ($array->split(), $string->join()) and the PHP
developer's response will be positive.

Thanks.
  101778
February 5, 2018 16:54 kontakt@beberlei.de (Benjamin Eberlei)
On Sun, Feb 4, 2018 at 10:56 PM, Stanislav Malyshev <smalyshev@gmail.com>
wrote:

> Hi! > > > To get the same benefits (jit and such) wouldn't it be better to > introduce > > a "use function root;" or similar statement or a declare() to specify > this > > file imports all root functions? > > We already have this right now, and realistically speaking, who wouldn't > do that in their code instead of writing weird \strlen() code? Everybody > would configure their IDEs and so to insert this automatically. So we're > talking about RFC to make people work harder for what they already have > now and then end up in the same place we are already right now. >
Yes we do have root namespace lookup, but its not automatic, it is only as a fallback. This RFC is about removing the intermediate namespace'd check, hence requiring \strlen. My idea was to force all function lookups into the global nameespace first by doing the declare or use. This way someone writing a file could state "i dont use namespaced functions in this file, don't try to load them". I agree its annoying and more work, just wanted to present it as an alternative option.
> > > was acted on at any time in the future. and in addition people will > silence > > the notices on global error reporting level, because violations would > > And note also that we can't silence just this warning. Which means > people would have to silence *all* warnings, thus making all other > messages useless. This is not a good development and this is not what we > should be training users to do - saying "well, it's a warning, just > silence it" is the worth idea we could have. If we create a warning, > recommendation should be "it's important enough so we call your > attention to it, please deal with it", not "just silence it". If it's OK > in most cases (as opposed to rare exceptional cases) for it to be > silenced, it shouldn't be there in the first place. >
Yes, this is why I have a problem with using E_STRICT (we don't have a lot of them at the moment, but maybe in preparation of 8 more?) warning for it. It would send a wrong signal to ignore rather than fix, because the amount of violations would be massive.
> > -- > Stas Malyshev > smalyshev@gmail.com >
  101779
February 6, 2018 01:51 levim@php.net (Levi Morrison)
On Mon, Feb 5, 2018 at 9:54 AM, Benjamin Eberlei <kontakt@beberlei.de> wrote:
> On Sun, Feb 4, 2018 at 10:56 PM, Stanislav Malyshev <smalyshev@gmail.com> > wrote: > >> Hi! >> >> > To get the same benefits (jit and such) wouldn't it be better to >> introduce >> > a "use function root;" or similar statement or a declare() to specify >> this >> > file imports all root functions? >> >> We already have this right now, and realistically speaking, who wouldn't >> do that in their code instead of writing weird \strlen() code? Everybody >> would configure their IDEs and so to insert this automatically. So we're >> talking about RFC to make people work harder for what they already have >> now and then end up in the same place we are already right now. >> > > Yes we do have root namespace lookup, but its not automatic, it is only as > a fallback. This RFC is about removing the intermediate namespace'd check, > hence requiring \strlen. > > My idea was to force all function lookups into the global nameespace first > by doing the declare or use. This way someone writing a file could state "i > dont use namespaced functions in this file, don't try to load them". > > I agree its annoying and more work, just wanted to present it as an > alternative option. > > >> >> > was acted on at any time in the future. and in addition people will >> silence >> > the notices on global error reporting level, because violations would >> >> And note also that we can't silence just this warning. Which means >> people would have to silence *all* warnings, thus making all other >> messages useless. This is not a good development and this is not what we >> should be training users to do - saying "well, it's a warning, just >> silence it" is the worth idea we could have. If we create a warning, >> recommendation should be "it's important enough so we call your >> attention to it, please deal with it", not "just silence it". If it's OK >> in most cases (as opposed to rare exceptional cases) for it to be >> silenced, it shouldn't be there in the first place. >> > > Yes, this is why I have a problem with using E_STRICT (we don't have a lot > of them at the moment, but maybe in preparation of 8 more?) warning for it. > It would send a wrong signal to ignore rather than fix, because the amount > of violations would be massive.
It's fine to ignore them as long as they fix them later. That's precisely why I think E_STRICT is a good category for these notices. If, however, they ignore them forever that's their fault; we are simply providing advanced notice of a behavior we'd like to eventually change. Let me put "eventually" into perspective. We will probably have a 7.3 before we have an 8.0. This means that 8.0, the absolute earliest version we could remove this feature, is at least 2 years away before it reaches *any* of our users. Unless we extend it like we did with the last 5.X release (and I think we probably should extend it) this means that users can run their existing code on an officially supported PHP 7 release for the next 4 years at the minimum. I am fairly confident that for one reason or another it will delay another year or two, putting it at 5-6 years. If we are uncomfortable removing this feature in PHP 8.0 that means support would extend until the end of the last PHP 8 release. My best guess is that is at least 5 more years but probably more. That puts us in the 10-12 years timeframe. If we cannot fix such an issue *over an entire decade* then we may as well call PHP 7 the last major release. And let me be clear: I would like there to be a PHP 8 and a PHP 9. I think most of our users would like that as well. This means we have breaking to do over the next decade. The responsible thing is to give users this information as early as possible.
  101780
February 6, 2018 10:08 rowan.collins@gmail.com (Rowan Collins)
On 6 February 2018 at 01:51, Levi Morrison <levim@php.net> wrote:

> It's fine to ignore them as long as they fix them later. That's > precisely why I think E_STRICT is a good category for these notices. > If, however, they ignore them forever that's their fault; we are > simply providing advanced notice of a behavior we'd like to eventually > change. > > Let me put "eventually" into perspective. We will probably have a 7.3 > before we have an 8.0. This means that 8.0, the absolute earliest > version we could remove this feature, is at least 2 years away before > it reaches *any* of our users. Unless we extend it like we did with > the last 5.X release (and I think we probably should extend it) this > means that users can run their existing code on an officially > supported PHP 7 release for the next 4 years at the minimum. I am > fairly confident that for one reason or another it will delay another > year or two, putting it at 5-6 years. >
I think for a lot of people the "forever" in your first paragraph and the "5-6 years" in your second paragraph will feel like the same thing. If the message is "this might be removed some time in the next decade", people will simply shrug and ignore it until an actual removal is announced; thinking as a cynical user, there's no guarantee the recommendation won't be changed back in future - we've had features "undeprecated" before. As others have pointed out, even if you run an analyser over your own code base to add \ in the appropriate places, you can't turn on E_STRICT notices without being flooded until all your dependencies have done the same - and there's no compelling reason for them to do so. That's why I think having some concrete benefit much sooner is the only way to stop people resenting this change. Build function autoloading in a way that it only works if you opt out of the fallback, and *then* deprecate the fallback mode, and it feels like progress rather than disruptive tinkering. Regards, -- Rowan Collins [IMSoP]
  101781
February 6, 2018 14:36 levim@php.net (Levi Morrison)
On Tue, Feb 6, 2018 at 3:08 AM, Rowan Collins collins@gmail.com> wrote:
> On 6 February 2018 at 01:51, Levi Morrison <levim@php.net> wrote: > >> It's fine to ignore them as long as they fix them later. That's >> precisely why I think E_STRICT is a good category for these notices. >> If, however, they ignore them forever that's their fault; we are >> simply providing advanced notice of a behavior we'd like to eventually >> change. >> >> Let me put "eventually" into perspective. We will probably have a 7.3 >> before we have an 8.0. This means that 8.0, the absolute earliest >> version we could remove this feature, is at least 2 years away before >> it reaches *any* of our users. Unless we extend it like we did with >> the last 5.X release (and I think we probably should extend it) this >> means that users can run their existing code on an officially >> supported PHP 7 release for the next 4 years at the minimum. I am >> fairly confident that for one reason or another it will delay another >> year or two, putting it at 5-6 years. >> > > > I think for a lot of people the "forever" in your first paragraph and the > "5-6 years" in your second paragraph will feel like the same thing. If the > message is "this might be removed some time in the next decade", people > will simply shrug and ignore it until an actual removal is announced; > thinking as a cynical user, there's no guarantee the recommendation won't > be changed back in future - we've had features "undeprecated" before. > > As others have pointed out, even if you run an analyser over your own code > base to add \ in the appropriate places, you can't turn on E_STRICT notices > without being flooded until all your dependencies have done the same - and > there's no compelling reason for them to do so. > > That's why I think having some concrete benefit much sooner is the only way > to stop people resenting this change. Build function autoloading in a way > that it only works if you opt out of the fallback, and *then* deprecate the > fallback mode, and it feels like progress rather than disruptive tinkering.
This thinking is too pessimistic. We cannot design to appease our worst users. The advanced notice is better than a sudden one even if we have function autoloading.
  101784
February 6, 2018 15:49 rowan.collins@gmail.com (Rowan Collins)
On 6 February 2018 at 14:36, Levi Morrison <levim@php.net> wrote:

> > That's why I think having some concrete benefit much sooner is the only > way > > to stop people resenting this change. Build function autoloading in a way > > that it only works if you opt out of the fallback, and *then* deprecate > the > > fallback mode, and it feels like progress rather than disruptive > tinkering. > > This thinking is too pessimistic. We cannot design to appease our > worst users. The advanced notice is better than a sudden one even if > we have function autoloading. >
Perhaps I wasn't clear; I'm not saying the transition should be more sudden, I'm just saying that we should introduce an opt-in advantage alongside the flood of messages. As I understand it, the timeline you support is: * Raise E_STRICT in PHP 7.3. * Once we have a plan to actually change the behaviour, move to E_DEPRECATED, e.g. in PHP 7.5, or 8.0. * Remove fallback at the same time as introducing autoloading, in PHP 8.0 or maybe 9.0. The timeline I am suggesting is: * Add an opt-in feature which enables some advantage, probably autoloading, as soon as possible, e.g. PHP 7.3 or 7.4 * Raise E_DEPRECATED for code which doesn't opt in and doesn't fully-qualify function names, once usage is established, e.g. PHP 7.5, or 8.0 * Remove the fallback mode as a purely internal change, in PHP 8.0 or 9.0. People would still be changing code on much the same timeline, but we wouldn't have the long period of telling people to change all their code without any benefit to them or us. I also think it's a stretch to call people affected by this change "our worst users". I don't know if any common coding standards cover leading backslashes (I searched the PSR-12 draft and Drupal style guide and neither seems to mention it) but if they do, they're as likely to say "never add them" as "always add them", particularly given their use as a hack to "mock" global functions. Or perhaps by "worst users" you mean "users not willing to change their code" - in which case remember that this is a disruptive and risky change to an entire code base for no immediate benefit; putting off such a change might be a perfectly rational decision. Regards, -- Rowan Collins [IMSoP]
  101788
February 6, 2018 19:23 smalyshev@gmail.com (Stanislav Malyshev)
Hi!

> I also think it's a stretch to call people affected by this change "our > worst users". I don't know if any common coding standards cover leading
I think you can call them just "our users". I haven't seen any code that does \strlen or \substr all over the code base. In my opinion, requiring this would be a huge annoyance to our users and make no sense at all. -- Stas Malyshev smalyshev@gmail.com
  101782
February 6, 2018 15:24 larry@garfieldtech.com (Larry Garfield)
On Tuesday, February 6, 2018 4:08:03 AM CST Rowan Collins wrote:
> On 6 February 2018 at 01:51, Levi Morrison <levim@php.net> wrote: > > It's fine to ignore them as long as they fix them later. That's > > precisely why I think E_STRICT is a good category for these notices. > > If, however, they ignore them forever that's their fault; we are > > simply providing advanced notice of a behavior we'd like to eventually > > change. > > > > Let me put "eventually" into perspective. We will probably have a 7.3 > > before we have an 8.0. This means that 8.0, the absolute earliest > > version we could remove this feature, is at least 2 years away before > > it reaches *any* of our users. Unless we extend it like we did with > > the last 5.X release (and I think we probably should extend it) this > > means that users can run their existing code on an officially > > supported PHP 7 release for the next 4 years at the minimum. I am > > fairly confident that for one reason or another it will delay another > > year or two, putting it at 5-6 years. > > I think for a lot of people the "forever" in your first paragraph and the > "5-6 years" in your second paragraph will feel like the same thing. If the > message is "this might be removed some time in the next decade", people > will simply shrug and ignore it until an actual removal is announced; > thinking as a cynical user, there's no guarantee the recommendation won't > be changed back in future - we've had features "undeprecated" before. > > As others have pointed out, even if you run an analyser over your own code > base to add \ in the appropriate places, you can't turn on E_STRICT notices > without being flooded until all your dependencies have done the same - and > there's no compelling reason for them to do so. > > That's why I think having some concrete benefit much sooner is the only way > to stop people resenting this change. Build function autoloading in a way > that it only works if you opt out of the fallback, and *then* deprecate the > fallback mode, and it feels like progress rather than disruptive tinkering. > > Regards,
Potential benefits of this change aside, I have to agree with Rowan on tactics. A carrot works much better than a stick in this case. Remember also that many larger systems stay around and in production WAAAAAAAAAAAAY past their expected lifetimes; there are still poor souls running PHP 4, and I personally know of Drupal 5 sites still in the wild. So even if the HEAD version of everything is updated within a year for such a change the long tail of what's running out in the world will lag badly. That said, I'm not sure that function autoloading will be that big of a carrot for the major projects at this point. Wordpress is going to ignore anything we do here anyway for at least 15 years, and pretty much every other project in existence has gone all-OOP or nearly-all-OOP at this point (good or bad is beside the point). Namespaced user defined functions are rare in my experience outside of very specific libraries (such as functional tooling libs). So "yay, you can now autoload namespaced user-defined functions" will likely be met with a lot of "what are those?" --Larry Garfield
  101783
February 6, 2018 15:44 derokorian@gmail.com (Ryan Pallas)
On Tue, Feb 6, 2018 at 8:24 AM, Larry Garfield <larry@garfieldtech.com>
wrote:
> > > That said, I'm not sure that function autoloading will be that big of a > carrot > for the major projects at this point. Wordpress is going to ignore > anything > we do here anyway for at least 15 years, and pretty much every other > project > in existence has gone all-OOP or nearly-all-OOP at this point (good or bad > is > beside the point). Namespaced user defined functions are rare in my > experience > outside of very specific libraries (such as functional tooling libs). So > "yay, > you can now autoload namespaced user-defined functions" will likely be met > with > a lot of "what are those?" > > I disagree with this assessment. Many functions are actually collected in
static classes so they can be autoloaded. So instead of, namespace Foo\Bar; class Map { public static function modelToApi(Model $model) : array {} } The function can now just be in a namespace directly, instead of treating a class like a namespace. You can then also import just the function you need, instead of the whole class. Many of these classes exist in projects I've worked on just for the purpose of being able to autoload the functions when needed. My 2 cents.
> --Larry Garfield
  101787
February 6, 2018 19:21 smalyshev@gmail.com (Stanislav Malyshev)
Hi!

> That said, I'm not sure that function autoloading will be that big of a carrot > for the major projects at this point. Wordpress is going to ignore anything
If they pay for that is to edit every single file that uses global functions (which is all of them) or suffer a hailstorm of warnings then I don't think any carrot would be large enough for this. And, frankly, the amount of cases where I absolutely needed namespace function autoloading and couldn't do without it (like, using classes) I probably could count on the fingers of one hand, and I still could type while doing it. I mean, I don't necessarily have anything against adding this feature, but if the progression goes from "we need namespaced functions" to "we need namespaced autoloaded functions" to "we can't use strlen without ridiculous prefixing or adding "yes, I still want strlen" in every file every time" then I'd rather not have namespaced functions at all than deal with that.
> outside of very specific libraries (such as functional tooling libs). So "yay, > you can now autoload namespaced user-defined functions" will likely be met with > a lot of "what are those?"
It won't be just "yay, you can now autoload namespaced user-defined functions", it would be "yay, all code that uses strlen is not throwing noisy warnings, but on the other hand, we made this obscure feature you never used easier, so rejoice!" I wouldn't rejoice. -- Stas Malyshev smalyshev@gmail.com
  101786
February 6, 2018 19:14 smalyshev@gmail.com (Stanislav Malyshev)
Hi!

> Yes we do have root namespace lookup, but its not automatic, it is only > as a fallback. This RFC is about removing the intermediate namespace'd > check, hence requiring \strlen.
It is automatic, in the meaning you don't have to do anything to get it. Realistically, how often do you override strlen? If I say "never", I probably would be close enough for all practical purposes.
> My idea was to force all function lookups into the global nameespace > first by doing the declare or use. This way someone writing a file could > state "i dont use namespaced functions in this file, don't try to load > them".
Why? We already have this working, why make it harder by requiring to do specific things that we know upfront 99%+ people end up doing? Why not assume them by default? -- Stas Malyshev smalyshev@gmail.com
  101796
February 7, 2018 02:51 narf@devilix.net (Andrey Andreev)
Hi,

> Realistically, how often do you override strlen? If I say "never", I > probably would be close enough for all practical purposes.
It's an ironic coincidence that you use strlen() as an example. Because it and substr() are possibly the most likely to be overriden, where we need code to be byte-safe in spite of mbstring.func_overload. But why does that matter, either way? Cheers, Andrey.
  101797
February 7, 2018 03:53 smalyshev@gmail.com (Stanislav Malyshev)
Hi!

> It's an ironic coincidence that you use strlen() as an example. > Because it and substr() are possibly the most likely to be overriden, > where we need code to be byte-safe in spite of mbstring.func_overload.
Also happens rather rarely, in my impression, since you'd have to a) run mbstring.func_overload which you can't remove and b) still need non-overloaded string functions. And if you are in this rare situation, it's usually better to have explicitly-named function, so that you know what you are dealing with, not relying on subtle details of how names are resolved vs. namespaces. -- Stas Malyshev smalyshev@gmail.com
  101766
February 5, 2018 10:17 ivan.enderlin@hoa-project.net (Ivan Enderlin)
Hello :-),

Thank you for the RFC. I really appreciate it, for sure, but I would 
like to raise a concern regarding the atoum test framework [1].

atoum provides 3 mock engines, resp. for class-like entitites, 
functions, and constants.

The function and constant mock engines are both based on the same 
principle, i.e. it relies on the “entity bubble look up resolution” 
algorithm to mock functions or constants. Typically, one might mock the 
`file_exists` function like this: `$this->function->file_exists = 
function (…) { … };`. In this case, atoum creates a new `file_exists` 
function in the same namespace than the system under test (if testing 
`A\B\C`, then atoum creates `A\B\file_exists`).

It is a very convinient and beloved way to mock functions and constants.

And thus, this RFC raises the following issue: *This feature is used a 
lot by atoum users. The RFC will destroy this feature. It's not about 
atoum loosing a master feature, it's more about: How users will be able 
to mock functions and constants after that? This is an important question*.

That's a hard question to answer, I know, but in its actual form, the 
RFC breaks a non-negligeable part of the testing ecosystem. This is 
something to take into account :-).

It is still possible to use moles instead of mocks to achieve the same 
behavior, but restricted to user-defined functions only. Moles do not 
allow to change the behavior of “VM-defined” functions.

Regards.


[1] http://atoum.org/

On 03.02.18 09:27, Wes wrote:
> Hello PHPeople. I just published the RFC "Deprecation of fallback to root > scope". > > It is quite a substantial change, but as you can read in the RFC, can be a > (basically) transparent one. > I'm referring to the possibility to shim it in userland. Essentially, this > would move the feature from core to userland. > > I hope you like it. Let me know what you think. > > https://wiki.php.net/rfc/fallback-to-root-scope-deprecation >
  101768
February 5, 2018 10:53 ocramius@gmail.com (Marco Pivetta)
Hey Ivan,

On 5 Feb 2018 11:18, "Ivan Enderlin" enderlin@hoa-project.net> wrote:

Hello :-),

Thank you for the RFC. I really appreciate it, for sure, but I would like
to raise a concern regarding the atoum test framework [1].

atoum provides 3 mock engines, resp. for class-like entitites, functions,
and constants.

The function and constant mock engines are both based on the same
principle, i.e. it relies on the “entity bubble look up resolution”
algorithm to mock functions or constants. Typically, one might mock the
`file_exists` function like this: `$this->function->file_exists = function
(…) { … };`. In this case, atoum creates a new `file_exists` function in
the same namespace than the system under test (if testing `A\B\C`, then
atoum creates `A\B\file_exists`).

It is a very convinient and beloved way to mock functions and constants.

And thus, this RFC raises the following issue: *This feature is used a lot
by atoum users. The RFC will destroy this feature. It's not about atoum
loosing a master feature, it's more about: How users will be able to mock
functions and constants after that? This is an important question*.

That's a hard question to answer, I know, but in its actual form, the RFC
breaks a non-negligeable part of the testing ecosystem. This is something
to take into account :-).

It is still possible to use moles instead of mocks to achieve the same
behavior, but restricted to user-defined functions only. Moles do not allow
to change the behavior of “VM-defined” functions.

Regards.


[1] http://atoum.org/


See https://externals.io/message/101745#101752

The problem is always with routines (not  functions)) that rely on shared
global mutable state.

Mocking those is generally a problem, as it exposes a dependency inversion
issue, rather than actually getting rid of an implicit reliance on global
state that is not declared to consumers of a SUT.
  101769
February 5, 2018 12:52 rowan.collins@gmail.com (Rowan Collins)
On 5 February 2018 at 10:53, Marco Pivetta <ocramius@gmail.com> wrote:

> > See https://externals.io/message/101745#101752 > > The problem is always with routines (not functions)) that rely on shared > global mutable state. > > Mocking those is generally a problem, as it exposes a dependency inversion > issue, rather than actually getting rid of an implicit reliance on global > state that is not declared to consumers of a SUT. >
While that would be a perfectly fine justification for not adding this feature, it doesn't address the impact of removing the feature now that it has existed for over 8 years. Even before the feature is actually removed, anyone using such tests would be faced with the following options: * Put up with hundreds of notices until they have a chance to completely refactor the code in question. * Suppress all messages of a particular level (possibly E_STRICT initially and E_DEPRECATED later) until they have the chance to refactor. * Prepend \ to global function references, purely to stop the deprecation notices, and break all tests that relied on this mocking mechanism. None of these options is particularly appealing, and this will all be for a hypothetical future improvement to the language. Regards, -- Rowan Collins [IMSoP]
  101770
February 5, 2018 12:54 ocramius@gmail.com (Marco Pivetta)
On Mon, Feb 5, 2018 at 1:52 PM, Rowan Collins collins@gmail.com>
wrote:

> None of these options is particularly appealing, and this will all be for a > hypothetical future improvement to the language. >
Would proposing a function autoloading RFC together with this improve the situation? Marco Pivetta http://twitter.com/Ocramius http://ocramius.github.com/
  101771
February 5, 2018 13:18 rowan.collins@gmail.com (Rowan Collins)
On 5 February 2018 at 12:54, Marco Pivetta <ocramius@gmail.com> wrote:

> On Mon, Feb 5, 2018 at 1:52 PM, Rowan Collins collins@gmail.com> > wrote: > >> None of these options is particularly appealing, and this will all be for >> a >> hypothetical future improvement to the language. >> > > Would proposing a function autoloading RFC together with this improve the > situation? >
I think it would, firstly because it gives a visible benefit to the change we would be asking users to make, and secondly because it allows a shim like the example in the RFC to be used immediately as a transition. As I mentioned in an aside previously, it would also make an opt-in statement more reasonable, because saying "namespace Foo\Bar with autoload" could both turn off the fallback lookup and turn on autoloading functions in the current namespace. Fully-qualified function names could be autoloaded in both modes, and presumably functions explicitly imported with "use" could be too. Regards, -- Rowan Collins [IMSoP]
  101789
February 6, 2018 19:26 smalyshev@gmail.com (Stanislav Malyshev)
Hi!

>> None of these options is particularly appealing, and this will all be for a >> hypothetical future improvement to the language. >> > > Would proposing a function autoloading RFC together with this improve the > situation?
No. Function autoloading addresses the needs of tiny part of the users. While I am far from discounting these needs - they are still valid needs and we may want to serve them if we can - if the costs is to impose a huge burden on the rest of the users it doesn't make it much better. It's the situation of "we just broke all your code" vs. "we just broke all your code, but some of *our* code is now easier to write". Not much of an improvement, I think. -- Stas Malyshev smalyshev@gmail.com
  101798
February 7, 2018 14:02 rowan.collins@gmail.com (Rowan Collins)
On 3 February 2018 08:27:18 GMT+00:00, Wes php@gmail.com> wrote:
>Hello PHPeople. I just published the RFC "Deprecation of fallback to >root >scope". > >https://wiki.php.net/rfc/fallback-to-root-scope-deprecation
Given the discussion so far, how about taking the "opposite" approach: deprecate unprefixed reference to functions which *are* in the current namespace. Proposal: - PHP 7.3: Add syntax to explicitly reference functions and constants in the current namespace, such as .\foo or this\foo - PHP 7.4: Raise E_DEPRECATED whenever an unprefixed function/constant resolves to something in the current namespace (other than via "use" alias) - PHP 8.0: Make all unprefixed functions/constants always refer to the root namespace Pros: - Much less disruptive change, as the majority of unprefixed function calls are to global functions, and would not need to change. - Both cases can be made unambiguous if the author wants to. - Apparently OpCache currently mitigates the performance hit by caching lookups in a technically unclean way. Users hit by this can make their code unambiguous in 7.3, and the optimisation will become clean in 8.0. - Function / constant autoloading can be added in 7.x if we accept the caveat that unprefixed functions will not be autoloaded; or in 8.0 if we want to cover everything. Cons: - Slightly uglier syntax. - Still a breaking change (in 8.0). - Class names will still be resolved differently from function and constant names. - Code actively using the fallback system (e.g. tests masking global functions with mocks) will need refactoring as there is no way to opt into the old behaviour. - The .\foo() syntax may appear in similar places to the . concatenation operator. Even if technically unambiguous and implementable in the parser, this may be confusing to users. A keyword approach like this\foo() would be clearer, but more verbose. What do people think? Is it worth expanding this out into an alternative RFC? Regards, -- Rowan Collins [IMSoP]
  101799
February 7, 2018 15:20 cmbecker69@gmx.de ("Christoph M. Becker")
On 07.02.2018 at 15:02, Rowan Collins wrote:

> - PHP 7.3: Add syntax to explicitly reference functions and constants in > the current namespace, such as .\foo or this\foo
It is already possible to use the `namespace` keyword for this, see <https://3v4l.org/bikjE>.
> - Slightly uglier syntax.
IMHO, .\foo is very ugly, and namespace\foo is not much better. -- Christoph M. Becker
  101802
February 7, 2018 16:40 rowan.collins@gmail.com (Rowan Collins)
On 7 February 2018 at 15:20, Christoph M. Becker <cmbecker69@gmx.de> wrote:

> On 07.02.2018 at 15:02, Rowan Collins wrote: > > > - PHP 7.3: Add syntax to explicitly reference functions and constants in > > the current namespace, such as .\foo or this\foo > > It is already possible to use the `namespace` keyword for this, see > <https://3v4l.org/bikjE>. >
Huh, I never knew that! Funnily enough, I thought of that as a possibility (because it's already a reserved word) but rejected it as too long. :P
> > - Slightly uglier syntax. > > IMHO, .\foo is very ugly, and namespace\foo is not much better. >
Yeah; the question is whether that ugliness is something we're willing to live with for the performance and features it would enable. Most code would still be less ugly than if we had to prefix all global functions, anyway. Something worth considering is that even when using namespaced functions, the shorthand is only available in *exactly the current namespace*, so you're rather likely to be qualifying or importing them anyway. For instance, they might be in a child or neighbouring namespace called "...\functions" or " ...\ utils" or " ...\ streams". Regards, -- Rowan Collins [IMSoP]
  101800
February 7, 2018 16:26 levim@php.net (Levi Morrison)
On Wed, Feb 7, 2018 at 7:02 AM, Rowan Collins collins@gmail.com> wrote:
> On 3 February 2018 08:27:18 GMT+00:00, Wes php@gmail.com> wrote: >>Hello PHPeople. I just published the RFC "Deprecation of fallback to >>root >>scope". >> >>https://wiki.php.net/rfc/fallback-to-root-scope-deprecation > > > Given the discussion so far, how about taking the "opposite" approach: > deprecate unprefixed reference to functions which *are* in the current > namespace. > > Proposal: > - PHP 7.3: Add syntax to explicitly reference functions and constants in > the current namespace, such as .\foo or this\foo > - PHP 7.4: Raise E_DEPRECATED whenever an unprefixed function/constant > resolves to something in the current namespace (other than via "use" alias) > - PHP 8.0: Make all unprefixed functions/constants always refer to the root > namespace > > Pros: > - Much less disruptive change, as the majority of unprefixed function calls > are to global functions, and would not need to change. > - Both cases can be made unambiguous if the author wants to. > - Apparently OpCache currently mitigates the performance hit by caching > lookups in a technically unclean way. Users hit by this can make their code > unambiguous in 7.3, and the optimisation will become clean in 8.0. > - Function / constant autoloading can be added in 7.x if we accept the > caveat that unprefixed functions will not be autoloaded; or in 8.0 if we > want to cover everything. > > Cons: > - Slightly uglier syntax. > - Still a breaking change (in 8.0). > - Class names will still be resolved differently from function and constant > names. > - Code actively using the fallback system (e.g. tests masking global > functions with mocks) will need refactoring as there is no way to opt into > the old behaviour. > - The .\foo() syntax may appear in similar places to the . concatenation > operator. Even if technically unambiguous and implementable in the parser, > this may be confusing to users. A keyword approach like this\foo() would be > clearer, but more verbose. > > What do people think? Is it worth expanding this out into an alternative > RFC? > > Regards, > -- > Rowan Collins [IMSoP]
My opinion is that the result is both uglier and *even less consistent* with namespaced types. I'm glad you are at least thinking about alternative proposals but this is worse than both the original proposal and doing nothing.
  101803
February 7, 2018 16:56 narf@devilix.net (Andrey Andreev)
Hi,

What's not obvious (to me at least) here is why is the current
behavior preventing a ("sensible", as the RFC desribes it)
implementation of function autoloading? That seems to be a major
motivation factor for the proposal, yet doesn't seem to be explained
anywhere.

Cheers,
Andrey.
  101804
February 7, 2018 17:19 rowan.collins@gmail.com (Rowan Collins)
On 7 February 2018 at 16:56, Andrey Andreev <narf@devilix.net> wrote:

> Hi, > > What's not obvious (to me at least) here is why is the current > behavior preventing a ("sensible", as the RFC desribes it) > implementation of function autoloading? That seems to be a major > motivation factor for the proposal, yet doesn't seem to be explained > anywhere. >
It's not been mentioned explicitly in this thread, but has come up a lot in previous discussions. I'll attempt to summarise my understanding. Currently, when you write "foo()" in code marked as namespace "Bob", the engine does this: 1. Check for a function "Bob\foo", use it if defined 2. Check for a function "foo", use it if defined 3. Raise an error if neither is defined If we add autoloading of functions, the logical sequence would be to attempt the autoloader every time we encounter something not defined: 1. Check for a function "Bob\foo", use it if defined 1a. Run autoloader callback for "Bob\foo"; use function if one is now defined 2. Check for a function "foo", use it if defined 2a. Run autoloader callback for "foo"; use function if one is now defined 3. Raise an error if neither is defined The problem is that all of this has to happen *every time you call the function*, because at any time, the function could be registered, or a new autoloader registered that knows where to find it. If "foo" is actually a global function, that means steps 1 and 1a will be run every time your use of "foo()" is reached, meaning that every call has an additional overhead of calling the autoloader callback. Since the autoloader callback might in fact be a whole stack of registered closures, this means a significant overhead every time you mention any global function, which includes 90% of PHP's standard library. I hope that clarifies the general problem (and that I haven't made any mistakes in my explanation). Regards, -- Rowan Collins [IMSoP]