rfc:class-like_primitive_types

Differences

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

Link to this comparison view

Next revision
Previous revision
Next revisionBoth sides next revision
rfc:class-like_primitive_types [2016/12/07 05:11] – incomplete draft ajfrfc:class-like_primitive_types [2016/12/19 22:00] ajf
Line 8: Line 8:
 ===== Background ===== ===== Background =====
  
-PHP has a small set of built-in types: null, Boolean, integer, float, string, array, object and resource. These types are known as “primitive” types, because they are built-in to the language. Of these, objects are special. Objects, themselves primitive type, are also instances of PHP's form of non-primitive, user-defined types: classes.+PHP has a small set of built-in types of value: null, Boolean, integer, float, string, array, object and resource. These types are known as “primitive” types, because they are built-in to the language. Of these, objects are special. Objects, themselves instances of the primitive type object, are also instances of PHP's form of non-primitive, user-defined types: classes.
  
-Classes and objects have evolved considerably since their introduction in PHP 3.0. As part of this evolutionthey have gained several features that are exclusive to them, which the other primitive types consequently cannot make use of. These features include instance and static methods, properties, class constants, interface implementation, inheritance, and <php>instanceof</php>.+Since their introduction in PHP 3.0, classes and objects have gained several features that are exclusive to them, which the other primitive types consequently cannot make use of. These features include instance and static methods, properties, class constants, interface implementation, inheritance, and <php>instanceof</php>.
  
-This set of exclusive features creates an awkward divide between PHP's objects and it'other primitive types. Various tasks must be done in different ways for objects versus other types, creating the need for workarounds to bridge the gap. For example, the [[rfc:iterable|iterable pseudo-type]] was introduced because objects can implement <php>Traversable</php>, yet the array type, not being a class, cannot.+This set of exclusive features creates an awkward divide between PHP's objects and its other primitive types. Various tasks must be done in different ways for objects versus other types, creating the need for workarounds to bridge the gap. For example, the [[rfc:iterable|iterable pseudo-type]] was introduced because objects can implement <php>Traversable</php>, yet the array type, not being a class, cannot.
  
-===== Introduction ===== +By contrast, some of PHP's contemporaries, like JavaScript and Python, make all their primitive types be classes. This brings uniformity, and also means primitive types can benefit from the convenience of method calls as compared to function calls. 
-The elevator pitch for the RFCThe first paragraph in this section will be slightly larger to give it emphasis; please write good introduction.+ 
 +There could be benefits to adopting the same approach in PHPHowever, as of PHP 5, PHP objects behave differently from the other primitive types, in that they are not value types, but rather reference types. This prevents making the other primitive types into objects, unless objects were changed to also support value type semantics. Even surmounting that hurdle, the PHP interpreter's internal representation of objects versus other primitive values is much less efficient, so replacing the primitive types with classes could significantly reduce performance. Moreover, changing the internal representation of the other primitive types in the PHP interpreter would be a massive undertaking. 
 + 
 +Hence, this RFC suggests different approach.
  
 ===== Proposal ===== ===== Proposal =====
-All the features and examples of the proposal. 
  
-To [[http://news.php.net/php.internals/66051|paraphrase Zeev Suraski]]explain hows the proposal brings substantial value to be considered +This RFC proposes to extend PHP's object-oriented features to the other primitive types. They would not become objects, and their internal representation would be unchanged. However, they would now benefit from most of the features of objects. 
-for inclusion in one of the world's most popular programming languages.+ 
 +==== Features extended to primitives ==== 
 + 
 +The following features of objects would now be extended to the other primitive types. 
 + 
 +=== Interfaces and inheritance === 
 + 
 +These types would now implement PHP's pre-defined interfaces as appropriate (see the class hierarchy further down for a list of which). 
 + 
 +These types would not be extendible by user classes, but could in future potentially extend new built-in abstract classes (e.g. <php>int</php> and <php>float</php> could extend <php>\Number</php>). 
 + 
 +Type declarations and <php>instanceof</php> would now accept values of these types as implementing these interfaces and extending these classesas appropriate. 
 + 
 +=== Instance methods and properties === 
 + 
 +These types will provide instance methods as necessary to conform to PHP's pre-defined interfaces (see the class hierarchy further down for a list of which). 
 + 
 +In future, they could provide other methods, or magic instance properties (see the future scope section). 
 + 
 +=== instanceof === 
 + 
 +The <php>instanceof</php> operator will now accept primitive values, rather than producing a fatal error. In addition, it will now support testing for membership of primitive types: 
 + 
 +  * <php>$x instanceof null</php> 
 +  * <php>$x instanceof bool</php> 
 +  * <php>$x instanceof int</php> 
 +  * <php>$x instanceof float</php> 
 +  * <php>$x instanceof string</php> 
 +  * <php>$x instanceof array</php> 
 +  * <php>$x instanceof object</php> 
 +  * <php>$x instanceof resource</php> (**FIXME:** should I omit this?) 
 + 
 +==== Features not extended to primitives ==== 
 + 
 +The following features would **not** now be extended to the other primitive types: 
 + 
 +  * <php>is_object()</php> will continue to return <php>FALSE</php> for the other primitive types 
 +  * <php>gettype()</php> will continue to report the other primitive types as non-objects 
 +  * <php>ArrayAccess</php> will not be implemented by <php>array</php>, because it provides mutating methods 
 +  * <php>null</php> has no shadow class (see the Open Issues section), but does support <php>instanceof null</php> 
 + 
 +**FIXME:** What do I do about reflection? 
 + 
 +=== Serializable and resources === 
 + 
 +The resource type will not implement the <php>Serializable</php> interface. Though the <php>serialize()</php> function accepts resources, it is broken: they serialise to an integer of the resource ID, and this integer, when deserialised, neither become a resource nor is usable as one. The <php>->deserialize()</php> method would therefore be redundant given resources cannot be deserialised, and the type would not be fulfilling the contract of the interface since resources do not meaningfully/ serialise. 
 + 
 +==== Primitive type class hierarchy ==== 
 + 
 +Behind each other primitive type, there would now be a hidden internal class, or //shadow class//. Attempts to call methods, look up properties, use <php>instanceof</php>, etc. on values of these types would consult these hidden internal classes. The following is an outline of these new classes. Note that the implementations of <php>JsonSerializable</php> would only be present when the JSON extension is loaded.
  
-Remember that the RFC contents should be easily reusable in the PHP Documentation.+<code php> 
 +/* There is no shadow class for null */
  
-If applicableyou may wish to use the language specification as a reference.+final class bool implements SerializableJsonSerializable { 
 +    public function __toString() { /* ... */ } 
 +    public function serialize() { /* ... */ } 
 +    public function unserialize($serialized) { /* ... */ } 
 +    public function jsonSerialize() { /* ... */ } 
 +
 +final class int implements Serializable, JsonSerializable { 
 +    public function __toString() { /* ... */ } 
 +    public function serialize() { /* ... */ } 
 +    public function unserialize($serialized) { /* ... */ } 
 +    public function jsonSerialize() { /* ... */ } 
 +
 +final class float implements Serializable, JsonSerializable { 
 +    public function __toString() { /* ... */ } 
 +    public function serialize() { /* ... */ } 
 +    public function unserialize($serialized) { /* ... */ } 
 +    public function jsonSerialize() { /* ... */ } 
 +
 +final class string implements Serializable, JsonSerializable { 
 +    public function __toString() { /* ... */ } 
 +    public function serialize() { /* ... */ } 
 +    public function unserialize($serialized) { /* ... */ } 
 +    public function jsonSerialize() { /* ... */ } 
 +
 +final class array implements Serializable, JsonSerializable, Countable, IteratorAggregate { 
 +    public function __toString() { /* ... */ } 
 +    public function serialize() { /* ... */ } 
 +    public function unserialize($serialized) { /* ... */ } 
 +    public function jsonSerialize() { /* ... */ } 
 +    public function count() { /* ... */ } 
 +    public function getIterator() { 
 +        return new ArrayIterator($this); 
 +    } 
 +
 +final class resource { 
 +    public function __toString() { /* ... */ } 
 +
 +</code>
  
 ===== Backward Incompatible Changes ===== ===== Backward Incompatible Changes =====
-What breaksand what is the justification for it?+ 
 +In order to support the <php>instanceof resource</php> syntax<php>resource</php> must be added to the list of reserved names that cannot be used by classes, interfaces or traits. Otherwise, there would be an ambiguity as to whether this referred to a hypothetical class with the same name, or to the type. This backwards-compatibility break could be avoided by removing support for the resource type (see the Open Issues section). 
 + 
 +**FIXME** 
  
 ===== Proposed PHP Version(s) ===== ===== Proposed PHP Version(s) =====
-List the proposed PHP versions that the feature will be included in.  Use relative versions such as "next PHP 7.x" or "next PHP 7.x.y".+ 
 +This is proposed for the next PHP 7.x. Currently, that would be PHP 7.2.
  
 ===== RFC Impact ===== ===== RFC Impact =====
 ==== To SAPIs ==== ==== To SAPIs ====
-Describe the impact to CLI, Development web server, embedded PHP etc.+ 
 +This has no particular special impact on the SAPIs.
  
 ==== To Existing Extensions ==== ==== To Existing Extensions ====
-Will existing extensions be affected? 
  
-==== To Opcache ==== +This does not impact existing extensions: their view of the world is unchanged and the primitive types other than objects are still not objectsinternally.
-It is necessary to develop RFC's with opcache in mindsince opcache is a core extension distributed with PHP.+
  
-Please explain how you have verified your RFC's compatibility with opcache.+**FIXME:** Reflection.
  
-==== New Constants ==== +==== To Opcache ====
-Describe any new constants so they can be accurately and comprehensively explained in the PHP documentation.+
  
-==== php.ini Defaults ==== +**FIXME**.
-If there are any php.ini settings then list: +
-  hardcoded default values +
-  php.ini-development values +
-  php.ini-production values+
  
 ===== Open Issues ===== ===== Open Issues =====
-Make sure there are no open issues when the vote starts!+ 
 +**FIXME:** Reflection, Opcache. 
 + 
 +==== Should null have a shadow class? ==== 
 + 
 +Or in other words, should these features be extended to <php>null</php>? 
 + 
 +<php>null</php> is a value and type representing the absence of a value. It is a special case among the scalar types, lacking its own type declaration and not being coerced in weak type checking. 
 + 
 +Would methods like <php>__toString()</php> on <php>null</php> values be more likely to be called in error than intentionally? 
 + 
 +In JavaScript, ''null'' does not have any properties or methods, but ''true'' and ''false'' do. In contrast, Python's ''None'' (its equivalent to null) //does// have properties and methods, albeit only magic methods. 
 + 
 +This RFC currently chooses to omit null from support by most of these features. 
 + 
 +==== Should resource be supported? ==== 
 + 
 +Resource is a legacy type that could be wholly replaced by objects in future. Extending these features to this type would be further entrenching it and contrary to the goal of its eventual removal. 
 + 
 +Beyond that, supporting <php>instanceof resource</php> would require adding ''resource'' to the list of reserved class names (the other types are already on it), and therefore entail a backwards-compatibility break. Omitting support for resources would avoid this backwards-compatibility break.
  
 ===== Unaffected PHP Functionality ===== ===== Unaffected PHP Functionality =====
-List existing areas/features of PHP that will not be changed by the RFC. 
  
-This helps avoid any ambiguity, shows that you have thought deeply about the RFC's impact, and helps reduces mail list noise.+**FIXME**
  
 ===== Future Scope ===== ===== Future Scope =====
-This sections details areas where the feature might be improved in futurebut that are not currently proposed in this RFC.+ 
 +The extension of these features to the other primitive types opens up a number of future possibilities. 
 + 
 +One of these would be [[http://nikic.github.io/2014/03/14/Methods-on-primitive-types-in-PHP.html|methods on the other primitive types]] (and also properties). This could make string and array manipulation more convenientand additionally provides an opportunity for a fresh start versus the old standard string and array functions, which have notoriously inconsistent naming and parameter orders. 
 + 
 +It also means we can easily introduce new superclasses of our other primitive types. For example, a new <php>\Number</php> type superclassing <php>int</php> and <php>float</php>, or a new <php>\Scalar</php> type superclassing everything except objects and arrays.
  
 ===== Proposed Voting Choices ===== ===== Proposed Voting Choices =====
-Include these so readers know where you are heading and can discuss the proposed voting options. 
  
-State whether this project requires a 2/3 or 50%+1 majority (see [[voting]])+This is a major language change, so it would require a 2/3 majority
 + 
 +It would be a Yes/No vote on whether to accept the RFC.
  
 ===== Patches and Tests ===== ===== Patches and Tests =====
-Links to any external patches and tests go here. 
  
-If there is no patch, make it clear who will create a patch, or whether a volunteer to help with implementation is needed.+There is no interpreter patch at present. **FIXME**.
  
-Make it clear if the patch is intended to be the final patch, or is just a prototype. +There is no language specification patch at present**FIXME**
- +
-For changes affecting the core language, you should also provide a patch for the language specification.+
  
 ===== Implementation ===== ===== Implementation =====
Line 87: Line 195:
  
 ===== References ===== ===== References =====
-Links to external references, discussions or RFCs+ 
 +**FIXME**
  
 ===== Rejected Features ===== ===== Rejected Features =====
-Keep this updated with features that were discussed on the mail lists.+ 
 +None yet.
rfc/class-like_primitive_types.txt · Last modified: 2017/09/22 13:28 by 127.0.0.1