rfc:keywords_as_identifiers

Differences

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

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
rfc:keywords_as_identifiers [2013/09/15 14:17] – [Proposal] + some comment on typehints bwoebirfc:keywords_as_identifiers [2017/09/22 13:28] (current) – external edit 127.0.0.1
Line 1: Line 1:
 ====== PHP RFC: Extended keyword support ====== ====== PHP RFC: Extended keyword support ======
-  * Version: 1.0+  * Version: 1.2
   * Date: 2013-09-14   * Date: 2013-09-14
   * Author: Bob Weinand, bobwei9@hotmail.com   * Author: Bob Weinand, bobwei9@hotmail.com
-  * Status: Under Discussion+  * Status: Declined 
 +    * The implementation was creating too much need for maintenance etc. Don't duplicate that proposal without a better implementation.
   * First Published at: http://wiki.php.net/rfc/keywords_as_identifiers   * First Published at: http://wiki.php.net/rfc/keywords_as_identifiers
  
 ===== Introduction ===== ===== Introduction =====
  
-This RFC aims to remove some restrictions which are due to the fact that keywords are not included in T_STRING.+This RFC aims to remove some restrictions which are due to the fact that keywords are not included in T_STRING (especially for class const, method and class names).
  
-===== Proposal =====+This especially could be useful to preserve more BC compatibility whenever new keywords are introduced.  
 + 
 +===== What is now possible ===== 
 + 
 +  * One might want to define an HTTP agent class. And would like to store some HTTP status constants: 
 +<code php> 
 +class HTTP { 
 +    const CONTINUE = 100; // Works with patch 
 +// But currently this fails with a parse error, because continue is a keyword. 
 +    const SWITCHING_PROTOCOLS = 101; 
 +    // etc. ... 
 +
 +</code> 
 +  * Building conditions with "and" or "or" methods 
 +<code php> 
 +class Cond { 
 +    public static function and (...) { // using an "and" or "or" as name currently fails 
 +        // some logic here 
 +        return $andCondition; 
 +    } 
 + 
 +    public static function or (...) { 
 +        // some logic here 
 +        return $orCondition; 
 +    } 
 +
 + 
 +Cond::and($cond1, $cond2); 
 +</code> 
 +  * Prevents unnecessary use of _****_call magic method ("-****>keyword_name_for_non_static_method()" works, but "public function keyword_name_for_non_static_method() {}" currently fails) 
 +<code php> 
 +// Ugly, current code 
 +class SomeClass { 
 +    private $list = []; 
 + 
 +    public function _list () { 
 +        return $this->list; 
 +    } 
 + 
 +    public function __call ($func, $args) { 
 +        if (method_exists($this, "_".$func)) { 
 +            return call_user_func_array("_".$func, $args); // or some similar thing, if not underscores etc.... 
 +        } 
 +        // some error handling here 
 +    } 
 +
 + 
 +// How we could write it with the patch 
 +class SomeClass { 
 +    private $list = []; 
 + 
 +    public function list () { 
 +        return $this->list; 
 +    } 
 +
 +</code> 
 + 
 +===== Details of proposal =====
  
 Concretely this patch enables: Concretely this patch enables:
Line 17: Line 75:
     * class constant names     * class constant names
     * declare directive names     * declare directive names
-  * a limited set of keywords ***** for 
     * class names     * class names
     * trait names     * trait names
     * interface names     * interface names
     * goto label names     * goto label names
- +    namespace names 
-****This includes all keywords except +  * actual language features are preserved: 
-  * catch +    a label (for goto) named //default// or //else// won't work ("default:" in switch or "else:" in alternative if structure) 
-  * finally +    a namespace named //namespace// won't work (a namespace name beginning with "namespace\" is a relative namespace name) 
-  * case +    a class constant named //class// can't be defined ("classname::class" has a special meaning) 
-  * default +    ...
-  * exit +
-  * else +
-  elseif +
-  endif +
-  endwhile +
-  * endfor +
-  * endforeach +
-  * enddeclare +
-  * endswitch +
-It is necessary to exclude them due to limitations of bison/yacc grammar.+
  
 An example what is possible with this patch: An example what is possible with this patch:
 <code php> <code php>
-namespace Test {+namespace Class {
     class List {     class List {
         const default = 0;         const default = 0;
Line 58: Line 105:
    
 namespace { namespace {
-    \Test\List::echo((new Test\List)->new(array(1)));+    \Class\List::echo((new Class\List)->new(array(1)));
 } }
 </code> </code>
Line 66: Line 113:
 Currently when using array or callable as typehint, the old behaviour is preferred over comparing if it's a class/interface named array or callable. Currently when using array or callable as typehint, the old behaviour is preferred over comparing if it's a class/interface named array or callable.
 I'm not sure if we should just allow both in this special case. I'm not sure if we should just allow both in this special case.
 +
 +===== Implementation =====
 +
 +The transformation of alphabetic tokens to a T_STRING is done in lexer (post-processing output of lexer).
 +
 +Initially it was done in parser, but that had a few disadvantages:
 +  * more restricted support for keywords
 +  * output of token_get_all() and highlight_*() functions was still using the unconverted tokens
 +
 +That is also why performance is affected, as it is some code which needs to be run on every token.
 +
 +===== Impact on performance =====
 +
 +There is a slight decrease in //compilation performance// of up to 10% in worst case. So, actually, when used with opcache (execution only), any impact shouldn't be noticeable.
 +
 +For that benchmark I used an 1.5 megabyte big file wrapped in an //if (false)// (so that nothing is executed): https://raw.github.com/nikic/PHP-Parser/master/lib/PHPParser/Parser.php
 +
 +Compare actual run time:
 +<code>
 +time ./sapi/cli/php -r 'for($i=0;$i++<5000;)require "Parser.php";'
 +real 0m33.132s
 +user 0m32.816s
 +sys 0m0.313s
 +</code>
 +To run time with patch applied:
 +<code>
 +time ./sapi/cli/php -r 'for($i=0;$i++<5000;)require "Parser.php";'
 +real 0m36.720s
 +user 0m36.400s
 +sys 0m0.316s
 +</code>
 +
 ===== Proposed PHP Version(s) ===== ===== Proposed PHP Version(s) =====
  
Line 81: Line 160:
 ===== Rejected Features ===== ===== Rejected Features =====
  
-  * Initially the patch contained also some support for functions, namespaces and constants which was removed later due to some resulting syntactic inconsistencies+  * Initially the patch contained also some support for functions and constants which was removed later due to some resulting syntactic inconsistencies 
 + 
 +===== Vote ===== 
 + 
 +<doodle title="Should the extended keyword support patch be merged into master?" auth="bwoebi" voteType="single" closed="true"> 
 +   * Yes 
 +   * No 
 +</doodle> 
 + 
 +Deadline was Monday, 28th october 2013. 
 +===== Versions ===== 
 +  * 1.0: Initial proposal (16.9.2013) 
 +  * 1.1: Added some more examples (18.9.2013) 
 +  * 1.2: Removed some restrictions (now all keywords are permitted except the ones which would conflict with the existing language) (16.10.2013)
rfc/keywords_as_identifiers.1379254626.txt.gz · Last modified: 2017/09/22 13:28 (external edit)