rfc:never_for_parameter_types

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:never_for_parameter_types [2021/08/14 14:49] – fixing typo in section title jordanrlrfc:never_for_parameter_types [2021/08/24 11:53] (current) – Withdrawing jordanrl
Line 1: Line 1:
 ====== PHP RFC: Never For Parameter Types ====== ====== PHP RFC: Never For Parameter Types ======
-  * Version: 0.1+  * Version: 0.2
   * Date: 2021-08-14   * Date: 2021-08-14
   * Author: Jordan LeDoux, jordan.ledoux@gmail.com   * Author: Jordan LeDoux, jordan.ledoux@gmail.com
-  * Status: In Discussion+  * Status: Withdrawn
   * First Published at: http://wiki.php.net/rfc/never_for_parameter_types   * First Published at: http://wiki.php.net/rfc/never_for_parameter_types
  
 ===== Introduction ===== ===== Introduction =====
-Arguments in PHP are contravariant to preserve Liskov substitution. This means that if class B extends class A, then redefines a function call, the entire type of that argument from class A must be present in the type of the argument in class B:+Parameters in PHP are contravariant to preserve Liskov substitution. This means that if class B extends class A, then redefines a function call, the entire type of that parameter from class A must be present in the type of the parameter in class B:
  
 <code php> <code php>
Line 27: Line 27:
 </code> </code>
  
-Thus, the more specific a type is for an argument in a base class, the more broad it can be in an extending class with the requirement that it must also include the type from the base class.+Thus, the more specific a type is for an parameter in a base class, the more broad it can be in an extending class with the requirement that it must also include the type from the base class.
  
-Since ''never'' is a bottom type within the PHP engine, all other types contain it. This RFC proposes allowing ''never'' as a valid argument type for functions.+Since ''never'' is a bottom type within the PHP engine, all other types contain it. This RFC proposes allowing ''never'' as a valid parameter type for functions.
  
 ===== Use Cases ===== ===== Use Cases =====
  
 ==== Interfaces and Abstracts ==== ==== Interfaces and Abstracts ====
-With the ''never'' type available, interfaces and abstracts would be able to require that implementing classes provide a type without specifying any details about what that type must be. This would allow use cases such as the following:+With the ''never'' type available, interfaces and abstracts would be able to allow implementing classes to provide a type without specifying any details about what that type must be. This would allow use cases such as the following:
  
 <code php> <code php>
Line 46: Line 46:
 </code> </code>
  
-Implementers of the ''CollectionInterface'' could then specify any type they want, but failing to specify a type would result in a Fatal Error. Functions which use collections could then type against the interface, allowing any of the variously typed implementations to be provided.+Implementers of the ''CollectionInterface'' could then specify any type they want. Functions which use collections could then type against the interface, allowing any of the variously typed implementations to be provided, though additional docblocks would be required for static analysis as this feature does not actually solve the generics issue.
  
-In this way, allowing the never type for interfaces and abstracts could be a method of providing minimal support for generics while avoiding the challenges that providing generics represents. It would also not prevent or make it more difficult to provide full generics in the future.+In this way, allowing the never type for interfaces and abstracts could be a method of providing minimal stop-gap support for generics type behavior (covariant polymorphism) while avoiding the challenges that providing generics represents. It would also not prevent or make it more difficult to provide full generics in the future.
  
 Using never as a minimal form of generics in this way would require additional work, such as docblock information, for the static analysis to treat them as such, since this features is //not// generics. Using never as a minimal form of generics in this way would require additional work, such as docblock information, for the static analysis to treat them as such, since this features is //not// generics.
Line 54: Line 54:
 ==== Internal Classes and Interfaces ==== ==== Internal Classes and Interfaces ====
 Providing internal interfaces that require a type but do not specify which type can be very beneficial. This has been encountered recently with attempts to update ''ArrayAccess''. Providing internal interfaces that require a type but do not specify which type can be very beneficial. This has been encountered recently with attempts to update ''ArrayAccess''.
 +
 +<code php>
 +interface ArrayAccess {
 +
 +  public function offsetExists(never $offset): bool;
 +
 +  public function offsetGet(never $offset): mixed;
 +  
 +  public function offsetSet(never $offset, never $value): void;
 +  
 +  public function offsetUnset(never $offset): void;
 +
 +}
 +</code>
  
 Currently, internally provided interfaces that must provide flexible parameters for implementers specify the parameter as mixed, however as mixed is the top type in PHP it cannot be narrowed at all, and any code which implements the interface can not fully utilize the type system in place in PHP. Currently, internally provided interfaces that must provide flexible parameters for implementers specify the parameter as mixed, however as mixed is the top type in PHP it cannot be narrowed at all, and any code which implements the interface can not fully utilize the type system in place in PHP.
Line 77: Line 91:
 Allow the use of ''never'' as a type for arguments in interfaces and classes. This would have the following semantics: Allow the use of ''never'' as a type for arguments in interfaces and classes. This would have the following semantics:
  
-  * ''never'' cannot be used in an intersection type or union type. Any intersection would reduce to ''never'', and any union would reduce `neverout of the union, as ''never'' is the identity type of unions.+  * ''never'' cannot be used in an intersection type or union type. Any intersection would reduce to ''never'', and any union would reduce ''never'' out of the union, as ''never'' is the identity type of unions.
   * Attempting to call code directly that uses the ''never'' type for an argument would result in a ''TypeError'', as no zval will match this type.   * Attempting to call code directly that uses the ''never'' type for an argument would result in a ''TypeError'', as no zval will match this type.
-  * Omitting a type to imply ''mixed'' is not allowed when ''never'' is inherited as a type, though declaring ''mixed'' explicitly is. 
  
 This means that an interface or class could allow implementers and subclasses to declare a type for an argument without restricting that type to anything particular. This means that an interface or class could allow implementers and subclasses to declare a type for an argument without restricting that type to anything particular.
Line 87: Line 100:
  
 ===== Proposed PHP Version(s) ===== ===== Proposed PHP Version(s) =====
-This change is proposed for next PHP 8.x+This change is proposed for PHP 8.2
  
 ===== RFC Impact ===== ===== RFC Impact =====
Line 125: Line 138:
  
 ===== References ===== ===== References =====
-  * https://github.com/JordanRL/never-argument-type/edit/master/README.md+  * https://github.com/JordanRL/never-argument-type/blob/master/README.md
   * https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)   * https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)
   * https://en.wikipedia.org/wiki/Bottom_type   * https://en.wikipedia.org/wiki/Bottom_type
   * https://blog.logrocket.com/when-to-use-never-and-unknown-in-typescript-5e4d6c5799ad/   * https://blog.logrocket.com/when-to-use-never-and-unknown-in-typescript-5e4d6c5799ad/
 +  * https://externals.io/message/115712
 +
 +===== Changelog =====
 +
 +  * 0.1: Initial Proposal
 +  * 0.2: Removed explicit widening
rfc/never_for_parameter_types.1628952569.txt.gz · Last modified: 2021/08/14 14:49 by jordanrl