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 12:55] – Fixed title... 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
 +  * actual language features are preserved:
 +    * a label (for goto) named //default// or //else// won't work ("default:" in switch or "else:" in alternative if structure)
 +    * a namespace named //namespace// won't work (a namespace name beginning with "namespace\" is a relative namespace name)
 +    * a class constant named //class// can't be defined ("classname::class" has a special meaning)
 +    * ...
  
-***** This includes all keywords except +An example what is possible with this patch:
-  * catch +
-  * finally +
-  * case +
-  * default +
-  * exit +
-  * else +
-  * elseif +
-  * endif +
-  * endwhile +
-  * endfor +
-  * endforeach +
-  * enddeclare +
-  * endswitch +
-It is necessary to exclude them due to limitations of bison/yacc grammar. +
 <code php> <code php>
-namespace Test {+namespace Class {
     class List {     class List {
         const default = 0;         const default = 0;
Line 57: Line 105:
    
 namespace { namespace {
-    \Test\List::echo((new Test\List)->new(array(1)));+    \Class\List::echo((new Class\List)->new(array(1)));
 } }
 +</code>
 +
 +==== Typehints ====
 +
 +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.
 +
 +===== 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> </code>
  
Line 76: 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.1379249752.txt.gz · Last modified: 2017/09/22 13:28 (external edit)