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
rfc:shorter_attribute_syntax [2020/06/15 02:01]
theodorejb Secondary vote should be ranked-choice
rfc:shorter_attribute_syntax [2020/08/12 15:56] (current)
theodorejb Update nested syntax for #[] - I think this was a relic of the idea to strip all leading hashes
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
 +
  
 ===== 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.1592186511.txt.gz · Last modified: 2020/06/15 02:01 by theodorejb