rfc:shorter_attribute_syntax

Differences

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

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
Last revision Both sides next revision
rfc:shorter_attribute_syntax [2020/06/15 20:31]
theodorejb Add link to community poll
rfc:shorter_attribute_syntax [2020/08/02 22:13]
theodorejb Change status to implemented
Line 2: Line 2:
   * Date: 2020-06-03   * Date: 2020-06-03
   * Author: Theodore Brown <theodorejb@outlook.com>, Martin Schröder   * Author: Theodore Brown <theodorejb@outlook.com>, Martin Schröder
-  * Status: Under Discussion+  * Status: Implemented
   * Discussion: https://externals.io/message/110355   * Discussion: https://externals.io/message/110355
   * Target Version: PHP 8.0   * Target Version: PHP 8.0
-  * Implementation for ''@@''Based on https://github.com/kooldev/php-src/pull/2 (requires a single character to be changed in the lexer and a small grammar adjustment) +  * Implementation: https://github.com/php/php-src/pull/5796
-  * Implementation for ''#[]'': https://github.com/koolkode/php-src/pull/5+
  
 ===== Introduction ===== ===== Introduction =====
Line 161: Line 160:
 $f2 = @@ExampleAttribute fn() => 1; $f2 = @@ExampleAttribute fn() => 1;
 </code> </code>
 +
 +
 +===== Alternative #[] syntax =====
 +
 +An alternative to using ''@@Attr'' would be to borrow the ''#[attr]'' syntax from Rust. This would have the benefit of reusing the same syntax as another language, and it is also potentially forwards compatible for single-line attributes. E.g. the following code could work with both PHP 7 and PHP 8 (the attribute is treated as a comment on PHP 7):
 +
 +<code php>
 +#[Attribute]
 +final class Covers {}
 +</code>
 +
 +So with this syntax, in theory it would be possible for a library to support both native PHP 8 attributes and PHP 7 docblock annotations with the same code. E.g. PHPUnit could introduce a ''Covers'' attribute class which would also work in PHP 7 to encapsulate information from an ''@covers'' docblock annotation.
 +
 +However, this benefit would be lost as soon as a library wants to depend on any other PHP 8 features, and it will become irrelevant anyway once most users upgrade to PHP 8. With the ''@@'' syntax, libraries can still support both native attributes and docblock annotations, they just would need to use a different class (or a parent class) to encapsulate the docblock arguments on PHP 7.x.
 +
 +==== Downsides ====
 +
 +  * Larger BC break than ''@@'' (see Backward Incompatible Changes section below).
 +  * Slightly more verbose than ''@@'', which works against one of the goals of this RFC.
 +  * Arguably more difficult to type than ''@@'' on common qwerty keyboard layouts.
 +  * Syntax may be confusing for some, since it looks more like a comment than the existing docblock annotations developers are familiar with.
 +
 +==== Additional examples with #[] ====
 +
 +Note: JavaScript syntax highlighting is used so ''#'' doesn't appear as a comment.
 +
 +<code ecmascript>
 +#[Jit]
 +function foo() {}
 +
 +class Foo
 +{
 +    #[ExampleAttribute]
 +    public const FOO = 'foo';
 +
 +    // with potential nesting in future
 +    #[JoinTable(
 +        "User_Group",
 +        #JoinColumn("User_id", "id"),
 +        #JoinColumn("Group_id", "id"),
 +    )]
 +    private $groups;
 +
 +    #[ExampleAttribute]
 +    public function foo(#[ExampleAttribute] Type $bar) {}
 +}
 +
 +$object = new #[ExampleAttribute] class () {};
 +
 +$f1 = #[ExampleAttribute] function () {};
 +
 +$f2 = #[ExampleAttribute] fn() => 1;
 +</code>
 +
  
 ===== Discussion ===== ===== Discussion =====
Line 180: Line 233:
 <code php> <code php>
 function foo( function foo(
-    <<MyAttr("val")>> Type $myParam,+    <<MyAttr([1, 2])>> Type $myParam,
 ) {} ) {}
  
Line 186: Line 239:
  
 function foo( function foo(
-    @@MyAttr("val") Type $myParam,+    @@MyAttr([1, 2]Type $myParam, 
 +) {} 
 + 
 +// vs. 
 + 
 +function foo( 
 +    #[MyAttr([1, 2])] Type $myParam,
 ) {} ) {}
 </code> </code>
Line 203: Line 262:
 ==== Isn't the syntax choice just something subjective we'll get used to? ==== ==== Isn't the syntax choice just something subjective we'll get used to? ====
  
-To some extent this may be true. However, in this case we believe there are also objective reasons to prefer the shorter syntax, which this RFC attempts to outline.+To some extent this may be true. However, in this case we believe there are also objective shortcomings with using ''%%<<>>%%'' for attributes, which we have the opportunity to solve with a shorter syntax.
  
  
-===== Comparison to other languages =====+===== Comparison to Other Languages =====
  
 Most other languages with attributes use a variant of ''[Attr]'' or ''@Attr'' for the syntax. Hack is the only language using ''%%<<Attr>>%%'', but apparently they are migrating away from this to ''@Attr'' now that compatibility with PHP is no longer a goal. Most other languages with attributes use a variant of ''[Attr]'' or ''@Attr'' for the syntax. Hack is the only language using ''%%<<Attr>>%%'', but apparently they are migrating away from this to ''@Attr'' now that compatibility with PHP is no longer a goal.
Line 219: Line 278:
   * Swift: ''@attr'' [[https://docs.swift.org/swift-book/ReferenceManual/Attributes.html|9]]   * Swift: ''@attr'' [[https://docs.swift.org/swift-book/ReferenceManual/Attributes.html|9]]
   * TypeScript/JS: ''@Attr'' [[https://www.typescriptlang.org/docs/handbook/decorators.html|10]]   * TypeScript/JS: ''@Attr'' [[https://www.typescriptlang.org/docs/handbook/decorators.html|10]]
 +
  
 ===== Backward Incompatible Changes ===== ===== Backward Incompatible Changes =====
  
-In theory there is a small BC break, since multiple error suppression operators can currently be added with no additional effect (e.g. ''@@@@@really_suppress_me()''). However, this isn't useful for anything and is very unlikely to be used anywhere. +In theory there is a small BC break for the ''@@'' syntax, since multiple error suppression operators can currently be added with no additional effect (e.g. ''@@@@@really_suppress_me()''). However, this isn't useful for anything and is very unlikely to be used anywhere.
- +
-===== Alternative #[] syntax =====+
  
-An alternative to using ''@@Attr'' would be to borrow Rust'''#[attr]'' syntax for attributes. This would also present a backwards compatibility break, since it would no longer be possible to begin a hash style comment with a left bracket:+The alternate ''#[]'' syntax presents larger backwards compatibility break, since it would no longer be possible to begin a hash style comment with a left bracket:
  
 <code php> <code php>
Line 233: Line 291:
 </code> </code>
  
-==== Pros ==== +While duplicate error suppression operators aren't useful, there is a use for comments starting with a left bracket (e.gmaking checkboxes or commenting out an array). There is definitely code in the wild like this that would break[[https://grep.app/search?q=%23%5B&filter[lang][0]=PHP|11]]
-  * Reuses the exact same syntax as another C family language. +
-  * Retains a closing delineator to mark the end of the attribute. +
-  * Potentially forwards compatible for single-line attributes.+
  
-E.g. the following syntax is compatible with both PHP 7 and PHP 8 (the attribute is treated as a comment on PHP 7): 
  
-<code php> +===== Unaffected Functionality =====
-#[Attribute] +
-final class Covers {} +
-</code>+
  
-So with this syntax, in theory it would be possible for a library to support both native PHP 8 attributes and PHP 7 docblock annotations with the same codeE.gPHPUnit could introduce a ''Covers'' attribute class which would also work in PHP 7 to encapsulate information from an ''@covers'' docblock annotation.+Attributes can still be applied to all the same places outlined in the [[https://wiki.php.net/rfc/attributes_v2|Attributes v2]] RFCNon-syntactical attribute functionality also remains unchanged (e.g. the reflection API).
  
-However, this benefit would be lost as soon as a library wants to depend on any other PHP 8 features, and it will become irrelevant anyway once most users upgrade to PHP 8Even with the ''@@'' syntax, libraries can support both native attributes and docblock annotations, they just would need to use a different class (or a parent class) to encapsulate the docblock arguments on PHP 7.x.+Finally, this proposal does not conflict with the [[https://wiki.php.net/rfc/attribute_amendments|Attribute Amendments]] RFC, with the exception that if the ''@@'' syntax is acceptedit will supersede the syntax for grouped attributes.
  
-==== Cons ==== 
  
-  * Larger BC break than ''@@''. While duplicate error suppression operators aren't useful, there is a use for comments starting with a left bracket (e.g. for making checkboxes, or to comment out an array). There is definitely code in the wild using this syntax. [[https://grep.app/search?q=%23%5B&filter[lang][0]=PHP|11]] +===== Community Poll =====
-  * It's slightly more verbose than ''@@'', which works against one of the goals of this RFC. +
-  * Arguably more difficult to type than ''@@'' on common QWERTY keyboard layouts. +
-  * Syntax may be confusing for some, since it looks more like a comment than the existing docblock annotations developers are familiar with.+
  
-==== Additional examples with #[] ====+On June 10-13 there was a poll on Reddit to see which syntax the community prefers. [[https://www.reddit.com/r/PHP/comments/h06bra/community_poll_attribute_syntax/|12]]
  
-<code ecmascript> +''@@'' was the most popular, with 436 votes. ''%%<<>>%%'' came in second place, with 240 votes. ''#[]'' came in third place, with 159 votes.
-#[Jit] +
-function foo() {}+
  
-class Foo 
-{ 
-    #[ExampleAttribute] 
-    public const FOO = 'foo'; 
  
-    // with potential nesting in future +===== Vote =====
-    #[JoinTable( +
-        "User_Group", +
-        #JoinColumn("User_id", "id"), +
-        #JoinColumn("Group_id", "id"), +
-    )] +
-    private $groups;+
  
-    #[ExampleAttribute] +Voting started on 2020-06-17 and ended on 2020-07-01.
-    public function foo(#[ExampleAttribute] Type $bar) {} +
-}+
  
-$object new #[ExampleAttribute] class () {};+==== Primary vote ====
  
-$f1 #[ExampleAttribute] function () {};+<doodle title="Are you okay with re-voting on the attribute syntax for PHP 8.0?" auth="theodorejb" voteType="single" closed="true"> 
 +   * Yes 
 +   * No 
 +</doodle>
  
-$f2 #[ExampleAttribute] fn() => 1; +==== Secondary vote ====
-</code>+
  
-===== Unaffected Functionality =====+This is a ranked-choice poll (following [[https://en.wikipedia.org/wiki/Single_transferable_vote#Example|STV]]) between the ''@@'', ''#[]'', and ''%%<<>>%%'' syntax alternatives. You can vote **three** times, but make sure you select each syntax only once.
  
-Attributes can still be applied to all the same places outlined in the [[https://wiki.php.net/rfc/attributes_v2|Attributes v2]] RFC. Non-syntactical attribute functionality also remains unchanged (e.g. the reflection API).+=== First choice ===
  
-Finally, this proposal does not conflict with the [[https://wiki.php.net/rfc/attribute_amendments|Attribute Amendments]] RFC, with the exception that if the ''@@'' syntax is accepted, it will supersede the syntax for grouped attributes.+<doodle title="Attribute syntax choice #1" auth="theodorejb" voteType="single" closed="true"> 
 +   @@ 
 +   * #[] 
 +   * <<>> 
 +</doodle>
  
-===== Vote =====+=== Second choice ===
  
-Are you okay with re-voting on the attribute syntax for PHP 8.0, including the already accepted ''%%<<>>%%'' option? Yes/No+<doodle title="Attribute syntax choice #2" auth="theodorejb" voteType="single" closed="true"> 
 +   * @@ 
 +   * #[] 
 +   <<>> 
 +</doodle> 
 + 
 +=== Third choice === 
 + 
 +<doodle title="Attribute syntax choice #3" auth="theodorejb" voteType="single" closed="true"> 
 +   * @@ 
 +   * #[] 
 +   * <<>> 
 +</doodle>
  
-Secondary vote: ranked-choice vote between ''@@'', ''#[]'', and ''%%<<>>%%'' syntax alternatives. 
  
 ===== References ===== ===== References =====
Line 302: Line 352:
   * Previous discussion about nested attributes: https://externals.io/message/108907#109623 and https://externals.io/message/108907#109688   * Previous discussion about nested attributes: https://externals.io/message/108907#109623 and https://externals.io/message/108907#109688
   * Previous comments in favor of ''@@'': https://externals.io/message/109713#109742   * Previous comments in favor of ''@@'': https://externals.io/message/109713#109742
-  * Attribute syntax community poll: https://www.reddit.com/r/PHP/comments/h06bra/community_poll_attribute_syntax/+
  
 ===== Changelog ===== ===== Changelog =====
  
   * 2020-06-09 - Added ''#[Attr]'' syntax alternative with ranked-choice vote.   * 2020-06-09 - Added ''#[Attr]'' syntax alternative with ranked-choice vote.
 +  * 2020-06-16 - Summarized community poll and moved alternative syntax proposal before discussion section.
rfc/shorter_attribute_syntax.txt · Last modified: 2020/08/12 15:56 by theodorejb