rfc:propertygetsetsyntax-alternative-typehinting-syntax
no way to compare when less than two revisions

Differences

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


Previous revision
Next revision
rfc:propertygetsetsyntax-alternative-typehinting-syntax [2013/01/21 17:58] – Start vote nikic
Line 1: Line 1:
 +====== Request for Comments: Alternative typehinting syntax for accessors ======
 +  * Date: 2013-01-04
 +  * Author: Nikita Popov <nikic@php.net>
 +  * Status: Voting
  
 +===== Introduction =====
 +
 +This RFC proposes a different typehinting syntax for the [[https://wiki.php.net/rfc/propertygetsetsyntax-v1.2|property accessors proposal]]. The proposed syntax places the typehint before the property name rather than in the ''set'' accessor's parameter declaration. This optimizes a common use of accessor properties and aligns the syntax with other languages. In particular it will allow to typehint properties without specifying accessors (''public DateTime $date;'').
 +
 +===== Current syntax(es) =====
 +
 +The current accessors RFC implements two syntax variations for accessors. The first is the original parentheses-less form using the magic ''$values'' variable:
 +
 +<code php>
 +private $seconds;
 +public $hours {
 +    get { return $this->seconds / 3600; }
 +    set { $this->seconds = $value * 3600; }
 +}
 +</code>
 +    
 +The newly added second syntax allows specifying the accessors in a more function-like form:
 +
 +<code php>
 +private $seconds;
 +public $hours {
 +    get() { return $this->seconds / 3600; }
 +    set($hours) { $this->seconds = $hours * 3600; }
 +}
 +</code>
 +
 +One of the reasons to add the latter syntax is to allow typehinting the setter. E.g. this allows to do something like the following:
 +
 +<code php>
 +public $date {
 +    get() { return $this->date; }
 +    set(DateTime $date) { $this->date = $date; }
 +}
 +</code>
 +    
 +The ''$date'' property implemented above behaves the same way as a normal property, but only allows to be assigned ''DateTime'' instances. Using automatic accessors it is possible to implement the same with a bit less boilerplate:
 +
 +<code php>
 +public $date {
 +    get;
 +    set(DateTime $date);
 +}
 +</code>
 +
 +===== Typehinting =====
 +
 +There is clear evidence that typehinting is of great importance to PHP developers. This doesn't only apply to ordinary methods, but also to accessors. An analysis of the Symfony 2.1 Standard Distribution ((The Symfony Standard Distribution is a collection of several large object-oriented projects written in PHP, as such I think it is a good representative to collect this kind of statistics)) has shown that about a third of all ''setXYZ()''-style methods are typehinted. About 15% of the setters are actually **only** typehinting and don't perform any other action than enforcing the typehint.
 +
 +Thus the main objective of this proposal is to improve the typehinting aspect of the accessors proposal.
 +
 +===== Proposed syntax =====
 +
 +This RFC proposes to change the current syntax for typehinted accessors...
 +
 +<code php>
 +public $date {
 +    get() { return $this->date; }
 +    set(DateTime $date) { $this->date = $date; }
 +}
 +</code>
 +
 +... by moving the typehint in front of the property name:
 +
 +<code php>
 +public DateTime $date {
 +    get { return $this->date; }
 +    set { $this->date = $value; }
 +}
 +</code>
 +    
 +Automatic accessors can be used to reduce the boilerplate:
 +
 +<code php>
 +public DateTime $date { get; set; }
 +</code>
 +    
 +Which again is equivalent to just the property with the typehint:
 +
 +<code php>
 +public DateTime $date;
 +</code>
 +
 +===== Default values and nullability =====
 +
 +When the shorthand ''public Type $name;'' syntax is used it will be possible to specify a default value (something that is not normally possible with accessors). The default value will use the same syntax and semantics as function parameter typehints. For example the following specifies an ''array'' property with an array default value:
 +
 +<code php>
 +public array $foo = [1, 2, 3];
 +</code>
 +
 +The nullability semantics are also the same as with parameter typehints:
 +
 +<code php>
 +public DateTime $date;        // can not assign null
 +public DateTime $date = null; // can assign null
 +</code>
 +
 +Note that properties are ''null'' initialized by default. The nullability semantics do not (and can not) affect this. They only specify whether it's possible to **assign** ''null'' to the property after initialization.
 +
 +Default values can only be used on the shorthand notation. If accessor methods are specified a default value can not be used. The only exception is the ''= null'' default, which can still be used to specify nullability:
 +
 +<code php>
 +public DateTime $date = null {
 +    get { ... } set { ... }
 +}
 +</code>
 +
 +===== Benefits of the proposed syntax =====
 +
 +The proposed syntax has several benefits over the current syntax, with the main one being that it **optimizes a very common use case** (while not making other use cases worse). As mentioned above about 15% of all accessor methods in Symfony would be able to use the ''public DateTime $date'' style shorthand notation. Furthermore this proposal allows a **default value** to be specified for typehinted properties.
 +
 +Even when the shorthand can not be used (because one actually defines some accessors) I would argue that the proposed syntax is more elegant than the current one, mainly because the **relevant API information is focused** at one point at the start of the declaration. For interacting with the class only the visibility and the typehint are of importance, whereas the actual implementation is irrelevant. The ''public DateTime $date { ... }'' syntax does a better job at conveying the relevant bits than the current syntax:
 +
 +<code php>
 +public $date { // <-- This is important
 +    get {
 +        // Some
 +        // Rather
 +        // Long
 +        // Code
 +    }
 +    set(DateTime $date) { // <-- And the typehint here is important, too
 +        // Some
 +        // Further
 +        // Code
 +        // Here
 +    }
 +}
 +</code>
 +
 +Another benefit I see in this typehint syntax is that most programmers are already **familiar** with it, because virtually every strongly typed language uses it. Most dynamic languages with support for optional typing that I know (like Dart or TypeScript) also use this syntax. This makes the syntax a lot more intuitive. If you want to typehint a property your first try will probably be putting the typename in front of it, rather than coming up with something like ''public $date { get; set(DateTime $date); }''. I think the latter syntax isn't particularly hard to understand *once you know it*, but it's not something that comes up intuitively.
 +
 +One last benefit that comes from this syntax is that we no longer need two ways to specify accessors (with and without parentheses). Though I also heard the opinion from some people that both syntaxes should be still kept to avoid the ''$value'' magic variable. I'd probably be okay either way, but I personally dislike it if there are two very similar ways to do one thing.
 +
 +===== Common Misconceptions =====
 +
 +When I brought this up last time the discussion showed some misconceptions regarding this proposal. This seems to be inherent to any discussion involving typehints in some way, so I decided to clear some things up beforehand.
 +
 +The important thing to realize is that this proposal does **not add new typehinting concepts** to PHP. It's just suggests a more general, more convenient and more familiar syntax for what already exists in the accessors proposal. The ''public DateTime $date;'' syntax is exactly equivalent to the following snippet using the current syntax:
 +
 +<code php>
 +public $date {
 +    get;
 +    set(DateTime $date);
 +}
 +</code>
 +
 +The last time I brought this up most of the discussion focused on the question whether typehints in PHP are a good idea in general and I would like to prevent this kind of discussion this time, as it is only tangentially related. Fact is that we do have typehints for methods and that those typehints are used a lot. Fact is that the typehints are also used a lot on accessors (30%) and often *just* for the typehint (15%). Fact also is that the accessors proposal makes the normal method typehints apply to properties. So the question really isn't whether typehints on properties are a good idea, the question is rather whether we want to have the convoluted ''public $date { get; set(DateTime $date); }'' syntax all over the code or the familiar and clearer ''public DateTime $date;'' syntax.
 +
 +I understand that some people on internals disapprove of typehints in general and that they have reasons to do so. I hope that those people will be able to consider this without prejudice and on its actual merits concerning the actual use of the language. Thanks.
 +
 +===== Patch =====
 +
 +The patch for this proposal is available here: https://gist.github.com/4579298. You can find the individual commits here: https://github.com/nikic/php-src/commits/alternativeSyntax.
 +
 +===== Voting =====
 +
 +This proposal depends on the main accessors RFC. The result of this vote is only relevant if the main RFC is accepted. As this is a language change it requires a 2/3 majority.
 +
 +<doodle title="Should the proposed typehinting syntax be used instead of the current one?" auth="nikic" voteType="single" closed="false">
 +   * Yes
 +   * No
 +</doodle>
rfc/propertygetsetsyntax-alternative-typehinting-syntax.txt · Last modified: 2017/09/22 13:28 by 127.0.0.1