[RFC] Treat namespaced names as single token, relax reserved keyword restrictions

  110568
June 16, 2020 08:52 nikita.ppv@gmail.com (Nikita Popov)
Hi internals,

Inspired by the recent discussion on reserved keyword reservation, I'd like
to propose the following RFC:

https://wiki.php.net/rfc/namespaced_names_as_token

This RFC makes two related changes: Treat namespaced names as a single
token, which enables use of reserved keywords inside them. And remove
reserved keyword restrictions from various declarations.

The RFC comes with a small backwards compatibility break related to names
that include whitespace, but will hopefully reduce the backwards
compatibility impact of future reserved keyword additions.

Regards,
Nikita
  110571
June 16, 2020 09:07 sebastian@php.net (Sebastian Bergmann)
Am 16.06.2020 um 10:52 schrieb Nikita Popov:

+1

> The RFC comes with a small backwards compatibility break related to names > that include whitespace, but will hopefully reduce the backwards > compatibility impact of future reserved keyword additions.
This statement misses the fact that code which uses token_get_all() needs to be updated due to the new T_NAME_* tokens. The RFC itself lists this change, so that's okay.
  110608
June 16, 2020 20:28 davey@php.net (Davey Shafik)
On Tue, Jun 16, 2020 at 1:52 AM Nikita Popov ppv@gmail.com> wrote:

> Hi internals, > > Inspired by the recent discussion on reserved keyword reservation, I'd like > to propose the following RFC: > > https://wiki.php.net/rfc/namespaced_names_as_token > > This RFC makes two related changes: Treat namespaced names as a single > token, which enables use of reserved keywords inside them. And remove > reserved keyword restrictions from various declarations. > > The RFC comes with a small backwards compatibility break related to names > that include whitespace, but will hopefully reduce the backwards > compatibility impact of future reserved keyword additions. > > Regards, > Nikita >
The only issue I have with this RFC is this: use Foo as KEYWORD; While this might be _technically_ correct, it is unusable. That is: use Foo as List; class Bar extends List { } // this will not work Given this, I think this specific syntax should be an error, unless I'm missing something? Also, does this mean we can alias to fully namespaced names now? use \My\Foo as \Bar\Foo; class Bat extends \Bar\Foo { } // now actually extends \My\Foo, not \Bar\Foo (no autoload would happen?) - Davey
  110609
June 16, 2020 20:34 nikita.ppv@gmail.com (Nikita Popov)
On Tue, Jun 16, 2020 at 10:28 PM Davey Shafik <davey@php.net> wrote:

> > > On Tue, Jun 16, 2020 at 1:52 AM Nikita Popov ppv@gmail.com> wrote: > >> Hi internals, >> >> Inspired by the recent discussion on reserved keyword reservation, I'd >> like >> to propose the following RFC: >> >> https://wiki.php.net/rfc/namespaced_names_as_token >> >> This RFC makes two related changes: Treat namespaced names as a single >> token, which enables use of reserved keywords inside them. And remove >> reserved keyword restrictions from various declarations. >> >> The RFC comes with a small backwards compatibility break related to names >> that include whitespace, but will hopefully reduce the backwards >> compatibility impact of future reserved keyword additions. >> >> Regards, >> Nikita >> > > The only issue I have with this RFC is this: > > use Foo as KEYWORD; > > While this might be _technically_ correct, it is unusable. That is: > > use Foo as List; > > class Bar extends List { } // this will not work >
That's correct. However, "class Bar extends List\FooBar" will work. I mainly allow this because "use Foo\Bar" is the same as "use Foo\Bar as Bar". If "use Foo\List" is allowed, it makes little sense to forbid the equivalent "use Foo\List as List". Given this, I think this specific syntax should be an error, unless I'm
> missing something? > > Also, does this mean we can alias to fully namespaced names now? > > use \My\Foo as \Bar\Foo; > class Bat extends \Bar\Foo { } // now actually extends \My\Foo, not > \Bar\Foo (no autoload would happen?) >
No, this continues to be not allowed. "As" does not accept a namespaced name, it accepts a single identifier. Regards, Nikita
  110610
June 16, 2020 20:53 davey@php.net (Davey Shafik)
On Tue, Jun 16, 2020 at 1:34 PM Nikita Popov ppv@gmail.com> wrote:

> On Tue, Jun 16, 2020 at 10:28 PM Davey Shafik <davey@php.net> wrote: > >> >> >> On Tue, Jun 16, 2020 at 1:52 AM Nikita Popov ppv@gmail.com> >> wrote: >> >>> Hi internals, >>> >>> Inspired by the recent discussion on reserved keyword reservation, I'd >>> like >>> to propose the following RFC: >>> >>> https://wiki.php.net/rfc/namespaced_names_as_token >>> >>> This RFC makes two related changes: Treat namespaced names as a single >>> token, which enables use of reserved keywords inside them. And remove >>> reserved keyword restrictions from various declarations. >>> >>> The RFC comes with a small backwards compatibility break related to names >>> that include whitespace, but will hopefully reduce the backwards >>> compatibility impact of future reserved keyword additions. >>> >>> Regards, >>> Nikita >>> >> >> The only issue I have with this RFC is this: >> >> use Foo as KEYWORD; >> >> While this might be _technically_ correct, it is unusable. That is: >> >> use Foo as List; >> >> class Bar extends List { } // this will not work >> > > That's correct. However, "class Bar extends List\FooBar" will work. >
Hadn't considered this! Good point.
> > I mainly allow this because "use Foo\Bar" is the same as "use Foo\Bar as > Bar". If "use Foo\List" is allowed, it makes little sense to forbid the > equivalent "use Foo\List as List". > > Given this, I think this specific syntax should be an error, unless I'm >> missing something? >> > Looks like I was, consider my concern assuaged :)
> >> Also, does this mean we can alias to fully namespaced names now? >> >> use \My\Foo as \Bar\Foo; >> class Bat extends \Bar\Foo { } // now actually extends \My\Foo, not >> \Bar\Foo (no autoload would happen?) >> > > No, this continues to be not allowed. "As" does not accept a namespaced > name, it accepts a single identifier. >
But now the namespace _is_ a single identifier. Or at least, it creates some (minimal) confusion here IMO. - Davey
  110637
June 17, 2020 22:06 jakob@givoni.dk (Jakob Givoni)
On Tue, Jun 16, 2020 at 10:52 AM Nikita Popov ppv@gmail.com> wrote:
> > Hi internals, > > Inspired by the recent discussion on reserved keyword reservation, I'd like > to propose the following RFC: > > https://wiki.php.net/rfc/namespaced_names_as_token > > This RFC makes two related changes: Treat namespaced names as a single > token, which enables use of reserved keywords inside them. And remove > reserved keyword restrictions from various declarations. > > The RFC comes with a small backwards compatibility break related to names > that include whitespace, but will hopefully reduce the backwards > compatibility impact of future reserved keyword additions. > > Regards, > Nikita
Love it, thanks Nikita! In a mail that probably went to everyone's spam folder, I asked for opinions on allowing use of .\Foo as an alternative to Foo in the current namespace, thus reducing friction with reserved keywords even more. Any thoughts on that now? Best, Jakob
  110647
June 18, 2020 07:38 nikita.ppv@gmail.com (Nikita Popov)
On Thu, Jun 18, 2020 at 12:06 AM Jakob Givoni <jakob@givoni.dk> wrote:

> On Tue, Jun 16, 2020 at 10:52 AM Nikita Popov ppv@gmail.com> > wrote: > > > > Hi internals, > > > > Inspired by the recent discussion on reserved keyword reservation, I'd > like > > to propose the following RFC: > > > > https://wiki.php.net/rfc/namespaced_names_as_token > > > > This RFC makes two related changes: Treat namespaced names as a single > > token, which enables use of reserved keywords inside them. And remove > > reserved keyword restrictions from various declarations. > > > > The RFC comes with a small backwards compatibility break related to names > > that include whitespace, but will hopefully reduce the backwards > > compatibility impact of future reserved keyword additions. > > > > Regards, > > Nikita > > Love it, thanks Nikita! > > In a mail that probably went to everyone's spam folder, I asked for > opinions on allowing use of .\Foo as an alternative to Foo in the > current namespace, thus reducing friction with reserved keywords even > more. Any thoughts on that now? >
How would .\Foo be different from the currently existing namespace\Foo? (Note that "namespace" here is to be taken literally, not as "put the current namespace here"). Nikita
  110649
June 18, 2020 08:04 jakob@givoni.dk (Jakob Givoni)
On Thu, Jun 18, 2020 at 9:39 AM Nikita Popov ppv@gmail.com> wrote:
> >> In a mail that probably went to everyone's spam folder, I asked for >> opinions on allowing use of .\Foo as an alternative to Foo in the >> current namespace, thus reducing friction with reserved keywords even >> more. Any thoughts on that now? > > > How would .\Foo be different from the currently existing namespace\Foo? (Note that "namespace" here is to be taken literally, not as "put the current namespace here"). >
I didn't know you could do that! I don't think I've ever seen it used, maybe because there's been little advantage over just Foo? I guess it only matters if you also import Foo? For what it's worth, .\Foo would be significantly shorter than namespace\Foo and probably more intuitive to understand as well. Furthermore, if you were to create a namespace called "Namespace" (don't judge! ;-)), which I would assume would be possible should this RFC be implemented, we could avoid namespace\Namespace\Foo :-D Thanks for the feedback, it was just an idea - could be a new RFC some other day. Thanks, Jakob
  110643
June 18, 2020 04:18 tendoaki@gmail.com (Michael Morris)
What other language allows this? None that I can think of. Do we want PHP
doing something it's most closely related languages do not allow?  Why
don't they allow this? What problems are we creating by allowing this? I
can imagine this would make autoloading functions and constants by
namespace more complicated, but I'm not sure.

On Tue, Jun 16, 2020 at 3:52 AM Nikita Popov ppv@gmail.com> wrote:

> Hi internals, > > Inspired by the recent discussion on reserved keyword reservation, I'd like > to propose the following RFC: > > https://wiki.php.net/rfc/namespaced_names_as_token > > This RFC makes two related changes: Treat namespaced names as a single > token, which enables use of reserved keywords inside them. And remove > reserved keyword restrictions from various declarations. > > The RFC comes with a small backwards compatibility break related to names > that include whitespace, but will hopefully reduce the backwards > compatibility impact of future reserved keyword additions. > > Regards, > Nikita >
  110646
June 18, 2020 07:34 marcio.web2@gmail.com (Marcio Almada)
Hi,

What other language allows this? None that I can think of. Do we want PHP
> doing something it's most closely related languages do not allow? Why > don't they allow this?
Most language implementations don't do that because we are all using parser generators to do the heavy lifting of parsing and these often force us to pretend our programming languages are context free, and we accept that for convenience. But most of the programming languages - C, C++, Python, Ruby, JS, PHP, SQL - are not really context-free.
> What problems are we creating by allowing this?
In that case, this RFC makes it unnecessary to soft reserve words like `enum` to avoid BC breaks during PHP8 lifetime.
> I can imagine this would make autoloading functions and constants by > namespace more complicated, but I'm not sure.
I don't see how this would be harder with this proposal being accepted. Ty, Márcio Almada
  110645
June 18, 2020 06:44 claude.pache@gmail.com (Claude Pache)
Hi,

The following part of the proposal is problematic: Allow keywords in definition of classes, functions, const, etc.

class KEYWORD {}
interface KEYWORD {}
trait KEYWORD {}
function KEYWORD() {}
const KEYWORD = 0;
use Foo as KEYWORD;
Under your proposal, the following code will compile without notice, but will have a different behaviour from what the programmer intended:

```php
class Int { }

const PRINT = 2;
const YIELD = 3;

function foo(Int $b) {
    return PRINT + YIELD;
}
```

If it is important to allow to define classes, etc. with a keyword as name, I suggest to force the programmer to say explicitly “Yes, it is really what I want”. For example, something like the following:

```php
class namespace\Int { }

const namespace\PRINT = 2;
```

Another point which is problematic, is to allow `namespace` as a namespace parts, since `namespace\foo`, although interpreted as a namespace-relative name, could be intended to be a qualified name by the programmer.

—Claude




> Le 16 juin 2020 à 10:52, Nikita Popov ppv@gmail.com> a écrit : > > Hi internals, > > Inspired by the recent discussion on reserved keyword reservation, I'd like > to propose the following RFC: > > https://wiki.php.net/rfc/namespaced_names_as_token > > This RFC makes two related changes: Treat namespaced names as a single > token, which enables use of reserved keywords inside them. And remove > reserved keyword restrictions from various declarations. > > The RFC comes with a small backwards compatibility break related to names > that include whitespace, but will hopefully reduce the backwards > compatibility impact of future reserved keyword additions. > > Regards, > Nikita
  110648
June 18, 2020 07:46 nikita.ppv@gmail.com (Nikita Popov)
On Thu, Jun 18, 2020 at 8:44 AM Claude Pache pache@gmail.com> wrote:

> Hi, > > The following part of the proposal is problematic: Allow keywords in > definition of classes, functions, const, etc. > > class KEYWORD {}interface KEYWORD {}trait KEYWORD {}function KEYWORD() {}const KEYWORD = 0;use Foo as KEYWORD; > > Under your proposal, the following code will compile without notice, but > will have a different behaviour from what the programmer intended: > > ```php > class Int { } >
This part will still produce an error: "int" is not a reserved keyword, but it is a reserved class name, and handled by a different mechanism. const PRINT = 2;
> const YIELD = 3; > > function foo(Int $b) { > return PRINT + YIELD; > } > ``` >
Yes, this is the tradeoff :) We trade the ability to use reserved keywords in controlled situations, with potential confusion for cases like these. If it is important to allow to define classes, etc. with a keyword as name,
> I suggest to force the programmer to say explicitly “Yes, it is really what > I want”. For example, something like the following: > > ```php > class namespace\Int { } > > const namespace\PRINT = 2; > ``` >
This syntax doesn't make much sense to me. If we go down that line, I'd suggest something along the lines of Rust's "raw identifier" concept, which would allow you to write "const r#PRINT = 2" and "echo r#PRINT". This syntax would work everywhere identifiers are accepted, e.g. the "namespace iter\fn" would become "namespace iter\r#fn". The disadvantage of this approach is that it is not backwards compatible with PHP 7 and requires more active code change. E.g. the iter\fn example would "just work" under this RFC, while this approach would require rewriting the code. Nikita Another point which is problematic, is to allow `namespace` as a namespace
> parts, since `namespace\foo`, although interpreted as a namespace-relative > name, could be intended to be a qualified name by the programmer. > > —Claude > > > > > Le 16 juin 2020 à 10:52, Nikita Popov ppv@gmail.com> a écrit : > > Hi internals, > > Inspired by the recent discussion on reserved keyword reservation, I'd like > to propose the following RFC: > > https://wiki.php.net/rfc/namespaced_names_as_token > > This RFC makes two related changes: Treat namespaced names as a single > token, which enables use of reserved keywords inside them. And remove > reserved keyword restrictions from various declarations. > > The RFC comes with a small backwards compatibility break related to names > that include whitespace, but will hopefully reduce the backwards > compatibility impact of future reserved keyword additions. > > Regards, > Nikita > > >
  110710
June 23, 2020 17:45 claude.pache@gmail.com (Claude Pache)
> Le 16 juin 2020 à 10:52, Nikita Popov ppv@gmail.com> a écrit : > > Hi internals, > > Inspired by the recent discussion on reserved keyword reservation, I'd like > to propose the following RFC: > > https://wiki.php.net/rfc/namespaced_names_as_token > > This RFC makes two related changes: Treat namespaced names as a single > token, which enables use of reserved keywords inside them. And remove > reserved keyword restrictions from various declarations. > > The RFC comes with a small backwards compatibility break related to names > that include whitespace, but will hopefully reduce the backwards > compatibility impact of future reserved keyword additions. > > Regards, > Nikita
In fact, for classes and namespaces, we can probably do better, namely we can lift almost all keyword restriction, not only in definition and declaration, but also in in use. Indeed, bare names of class (and trait, interface, etc) and namespace can appear only in few, well-defined positions, where it cannot be confused with a keyword, namely: * after a handful of keywords: `new yield`, `class yield`, `instanceof yield`, `use yield`, `use foo as yield`, etc. * before a paamayim nekudotayim: `yield::$foo`, `yield::foo()`, `yield::FOO`; * before a backslash: `yield\foo`. As far as I can see, the only keywords that can legally appear in those positions (and therefore must remain unavailable) are: `namespace` (because of namespace-relative names: `namespace\foo`), and `class` (because of anonymous classes: `new class { }`. (As for functions and constants, I’m still thinking that it is not a good idea to allow to define or import a symbol that cannot be used. You will make the life of few library maintainers a little easier, but you will make the life of many users a little harder.) —Claude