Skip to content

Proposal: Support declare(function_and_const_lookup = 'global') #4951

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from

Conversation

TysonAndre
Copy link
Contributor

@TysonAndre TysonAndre commented Nov 28, 2019

RFC - https://wiki.php.net/rfc/use_global_elements

This adds an implementation and tests for my proposal in
https://news-web.php.net/php.internals/107877
and https://externals.io/message/107953
(those links has background information and why I'm proposing this.
I created this PR to prepare for creating an RFC document,
and demonstrate that this is doable)

  • This PR is deliberately making this behavior opt-in (e.g. not emitting notices or changing the behavior of existing code, such as unmaintained third-party libraries)

Normally, for a non-fully-qualified function or constant name,
PHP would check for My\NS\my_function() and My\NS\MY_CONST
at runtime before checking the global namespace (for every usage).

declare(function_and_const_lookup = global) would be the same as fully qualifying every
function call or constant usage, and avoids the second check.

This would be used as follows:
(No implicit uses are added - sprintf should be resolved in the same way in the below example
whether the function was declared in the same file or a different file)

declare(function_and_const_lookup = global);
 
namespace MyNS;

// Outside the global namespace, without 'use function MyNS\sprintf',
// declaring a function is a compile error when function_and_const_lookup='global'.
// PHP already only warns about the name already
// being in use if the namespace being referred to is different.
// It does not emit notices, warnings, or errors if the namespace is the same.
use function MyNS\factorial;
use function MyNS\sprintf;
// Outside the global namespace, without 'use const MyNS\MY_CONST',
// declaring a constant is a compile error when function_and_const_lookup='global'.
// PHP already only warns about the name already
// being in use if the namespace being referred to is different.
// It does not emit notices, warnings, or errors if the namespace is the same.
use const MyNS\MY_PREFIX;
 
const MY_PREFIX = 'Prefix';
 
function sprintf($msg, ...$args) {
    // this forces the implementer to explicitly refer to sprintf from the global namespace.
    return \sprintf(MY_PREFIX . " $msg", ...$args);
}
 
function factorial(int $n) {
    return $n > 1 ? factorial($n - 1) * $n : 1;
}

// The below function and constant references now unambiguously refer to the global namespace.
//
// Without "declare(function_and_const_lookup='global') ...",
// php would have checked for MyNS\version_compare
// and MyNS\PHP_VERSION at runtime before checking the global namespace.
// This can now be optimized to a constant by opcache, to eliminate dead code.
if (version_compare(PHP_VERSION, '8.0.5') >= 0) {
    // ...
}

@cmb69 cmb69 added the RFC label Nov 28, 2019
@TysonAndre TysonAndre changed the title Proposal: Support use function *; and use const *; Proposal: Support use global functions; and use global consts; Dec 23, 2019
@TysonAndre TysonAndre force-pushed the use-global-functions branch from 68a1d42 to 11e3e96 Compare January 18, 2020 17:10
@TysonAndre TysonAndre changed the title Proposal: Support use global functions; and use global consts; Proposal: Support declare(disable_ambiguous_element_lookup=1) Jan 18, 2020
@TysonAndre TysonAndre closed this Jan 19, 2020
@TysonAndre TysonAndre deleted the use-global-functions branch January 19, 2020 21:17
@TysonAndre TysonAndre reopened this Jan 19, 2020
@TysonAndre TysonAndre force-pushed the use-global-functions branch from 983f824 to f6dadd3 Compare January 19, 2020 21:22
@TysonAndre TysonAndre changed the title Proposal: Support declare(disable_ambiguous_element_lookup=1) Proposal: Support declare(function_and_const_lookup = global) Jan 24, 2020
@TysonAndre TysonAndre force-pushed the use-global-functions branch from f6dadd3 to e51a24b Compare January 26, 2020 15:15
@TysonAndre TysonAndre changed the title Proposal: Support declare(function_and_const_lookup = global) Proposal: Support declare(function_and_const_lookup = 'global') Jan 26, 2020
This adds an implementation and tests for my proposal in
https://news-web.php.net/php.internals/107877
and https://externals.io/message/107953
(that link has background information and why I'm proposing this.
I created this PR to prepare for creating an RFC document,
and demonstrate that this is doable)

Normally, for a non-fully-qualified function or constant name,
PHP would check for `My\NS\my_function()` and `My\NS\MY_CONST`
at runtime before checking the global namespace (for every usage).

`use function *;` or `use const *;` would be the same as fully qualifying every
function call or constant usage, and avoids the second check.

This would be used as follows:

```php
<?php
// value: the name global or default
declare(function_and_const_lookup = global);
namespace My\NS;
// can still use functions/constants from namespaces
// that aren't the global namespace.
printf("PHP Version is: %s\n", PHP_VERSION);
```

Allow function/const definitions,
but require explicitly using the function or const definition by name
to use the function from the current namespace instead of the global namespace.

1. If https://wiki.php.net/rfc/namespace_scoped_declares
   exists, declare() will be a more flexible choice than 'use global consts';
2. Most RFC feedback was in favor of declare(), and in using syntax
   describing this as changing the way resolution is done than as
   using functions/consts from the global namespace.
3. Applications/libraries that disable ambiguity for functions or constants
   would almost always disable it for both.

   Combining them into a single option would be less verbose.
when function_and_const_lookup='global'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants