rfc:scalar_type_hints

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:scalar_type_hints [2015/02/01 23:49] ajfrfc:scalar_type_hints [2017/09/22 13:28] (current) – external edit 127.0.0.1
Line 1: Line 1:
 ====== PHP RFC: Scalar Type Hints ====== ====== PHP RFC: Scalar Type Hints ======
-  * Version: 0.3 +  * Version: 0.3.1 
-  * Date: 2014-12-14 (initial draft; put Under Discussion 2014-12-31; version 0.2 created 2015-01-13)+  * Date: 2014-12-14 (initial draft; put Under Discussion 2014-12-31; version 0.2 created 2015-01-13; withdrawn 2015-02-15)
   * Author: Andrea Faulds, ajf@ajf.me   * Author: Andrea Faulds, ajf@ajf.me
-  * Status: Under Discussion+  * Status: Withdrawn
   * First Published at: http://wiki.php.net/rfc/scalar_type_hints   * First Published at: http://wiki.php.net/rfc/scalar_type_hints
  
Line 87: Line 87:
 </file> </file>
  
-The strict type checking mode also affects extension and built-in PHP functions:+The directive affects all function calls in the file (or ''declare()'' block if specified), regardless of whether the functions being called were declared in files which used strict type checking. So: 
 + 
 +<file php strict_mix.php> 
 +<?php 
 +require "ElePHPant.php"; 
 + 
 +// implicitly weakly type-checked code (default) 
 +$nelly = new ElePHPant(12345, "7 years", "0.9", "1"); // succeeds 
 + 
 +declare(strict_types=1) { 
 +    // explicitly strictly type-checked code 
 +     
 +    $nelly = new ElePHPant(12345, "7 years", "0.9", "1"); 
 +    // Catchable fatal error: Argument 1 passed to ElePHPant::__construct() must be of the type string, integer given 
 +
 +</file> 
 + 
 +This applies equally to nested function calls, which also use the strictness setting of the file: 
 + 
 +<file php strict_mix2.php> 
 +<?php 
 +require "ElePHPant.php"; 
 + 
 +// implicitly weakly type-checked code (default) 
 +function makeEllie() { 
 +    return new ElePHPant(42, "19", "0.7", 1); // will succeed, no matter where makeEllie() is called from 
 +
 + 
 +makeEllie(); // no error 
 + 
 +declare(strict_types=1) { 
 +    // explicitly strictly type-checked code 
 + 
 +    makeEllie(); // no error 
 +     
 +    function makeEllie_strict() { 
 +        return new ElePHPant(42, "19", "0.7", 1); // will fail, no matter where makeEllie_strict() is called from 
 +    } 
 + 
 +    makeEllie_strict(); // error 
 +
 + 
 +// implicitly weakly type-checked code, again 
 + 
 +makeEllie_strict(); // error 
 +</file> 
 + 
 +In addition to userland functions, the strict type checking mode also affects extension and built-in PHP functions:
  
 <file php main4.php> <file php main4.php>
Line 98: Line 145:
 </file> </file>
  
-Scalar type hints would also work for return values:+Scalar type hints would also work for return values, as does strict type checking mode:
  
 <file php returns.php> <file php returns.php>
Line 108: Line 155:
  
 var_dump(foobar()); // int(1) var_dump(foobar()); // int(1)
 +
 +declare(strict_types=1) {
 +    function foobar2(): int {
 +        return 1.0;
 +    }
 +}
 +
 +var_dump(foobar2());
 +// Catchable fatal error: Return value of foobar() must be of the type integer, float returned
 </file> </file>
  
-And strict type checking mode works for return values, too:+However, there is a key difference between parameter and return type hints. The type-checking mode used for parameters is the one used by the file containing the function call, while the type-checking mode used for return values is the one used by the file containing the return statement (i.e. the file defining the function). So:
  
-<file php returns2.php>+<file php returns.php>
 <?php <?php
  
 declare(strict_types=1) { declare(strict_types=1) {
-    function foobar(): int { +    function foobar3(): int { 
-        return 1.0;+        return 1.0; // error, regardless of where it is called from
     }     }
 +
 +    foobar3(); // error
 } }
  
-var_dump(foobar()); +foobar3(); // also error
-// Catchable fatal error: Return value of foobar() must be of the type integer, float returned+
 </file> </file>
- 
-However, there is a key difference between parameter and return type hints. The type-checking mode used for parameters is the one used by the file containing the function call, while the type-checking mode used for return values is the one used by the file containing the return statement (i.e. the file defining the function). 
  
 ===== Background and Rationale ===== ===== Background and Rationale =====
Line 131: Line 186:
 ==== History ==== ==== History ====
  
-PHP has had parameter type hints for class names since PHP 5.0, arrays since PHP 5.1 and callables since PHP 5.4. These type hints allow the PHP runtime to ensure that correctly-typed arguments are passed to functions, and make function signatures more informative. Unfortunately, PHP's scalar types haven't been hintable.+PHP has had parameter type hints for interface and class names since PHP 5.0, arrays since PHP 5.1 and callables since PHP 5.4. These type hints allow the PHP runtime to ensure that correctly-typed arguments are passed to functions, and make function signatures more informative. Unfortunately, PHP's scalar types haven't been hintable.
  
 There have been some previous attempts at adding scalar type hints, such as the [[rfc:scalar_type_hinting_with_cast|Scalar Type Hints with Casts]] RFC. From what I can see, that specific RFC failed primarily for three reasons: There have been some previous attempts at adding scalar type hints, such as the [[rfc:scalar_type_hinting_with_cast|Scalar Type Hints with Casts]] RFC. From what I can see, that specific RFC failed primarily for three reasons:
Line 344: Line 399:
 This doesn't affect the behaviour of cast operators. This doesn't affect the behaviour of cast operators.
  
-When the strict type-checking mode isn't in use (which is the default), function calls behave identically to previous PHP versions.+When the strict type-checking mode isn't in use (which is the default), function calls to built-in and extension PHP functions behave identically to previous PHP versions.
  
 ===== Open Issues ===== ===== Open Issues =====
  
-There is currently an open issue related to naming, described below. This will probably go to a vote.+There is currently an open issue related to naming, described below. This will go to a vote.
  
 This RFC and patch allows the aliases ''integer'' and ''boolean'' in addition to ''int'' and ''bool''. Should we only allow ''int'' and ''bool''? It is probably not a good idea to add too many new reserved class names. On the other hand, we use ''integer'' and ''boolean'' in many places in the manual, and programmers would be forgiven for expecting ''integer'' and ''boolean'' to work. We could opt to reserve them but prevent their use, telling people to use ''int'' and ''bool'' instead. That wouldn't reduce the number of prohibited class names, but it would prevent confusion and ensure consistency. This RFC and patch allows the aliases ''integer'' and ''boolean'' in addition to ''int'' and ''bool''. Should we only allow ''int'' and ''bool''? It is probably not a good idea to add too many new reserved class names. On the other hand, we use ''integer'' and ''boolean'' in many places in the manual, and programmers would be forgiven for expecting ''integer'' and ''boolean'' to work. We could opt to reserve them but prevent their use, telling people to use ''int'' and ''bool'' instead. That wouldn't reduce the number of prohibited class names, but it would prevent confusion and ensure consistency.
Line 355: Line 410:
  
   * Produce a different error message on strict type hint failure vs. on weak type hint failure, lest debugging be a pain. For practical reasons we may not be able to change the weak one, as it is an existing message (should we?).   * Produce a different error message on strict type hint failure vs. on weak type hint failure, lest debugging be a pain. For practical reasons we may not be able to change the weak one, as it is an existing message (should we?).
-  * Return types need tests.+  * Return types need more tests.
  
 ===== Future Scope ===== ===== Future Scope =====
Line 361: Line 416:
 Because scalar type hints guarantee that a passed argument will be of a certain type within a function body (at least initially), this could be used in the Zend Engine for optimisations. For example, if a function takes two ''float''-hinted arguments and does arithmetic with them, there is no need for the arithmetic operators to check the types of their operands. As I understand it, HHVM already does such optimisations, and might benefit from this RFC. Because scalar type hints guarantee that a passed argument will be of a certain type within a function body (at least initially), this could be used in the Zend Engine for optimisations. For example, if a function takes two ''float''-hinted arguments and does arithmetic with them, there is no need for the arithmetic operators to check the types of their operands. As I understand it, HHVM already does such optimisations, and might benefit from this RFC.
  
-===== Proposed Voting Choices =====+In discussions around this RFC, the ''declare(strict_types=1);'' syntax has been controversial. It is arguably rather ugly, and it has all the scoping quirks of ''declare()''. I've now arrived at a point where I'm willing to change to a truly per-file syntax, ''<?php strict'' (or similar). However, the RFC is currently being voted on, and I'd rather not cancel the vote. So, this will be proposed in a subsequent RFC. 
 + 
 +Another issue that came up is PHP's lack of a typehint for numbers (which also came up with the previous Scalar Type Hinting with Cast RFC). I plan to propose a ''numeric'' typehint in a future RFC which would take either an integer or a float. 
 + 
 +===== Vote ===== 
 + 
 +As this is a language change, this RFC requires a 2/3 majority to pass. Voting for all three votes started on 2015-02-05 and all were to end on 2015-02-19, but the voting was cancelled and the RFC withdrawn on 2015-02-15. 
 + 
 +==== Main ==== 
 + 
 +This vote is for the RFC itself. 
 + 
 +<doodle title="Accept the Scalar Type Hints RFC and merge patch into master?" auth="ajf" voteType="single" closed="true"> 
 +   * Yes 
 +   * No 
 +</doodle> 
 + 
 +==== Type aliases ==== 
 + 
 +This second vote is to solve the open issue regarding the ''integer'' and ''boolean'' synonyms for ''int'' and ''bool''. Whichever option receives the most votes will be implemented. 
 + 
 +<doodle title="Type aliases" auth="ajf" voteType="single" closed="true"> 
 +   * Allow synonyms 
 +   * Reserve synonyms and produce error message when used 
 +   * Do not reserve 
 +</doodle> 
 + 
 +===Reserve for future use ==== 
 + 
 +This final vote is in case the RFC fails to pass. It's a 2/3 majority-required backwards compatibility-breaking language change, which is to reserve the type hint names proposed by the RFC, so that a future RFC could implement scalar type hints without requiring a backwards compatibility break. The type names reserved include the synonyms ''integer'' and ''boolean''. They would not be reserved words, merely prohibited from use as class/interface/trait names, like this RFC's type names.
  
-As this is a language change, this RFC requires a 2/3 majority to pass. It will be a Yes/No vote.+<doodle title="Reserve type names if RFC does not pass?" auth="ajf" voteType="single" closed="true"> 
 +   Yes 
 +   * No 
 +</doodle>
  
 ===== Patches and Tests ===== ===== Patches and Tests =====
  
-There is a working, but incomplete php-src pull request with tests for parameter type hints (but not yet return type hints) here: https://github.com/php/php-src/pull/998 +There is a working, but possibly buggy php-src pull request with tests here: https://github.com/php/php-src/pull/998 
  
-There is no language specification patch.+There is no language specification patch as yet.
  
 ===== Implementation ===== ===== Implementation =====
Line 383: Line 470:
 ===== Changelog ===== ===== Changelog =====
  
 +  * v0.3.1 - Noted ''numeric'' and syntax change in Future Scope
   * v0.3 - Return types support   * v0.3 - Return types support
   * v0.2.3 - ''strict_types=1'' rather than ''strict_typehints=TRUE''   * v0.2.3 - ''strict_types=1'' rather than ''strict_typehints=TRUE''
rfc/scalar_type_hints.1422834563.txt.gz · Last modified: 2017/09/22 13:28 (external edit)