Hi internals,
This RFC proposes to support an opt-in "use global functions/consts;" statement to disable PHP's check for the function/const in the current namespace before falling back to the global namespace.
https://wiki.php.net/rfc/use_global_elements
Earlier discussion can be found in the 'Opt-in "use function *;" for skipping check for function/const in alternate namespace' email thread, which can be seen at https://externals.io/message/107877
Let me know if you have any comments on the RFC, e.g.
- Typical RFC feedback
- Missing parts, sections, or formatting issues in the RFC
- Choices of voting options
- Alternate syntax ideas ("use function *" was mentioned earlier, "use global function" doesn't make sense to me because it's singular instead of plural)
e.g. different directive names for the declare() voting option.
Thanks,
- Tyson
Hello Tyson,
Hi internals,
This RFC proposes to support an opt-in "use global functions/consts;"
statement to disable PHP's check for the function/const in the current
namespace before falling back to the global namespace.https://wiki.php.net/rfc/use_global_elements
Earlier discussion can be found in the 'Opt-in "use function *;" for
skipping check for function/const in alternate namespace' email thread,
which can be seen at https://externals.io/message/107877Let me know if you have any comments on the RFC, e.g.
- Typical RFC feedback
- Missing parts, sections, or formatting issues in the RFC
- Choices of voting options
- Alternate syntax ideas ("use function *" was mentioned earlier, "use
global function" doesn't make sense to me because it's singular instead of
plural)
e.g. different directive names for the declare() voting option.Thanks,
- Tyson
--
Do you have plans to use the https://github.com/php/php-rfcs to promote the
discussion as well, the same way we did
https://github.com/php/php-rfcs/pull/1 for the Typed Properties RFC?
Best regards,
Do you have plans to use the https://github.com/php/php-rfcs to promote the discussion as well, the same way
we did https://github.com/php/php-rfcs/pull/1 for the Typed Properties RFC?
No, I have no plans to switch to GitHub. At the time of writing, https://github.com/php/php-rfcs/blob/master/README.md has the following note about not submitting PRs, so I decided against trying out the experimental RFC process.
This is just a one-off experiment for now, we'll have to discuss whether we want to move the RFC process towards this separately. This repository may be abandoned. Please don't submit PRs for now.
- I'm not sure if there's a consensus on https://externals.io/message/107747#107747 ("GitHub RFC workflow").
- I expect this RFC to be smaller in scope (of discussion) than adding union types to the language.
Other thoughts on "GitHub RFC workflow" (Sorry for this being off topic- I don't know how to reply to a mailing list thread I don't have in my inbox while preserving threading, from Outlook in a browser. The "In Reply To" header seems like what I'd want, but is impractical to set with this setup):
- It seems slightly time consuming and error-prone for formatting (but doable) to migrate from markdown to dokuwiki after the RFC is reviewed on GitHub (I see this was already mentioned). Maybe publishing the dokuwiki markup as plain text, linking to the wiki, and having code review on that would be a better option to write (but harder for reviewers unfamiliar with the dokuwiki format).
Tooling (use pandoc or something else to convert from HTML (rendered by wiki) to markdown for the github PR) may help with that process - I'm not familiar with the best options. dokuwiki only has official support for export to odt and xhtml, as far as I can tell - If I linked to a GitHub PR as a secondary source of reviews to the email thread (instead of the main source), it might be splitting up the discussion, and reviewers would miss or duplicate comments.
Thanks,
- Tyson
This RFC proposes to support an opt-in "use global functions/consts;" statement to disable PHP's check for the function/const in the current namespace before falling back to the global namespace.
It's an interesting idea, but at this time I think it's the wrong
approach to what is in the best long-term interests of the language by
introducing an additional point of inconsistency.
Classes search the current namespace, but functions / const would search
namespace first, unless they don't, then global?
For the very minor one-time performance hit (thanks to the cache slot),
I think the situation is best remaining as-is for the time being.
In future, I think the optimal solution is opt-in deprecating fallback
to the root namespace using a declare. We might eventually benefit from
versioned "libraries" of functions that can be imported in one command
which would solve many-a-future-problem by itself.
Somewhat related is how global functions are consumed -
Id like to see nikic/scalar_objects added to the core in 8.0, that would
offer non-procedural (and therefore non-namespaced) access to many of
the most common global functions (strings, arrays etc). In turn, that
would allow developers to limit the number of use ... statements.
That doesn't cover defined constants, but IMO we should be pushing those
to be moved into class constants, simply because in the absense of
function / constant / anything-but-class level autoloading, things might
as well be in a readily available location.
--
Mark Randall
marandall@php.net
This RFC proposes to support an opt-in "use global functions/consts;" statement
to disable PHP's check for the function/const in the current namespace before falling back to the global namespace.https://wiki.php.net/rfc/use_global_elements
Earlier discussion can be found in the 'Opt-in "use function *;" for skipping check for
function/const in alternate namespace' email thread, which can be seen at
https://externals.io/message/107877
Let me know if you have any comments on the RFC
I plan to update the wiki and start the voting phase tomorrow with the voting structure mentioned in https://wiki.php.net/rfc/use_global_elements
Alternatives/Arguments mentioned in this thread have had summaries added in the discussion section.
Thanks,
- Tyson
On Tue, Jan 14, 2020 at 7:27 PM tyson andre tysonandre775@hotmail.com
wrote:
This RFC proposes to support an opt-in "use global functions/consts;"
statement
to disable PHP's check for the function/const in the current namespace
before falling back to the global namespace.https://wiki.php.net/rfc/use_global_elements
Earlier discussion can be found in the 'Opt-in "use function *;" for
skipping check for
function/const in alternate namespace' email thread, which can be seen at
https://externals.io/message/107877
Let me know if you have any comments on the RFCI plan to update the wiki and start the voting phase tomorrow with the
voting structure mentioned in https://wiki.php.net/rfc/use_global_elements
Alternatives/Arguments
https://wiki.php.net/rfc/use_global_elementsAlternatives/Arguments
mentioned in this thread have had summaries added in the discussion section.
Hi Tyson,
I don't think it's a good idea to resolve the question of "use global
functions" vs "declare" as a subsidiary vote. At least in my mind, those
two options are significantly different, and this choice would affect both
my overall opinion of the proposal and also the answer I would give on some
of the other voted question.
The RFC already outlines a number of reasons why it is preferable to
implement this as a declare directive, so please excuse my reiterating some
points here :)
First and foremost, if we ever implement
https://wiki.php.net/rfc/namespace_scoped_declares or some similar way of
specifying declares on the package level, and I think it's pretty likely
that we're going to do this in one form or another, then we're very much
going to regret not making this a declare. Disabling the namespace
fallback, just like the use of strict types, is something you will usually
want to do for an entire library/project, not just for individual files.
Going for something like "use global functions" preemptively precludes this
for no good reason.
Second, I think phrasing the semantics in terms of a change to name
resolution behavior (which the declare does) is clearer than phrasing it as
"import all functions/consts in the global namespace". That's not really
what this this feature is doing on a technical level, and this phrasing is
what results in questions regarding the behavior for various conditions
regarding symbol overlaps etc. For example, with the declare, I don't think
that it should be an error to make a function declaration inside a
namespace -- that's still entirely well defined, and I think a legitimate
use-case (a project that is disabling namespace fallback everywhere, will
likely want to do that for files declaring functions as well, as a matter
of consistency.)
Third, I'm not sure it makes sense to separate this functionality for
functions and for constants. I can't really imagine a situation where you
would want to, say, use namespaced constants but global functions. I can
see why you went with this split when using the "use" syntax (as we already
have "use function" and "use const" both), but with a declare approach, I
would suggest to combine both. Functions and constants live in different
symbol spaces, but their name resolution behavior is the same.
Finally, if you do want to go with the "use" syntax, "functions" and
"consts" should not be made reserved keywords. There is no technical need
for these to be true keywords, so we can avoid an unnecessary BC break here.
Regards,
Nikita
I'll be postponing the vote to update the RFC and proof of concept/tests associated with it to use declare()
Also, "declare(lookup_functions_in_current_namespace = false, lookup_consts_in_global_namespace = false)" in the file's declare() blocks was my first idea.
Any ideas - declare(disable_ambiguous_element_lookups=1), declare(disable_ambiguous_lookups_in_current_namespace=1), etc?
x=1 seems to be more common, and reflects the fact that this is not the default.
I don't think it's a good idea to resolve the question of "use global functions" vs "declare" as a subsidiary vote.
At least in my mind, those two options are significantly different, and this choice would affect both my overall opinion of the proposal
and also the answer I would give on some of the other voted question.
Agreed, I had some of those concerns after suggesting setting it up that way.
It doesn't capture "accept if one option, but not if the other option".
Ideally, I could have a vote for the syntax to use for the RFC,
then amend the RFC with the syntax, but that isn't practical.
The RFC already outlines a number of reasons why it is preferable to implement this as a declare directive,
so please excuse my reiterating some points here :)
First and foremost, if we ever implement
https://wiki.php.net/rfc/namespace_scoped_declares or some similar way of specifying declares on the package level,
and I think it's pretty likely that we're going to do this in one form or another, then we're very much going to regret not making this a
declare.
Disabling the namespace fallback, just like the use of strict types, is something you will usually want to do for an entire library/project, not just for individual files.
Going for something like "use global functions" preemptively precludes this for no good reason.
That's a good point. I think that's the first time I've seen that RFC.
https://wiki.php.net/rfc/namespace_scoped_declares#nesting_behavior /
https://wiki.php.net/rfc/namespace_scoped_declares#implementation_considerations answers my questions about how that would work with readability/opcache.
It'd definitely be convenient to have less boilerplate.
Second, I think phrasing the semantics in terms of a change to name resolution behavior (which the declare does)
is clearer than phrasing it as "import all functions/consts in the global namespace".
That's not really what this this feature is doing on a technical
level, and this phrasing is what results in questions regarding the behavior for various conditions regarding symbol overlaps etc.
For example, with the declare, I don't think that it should be an error to make a function declaration inside a namespace
-- that's still entirely well defined, and I think a legitimate use-case
(a project that is disabling namespace fallback everywhere, will likely want to do that for files declaring functions as well, as a matter of consistency.)
My concern was about this being well-defined but being likely to be accidentally misused, e.g. with namespace-scoped declares.
Same for NS\my_printf calling \my_sprintf instead of NS\my_sprintf within the same file.
Explicitly changing to namespace\my_sprintf() or uses would be one way to migrate code like that.
namespace Example;
use global functions; // or declare()
// interpreting this literally, without `use Example\fact;` instead of namespace\fact, this is calling \fact(), which is surprising
// (the old equivalent `use function fact;` would throw because of the name reuse)
function fact($n) { return $n > 1 ? $n * fact($n - 1) : 1; }
Third, I'm not sure it makes sense to separate this functionality for functions and for constants.
I can't really imagine a situation where you would want to, say, use namespaced constants but global functions.
I can see why you went with this split when using the "use" syntax (as we already have "use function" and "use const" both),
but with a declare approach, I would suggest to combine both. Functions and constants live in different symbol spaces,
but their name resolution behavior is the same.
If you're declaring a function or a constant in a namespace, the way I implemented it would throw an Error at compile time to avoid confusion.
If it didn't throw an Error, then I'd agree that it'd virtually always be used together, except possibly when migrating to being stricter gradually.
Finally, if you do want to go with the "use" syntax, "functions" and "consts" should not be made reserved keywords.
There is no technical need for these to be true keywords, so we can avoid an unnecessary BC break here.
Agreed for future work on "use"
Hi internals,
After feedback, the RFC syntax has been changed from use global functions
to declare(disable_ambiguous_element_lookup=1)
. In addition,
-
The two settings have been combined into a single option,
which is now declare(disable_ambiguous_element_lookup=1) at the top of a file.Those settings would be enabled together, in any use case I can think of.
-
Declaring global functions and constants in files with declare(disable_ambiguous_element_lookup=1) is now allowed in any namespace,
to allow code to continue to work even with future changes such as https://wiki.php.net/rfc/namespace_scoped_declares
(and so that files declaring functions or constants can have consistent coding style with files that don't) -
The following voting choices have been removed: (1) the syntax and for (2) whether declaring functions/constants are errors
The outcome of those votes would noticeably change the RFC and affect whether voters would vote for the RFC as a whole.
The RFC https://wiki.php.net/rfc/use_global_elements has been updated.
The implementation at https://github.com/php/php-src/pull/4951 has also been updated.
I was planning to move this to the voting stage on the 25th (1 week),
since the revised RFC is similar to the old RFC,
and arguments in favor of declare() have been mentioned for over 2 weeks.
Thanks,
- Tyson
Hi,
I find that the “disable_ambiguous_element_lookup” directive name is, well, ambiguous. Does it mean that it will look up only in the current namespace, or only in the global namespace? I can’t guess.
Maybe a three-value directive:
declare(function_and_const_lookup=global);
declare(function_and_const_lookup=namespace);
declare(function_and_const_lookup=fallback); // the default
—Claude
which is now declare(disable_ambiguous_element_lookup=1) at the top of a file.
I_suspect_these_long_declares_might_get_tedious
Can we at least agree on internals that a declare doesn't have to have a
negative default value that is toggled on?
I'd much rather have something like:
declare(ambiguous_element_lookup=0)
declare(ambiguous_element_lookup=off)
--
Mark Randall
marandall@php.net