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.


Next revision
rfc:propertygetsetsyntax-alternative-typehinting-syntax [2013/01/04 14:16] – created nikic
Line 1: Line 1:
 +====== Request for Comments: Alternative typehinting syntax for accessors ======
 +  * Date: 2013-01-04
 +  * Author: Nikita Popov <nikic@php.net>
 +  * Status: Under Discussion
  
 +===== 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>
 +
 +===== 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.
 +
 +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 =====
 +
 +I haven't written a patch for this yet, but the change from the current syntax to this one is rather simple. The current accessors proposal will need special handling of the typehint in any case (it can't be handled as a normal method typehint). The proposed syntax would actually make the handling slightly simpler.
rfc/propertygetsetsyntax-alternative-typehinting-syntax.txt · Last modified: 2017/09/22 13:28 by 127.0.0.1