rfc:namespaced_names_as_token

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
rfc:namespaced_names_as_token [2020/06/15 15:16] – created nikicrfc:namespaced_names_as_token [2020/07/31 12:54] (current) nikic
Line 2: Line 2:
   * Date: 2020-06-15   * Date: 2020-06-15
   * Author: Nikita Popov <nikic@php.net>   * Author: Nikita Popov <nikic@php.net>
-  * Status: Draft+  * Status: Implemented
   * Target Version: PHP 8.0   * Target Version: PHP 8.0
-  * Implementation: https://github.com/php/php-src/pull/5720+  * Implementation: https://github.com/php/php-src/pull/5827
  
 ===== Introduction ===== ===== Introduction =====
  
-PHP currently treats namespaced names like ''Foo\Bar'' as a sequence of identifier and namespace separator tokens. This RFC proposed to treat namespaced names as a single token, an as such allow reserved keywords to appear inside them. At the same time, it proposes to lift reserved keyword restrictions for class, function and constant declarations.+PHP currently treats namespaced names like ''Foo\Bar'' as a sequence of identifiers and namespace separator tokens. This RFC proposes to treat namespaced names as a single token, and as such allow reserved keywords to appear inside them.
  
-The motivation is to reduce the backwards compatibility impact of new reserved keyword additions in future versions of PHP. To give a specific example, PHP 7.4 added the ''fn'' keyword as part of arrow function support. This broke my [[https://github.com/nikic/iter|iter library]], because it was using ''fn'' as part of a namespace name. However, this breakage was entirely unnecessary! Here is a typical usage example:+There are two motivations: The first is to reduce the backwards compatibility impact of new reserved keyword additions in future versions of PHP. To give a specific example, PHP 7.4 added the ''fn'' keyword as part of arrow function support. This broke my [[https://github.com/nikic/iter|iter library]], because it was using ''fn'' as part of a namespace name. However, this breakage was entirely unnecessary! Here is a typical usage example:
  
 <PHP> <PHP>
Line 26: Line 26:
 As you can see, both references of ''fn'' are part of a namespaced name: ''iter\fn'' and ''fn\operator''. Under this proposal, these are considered perfectly legal names, and the backwards compatibility break would not have occurred. As you can see, both references of ''fn'' are part of a namespaced name: ''iter\fn'' and ''fn\operator''. Under this proposal, these are considered perfectly legal names, and the backwards compatibility break would not have occurred.
  
-To provide another examplewhat would happen if ''enum'' become reserved keyword in a future PHP version? There are a number of userland implementations that use the ''Enum'' class name and would breakAfter this proposalthey would still break, but in a way that can be salvaged and migrated more easily:+Additionallytreating namespaced names as single token avoids certain syntactical ambiguitiesFor examplethe [[rfc:shorter_attribute_syntax|shorter attribute syntax]] has the following ambiguity:
  
 <PHP> <PHP>
-// This line would remain legal +function test(@@A B $param) {} 
-use MyCLabs\Enum\Enum; +// Can be interpreted as: 
- +function test( 
-// This line would still result in a parse error +   @@A\B 
-class Action extends Enum { } +   $param 
-</PHP> +{} 
- +// Or: 
-This means that code using the enum library will very likely break, but there are easy ways to avoid it, possibly by automated means: +function test( 
- +   @@A 
-<PHP> +   \B $param 
-class Action extends \MyCLabs\Enum\Enum { } +{}
-// or +
-use MyCLabs\Enum\Enum as Enum_; +
-class Action extends Enum_ { }+
 </PHP> </PHP>
  
-This makes it possible to keep code working until it is migrated.+This RFC resolves this by making the first variant a syntax error, and requiring you to write whichever interpretation was intended. This proposal is a prerequisite for the implementation of the "shorter attribute syntax" in PHP 8.
  
 ===== Proposal ===== ===== Proposal =====
Line 72: Line 69:
 // Before: T_NS_SEPARATOR T_STRING // Before: T_NS_SEPARATOR T_STRING
 // After:  T_NAME_FULLY_QUALIFIED // After:  T_NAME_FULLY_QUALIFIED
-// Rule:   {LABEL}("\\"{LABEL})*+// Rule:   ("\\"{LABEL})+
  
 namespace\Foo; namespace\Foo;
Line 83: Line 80:
  
 <PHP> <PHP>
-// This is interpreted as T_LIST and cannot be used as an identifier:+// This is interpreted as T_LIST (i.e., as a reserved keyword):
 List List
 // All of the following are interpreted as legal namespaced names: // All of the following are interpreted as legal namespaced names:
Line 91: Line 88:
 </PHP> </PHP>
  
-Whitespace is not permitted between namespace separators. If it occurs, the namespace separator will be parsed as ''T_NS_SEPARATOR'', which will subsequently lead to a parser error. It is not possible to allow whitespace, because namespaced names commonly occur next to keywords:+Whitespace is not permitted between namespace separators. If it occurs, the namespace separator will be parsed as ''T_NS_SEPARATOR'', which will subsequently lead to a parse error. It is not possible to allow whitespace, because namespaced names commonly occur next to keywords:
  
 <PHP> <PHP>
Line 106: Line 103:
  
 // This would have previously been interpreted as $foo = Foo\call($bar), // This would have previously been interpreted as $foo = Foo\call($bar),
-// now it will result in a parser error. +// now it will result in a parse error. 
-$foo = Foo+$foo = Foo // <- Missing semicolon
 \call($bar); \call($bar);
 </PHP> </PHP>
  
-In additional to the namespaced name changes, reserved keywords may now be used in a number of additional places:+In the interest of consistency, the ''namespace'' declaration will accept any name, including isolated reserved keywords:
  
 <PHP> <PHP>
-class KEYWORD {} +namespace iter\fn// Legal 
-interface KEYWORD {} +namespace fn     // Legal
-trait KEYWORD {} +
-function KEYWORD() {} +
-const KEYWORD = 0+
-use Foo as KEYWORD;+
 </PHP> </PHP>
  
-It should be emphasized that it will not be possible to refer to symbols that use keyword names by directly using the keyword, it always needs to be part of namespaced name that renders its usage unambigous:+This is to avoid a discrepancy where defining symbols like ''iter\fn\operator'' is allowed, but ''fn\operator'' is not. The only restriction is that the namespace name cannot start with ''namespace'' segment:
  
 <PHP> <PHP>
-class List {} +namespace namespace  // Illegal 
- +namespace namespace\x; // Illegal
-new List // Parse error. +
-new \List; // Ok!+
 </PHP> </PHP>
 +
 +This avoids introducing an ambiguity with namespace-relative names.
  
 ===== Backward Incompatible Changes ===== ===== Backward Incompatible Changes =====
Line 149: Line 142:
  
 As such, the practical impact is very limited, and any issues are trivial to fix. On the other hand, this change will reduce the backwards-compatibility impact from any future keyword additions. As such, the practical impact is very limited, and any issues are trivial to fix. On the other hand, this change will reduce the backwards-compatibility impact from any future keyword additions.
 +
 +Additionally tooling based on ''token_get_all()'' will need to be adjusted to handle the new ''T_NAME_*'' tokens. In practice, this will be the main negative impact of this proposal.
  
 ===== Vote ===== ===== Vote =====
  
-Yes/No.+Voting started 2020-07-17 and ends 2020-07-31. A 2/3 majority is required. 
 + 
 +<doodle title="Treat namespaced names as a single token?" auth="nikic" voteType="single" closed="true"> 
 +   * Yes 
 +   No 
 +</doodle> 
 + 
 +===== Future Scope ===== 
 + 
 +An earlier version of this RFC also relaxed various reserved keyword restrictions for class, function and constant declarations. Because these have to deal with more perceived ambiguities, I have dropped them from this proposal. Reserved keyword restrictions can always be lifted later on, while the change in this RFC contains a backwards-compatibility break that is best done in PHP 8.0.
  
rfc/namespaced_names_as_token.1592234192.txt.gz · Last modified: 2020/06/15 15:16 by nikic