[RFC] Shorter attribute syntax

php.internals

Theodore Brown

6 years ago
Hi internals, I discussed the syntax for attributes further with Benjamin, Martin, and several other internals developers off-list, and with their feedback completed an RFC proposing to use the shorter `@@` syntax instead of `<<>>` for attributes in PHP 8. https://wiki.php.net/rfc/shorter_attribute_syntax The goal is not to bikeshed over subjective syntax preferences, but to address several concrete shortcomings related to verbosity, nested attributes, confusion with generics and other tokens, and dissimilarity to other common languages. Best regards, Theodore

Benjamin Eberlei

6 years ago
On Thu, Jun 4, 2020 at 1:55 AM Theodore Brown <theodorejb@outlook.com> wrote:
> Hi internals, > > I discussed the syntax for attributes further with Benjamin, Martin, > and several other internals developers off-list, and with their > feedback completed an RFC proposing to use the shorter `@@` syntax > instead of `<<>>` for attributes in PHP 8. > > https://wiki.php.net/rfc/shorter_attribute_syntax > > The goal is not to bikeshed over subjective syntax preferences, > but to address several concrete shortcomings related to verbosity, > nested attributes, confusion with generics and other tokens, and > dissimilarity to other common languages. >
I don't have strong feelings for any syntax. I was focussing on <<Attr>> because from the previous RFC proposed by Dmitry in 2016 it looked like this is the most likely to get accepted and at least compared to @: that proved to be right. In hindsight it would have been better to have a three way vote on syntax including this AT-AT syntax, but having another vote now just about the syntax (not the feature) will make the end result (whatever it might be) stronger. And this is the last possible point in time where we could make these changes.

Benas IML

6 years ago
Hello, thank you for the RFC but I hope it doesn't pass. Here's my constructive feedback as to why. Verbosity? Are we really debating whether adding 2 extra characters is more "verbose"? Well, with 3 or more grouped attributes, we are less verbose by 1 character. I don't find "verbosity" to be an argument as to why we should use the `@@` syntax. Moreover, we become inconsistent with basically every other programming language. Even `<<...>>` syntax is more consistent since our sister language Hack has it. I don't think it's a good idea to reinvent the wheel. And well, a BC break, even as small as it, is a BC break. Best regards, Benas On Thu, Jun 4, 2020, 2:55 AM Theodore Brown <theodorejb@outlook.com> wrote:

Peter Bowyer

6 years ago
Hi Theodore, On Thu, 4 Jun 2020 at 00:55, Theodore Brown <theodorejb@outlook.com> wrote:
> https://wiki.php.net/rfc/shorter_attribute_syntax
Thanks for creating this RFC and for including "Comparison to other languages" in it. A provisional +1 from me. Does the PHP parser prevent us from adopting #[attr]? I presume C#'s [attr] syntax and C++'s [[attr]] are impossible due to PHP's short array syntax. Peter

Benas IML

6 years ago
Hello, yes, that would create ambiguity in the parser since `#` (just like `//`) is for comments. Best regards, Benas On Thu, Jun 4, 2020, 11:03 AM Peter Bowyer <phpmailinglists@gmail.com> wrote:

Ilija Tovilo

6 years ago
> > Does the PHP parser prevent us from adopting #[attr]? I presume C#'s [attr] > > syntax and C++'s [[attr]] are impossible due to PHP's short array syntax. > > yes, that would create ambiguity in the parser since `#` (just like `//`) > is for comments.
I've mentioned this off-list before. If we consider @@ with a BC break we could also consider #[] by making #[ a symbol. This is also a breaking change but a probably similarly small one. It would break code like this: # Comments still work #[ <-- But they can't start with #[ To me both of those look acceptable but #[ looks nicer (but that's just my personal preference). Ilija

Benas IML

6 years ago
Hey! That's why I am against this RFC or any other "change style to what I prefer". PHP's current attribute syntax is consistent with other languages and poses no BC breaks whatsoever. Best regards, Benas On Thu, Jun 4, 2020, 1:37 PM Ilija Tovilo <tovilo.ilija@gmail.com> wrote:

Theodore Brown

6 years ago
On Thu, June 4, 2020 at 5:37 AM Ilija Tovilo <tovilo.ilija@gmail.com> wrote: >>> Does the PHP parser prevent us from adopting #[attr]? I presume >>> C#'s [attr] syntax and C++'s [[attr]] are impossible due to >>> PHP's short array syntax. >> >> yes, that would create ambiguity in the parser since `#` (just >> like `//`) is for comments. > > I've mentioned this off-list before. If we consider @@ with a BC > break we could also consider #[] by making #[ a symbol. > This is also a breaking change but a probably similarly small one. > It would break code like this: > > # Comments still work > #[ <-- But they can't start with #[ > > To me both of those look acceptable but #[ looks nicer (but that's > just my personal preference). Hi Ilija, From the perspective of looks I don't have a strong preference between them. There are two main reasons the RFC doesn't propose the `#[]` syntax. First of all, I would consider this a larger BC break than `@@`. Although hash style comments are relatively uncommon, some codebases do use them, and I don't think we can presume to say that it "isn't useful" to begin a comment with a `[` (as can be said about using multiple suppression operators). Secondly, the `#[]` syntax is 50% more verbose than the two character `@@` proposal; Rust is the only language I found that uses three characters for its attribute syntax like this. ``` Best regards, Theodore

Iván Arias

6 years ago
Hi all, I understand that is better to replicate syntax from another language, but the only valid syntax seems to be the current one (Hack's <<>>). The proposed syntax in this RFC is a new syntax that is not directly used in another language, but an adaptation, and it includes a little BC break. As we are creating new syntax, why not simply use another single symbol? Here are some examples: *Deprecated %Deprecated
>Deprecated
&Deprecated function foo() { } I'm not 100% sure if all this symbols could by used in that context, but I think I prefer any of them rather than a double symbol. Would it be possible to add a multioption vote and let people choose? Regards, Iván Arias.

Theodore Brown

6 years ago
On Thu, June 4, 2020 at 5:39 AM Iván Arias <txigreman@hotmail.com> wrote: > As we are creating new syntax, why not simply use another single > symbol? Here are some examples: > > ```php > *Deprecated > %Deprecated > >Deprecated > &Deprecated > function foo() { } > ``` > > I'm not 100% sure if all this symbols could by used in that context, > but I think I prefer any of them rather than a double symbol. > > Would it be possible to add a multioption vote and let people choose? Hi Iván, No, I don't believe possible to use any of those symbols. * already means multiplication, % is used for modulus, > is for boolean comparison, and & is for references. The point of the RFC isn't to change styles to match a personal preference about looks, but to solve several concrete shortcomings with `<<>>` as laid out in the RFC. Thanks, Theodore

Iván Arias

6 years ago
>> As we are creating new syntax, why not simply use another single >> symbol? Here are some examples: >> >> ```php >> *Deprecated >> %Deprecated >> >Deprecated >> &Deprecated >> function foo() { } >> ``` >> >> I'm not 100% sure if all this symbols could by used in that context, >> but I think I prefer any of them rather than a double symbol. >> >> Would it be possible to add a multioption vote and let people choose? > > Hi Iván, > > No, I don't believe possible to use any of those symbols. * already > means multiplication, % is used for modulus, > is for boolean > comparison, and & is for references. > > The point of the RFC isn't to change styles to match a personal > preference about looks, but to solve several concrete shortcomings > with `<<>>` as laid out in the RFC.
Hi Theodore, Yes, in other context they are operators; the same that << and >>, the bitwise shift operators, and the current syntax is already using them with a different meaning. The ones I put in my original message were just examples of tokens we could use, maybe “&” can’t be used because it can conflict with references, but there are some others I think can be used. Let’s bringing them all together: // From my original message: *Deprecated %Deprecated
>Deprecated
function foo() { } // New ones: :Deprecated =Deprecated function foo() { } We are looking at what other languages are doing, but currently PHP “supports” (not natively) *attributes in docblock comments, and it’s a fairly used feature: /** * @Deprecated */ function foo() {} The closest usable token with one and two symbols would be * and *@ respectively. Anyhow @@ seems faster to type than *@. Anyway, what I was trying to expose is that, as we can not directly adopt syntax for another language, maybe it would be better to not introduce a 2 chars token with BC breaks, and maybe go with a even shorter token with no BC breaks. Which token? I think there are a lot of them we can use, and for sure anyone has its preference; and that’s why I was also suggesting to pick a few of them, vote them in the RFC, and go with the winner. Regards, Iván Arias.

Jordi Boggiano

6 years ago
Hey, On 04/06/2020 01:54, Theodore Brown wrote:
> I discussed the syntax for attributes further with Benjamin, Martin, > and several other internals developers off-list, and with their > feedback completed an RFC proposing to use the shorter `@@` syntax > instead of `<<>>` for attributes in PHP 8. > > https://wiki.php.net/rfc/shorter_attribute_syntax
Thanks for the write-up. I didn't feel strongly either way before but after reading the RFC I am hoping it passes. Another fringe benefit is the ability to grep for attributes, @@ does not occur anywhere in a couple projects I checked, while << does occur both as the << operator and heredocs/nowdocs. My fellow grumpy-old-non-IDE-users might find this a valid argument too :) Best, Jordi
-- Jordi Boggiano @seldaek - https://seld.be

Theodore Brown

6 years ago
On Thu, June 4, 2020 at 6:55 AM Jordi Boggiano <j.boggiano@seld.be> wrote: > Thanks for the write-up. I didn't feel strongly either way before but > after reading the RFC I am hoping it passes. > > Another fringe benefit is the ability to grep for attributes, @@ does > not occur anywhere in a couple projects I checked, while << does occur > both as the << operator and heredocs/nowdocs. My fellow > grumpy-old-non-IDE-users might find this a valid argument too :) Hi Jordi, That's a good point. I have updated the RFC to briefly mention this benefit as well. Best regards, Theodore

Ben Ramsey

6 years ago
> On Jun 3, 2020, at 18:54, Theodore Brown <theodorejb@outlook.com> wrote: > > Hi internals, > > I discussed the syntax for attributes further with Benjamin, Martin, > and several other internals developers off-list, and with their > feedback completed an RFC proposing to use the shorter `@@` syntax > instead of `<<>>` for attributes in PHP 8. > > https://wiki.php.net/rfc/shorter_attribute_syntax > > The goal is not to bikeshed over subjective syntax preferences, > but to address several concrete shortcomings related to verbosity, > nested attributes, confusion with generics and other tokens, and > dissimilarity to other common languages.
After reading the RFC, I think I’m a +1 on the proposed `@@` syntax. Glancing at the example code in the RFC, I think this improves readability (at least to my eyes). Cheers, Ben

Rowan Collins

6 years ago
On Thu, 4 Jun 2020 at 00:55, Theodore Brown <theodorejb@outlook.com> wrote:
> https://wiki.php.net/rfc/shorter_attribute_syntax > > The goal is not to bikeshed over subjective syntax preferences, > but to address several concrete shortcomings related to verbosity, > nested attributes, confusion with generics and other tokens, and > dissimilarity to other common languages. >
Hi Theodore, I find the "objective" reasons in this RFC to be greatly exaggerated. 1. "@@Jit" does not require "half as many characters" as "<<Jit>>"; even for this, which is probably the shortest attribute anyone will ever use, the saving is less than 30%; for more common attributes which resemble entire function calls, it will be a tiny proportional saving. 2. You don't actually explain why @@Foo would be any easier to integrate with nested attributes than <<Foo>>. Is there some parser conflict that applies to one and not the other? 3. While confusion with generics is possible, I would be interested to hear from C# programmers how often they confuse [Attribute] for an array index operation, or any of the other uses of square brackets. 4. Similarly, I've yet to see anyone point to an example of confusion with shift operators that's not extremely contrived. I could come up with equally contrived examples where an attribute contained e-mail addresses and twitter handles, making @@ look confusing. 5. No other language has been put forward using the @@ operator. It more closely resembles those languages that use a single @, but the <<Foo>> syntax more closely resembles those languages that use some form of brackets. I also find it disingenuous that you refer to the <<Foo>> syntax as "the shift tokens" throughout, but do not similarly call your proposed syntax "the double-suppression token". If one is "double-at", then the other is "double-angle-brackets". The one convincing *objective* argument I've seen is Jordi's, that @@ would be easily greppable. Interestingly, that's not true of any of the other languages listed in the comparison other than Rust's hash-bracket and maybe C++'s double-bracket, but that doesn't mean we can't do better. Other than that, I think it really comes down to a matter of taste. Some people reacted to the <<Foo>> syntax the way they did to the Cats movie trailer, and may react to this one better. That's fine; we can make a decision for subjective reasons, but let's be honest and say that. Regards,
-- Rowan Tommins [IMSoP]

Theodore Brown

6 years ago
On Thu, June 4, 2020 at 12:19 PM Rowan Tommins <rowan.collins@gmail.com> wrote: > Hi Theodore, Hi Rowan, Thanks for the feedback. I added replies inline. > I find the "objective" reasons in this RFC to be greatly exaggerated. > > 1. `@@Jit` does not require "half as many characters" as `<<Jit>>`; > even for this, which is probably the shortest attribute anyone will > ever use, the saving is less than 30%; for more common attributes > which resemble entire function calls, it will be a tiny proportional > saving. By "half as many characters" the RFC is referring to the attribute syntax itself, not the name/arguments of the attribute being used. You're right that with longer attributes, the attribute syntax makes up a smaller percentage of the code. However, I'd argue the savings still has value even when it's a smaller proportion. > 2. You don't actually explain why `@@Foo` would be any easier to > integrate with nested attributes than `<<Foo>>`. Is there some > parser conflict that applies to one and not the other? Martin can correct me if I'm wrong here, but I believe nested attributes are syntactically possible with the `<<>>` syntax, but "ugly as sin" (to quote Nikita). For example: ```php <<JoinTable( "User_Group", <<JoinColumn("User_id", "id")>>, <<JoinColumn("Group_id", "id")>>, )>> private $groups; ``` Also, grouped attributes would probably have to be special-cased to be disallowed in nested attributes, since they don't make sense there. During implementation a bunch of work was put into trying to support nested attributes with `new` (e.g. `new JoinColumn("User_id", "id")`), but as the RFC mentions this was given up on since it turned out to be very difficult to implement and would require lots of changes to const expressions. > 3. While confusion with generics is possible, I would be interested > to hear from C# programmers how often they confuse `[Attribute]` for > an array index operation, or any of the other uses of square brackets. One reason I think confusion with generics is more probable is that generics and attributes would frequently be used in a similar location (near the start of a class declaration). > 4. Similarly, I've yet to see anyone point to an example of confusion > with shift operators that's not extremely contrived. I could come up > with equally contrived examples where an attribute contained e-mail > addresses and twitter handles, making `@@` look confusing. Perhaps, though this seems much less likely since email addresses and twitter handles would be in a string, whereas `<<` is a standalone token used outside of strings. > 5. No other language has been put forward using the `@@` operator. It > more closely resembles those languages that use a single `@`, but the > `<<Foo>>` syntax more closely resembles those languages that use some > form of brackets. Fair enough. This doesn't really seem like an argument one way or another. > I also find it disingenuous that you refer to the `<<Foo>>` syntax as > "the shift tokens" throughout, but do not similarly call your proposed > syntax "the double-suppression token". If one is "double-at", then the > other is "double-angle-brackets". I don't understand how it's disingenuous. The RFC refers to the shift tokens as such because that's what they are (`T_SL` and `T_SR`). The proposed `@@` syntax uses a new `T_ATTRIBUTE` token. > The one convincing *objective* argument I've seen is Jordi's, that > `@@` would be easily greppable. Interestingly, that's not true of > any of the other languages listed in the comparison other than Rust's > hash-bracket and maybe C++'s double-bracket, but that doesn't mean we > can't do better. Yes, I this is one reason I think having an `@@` token is a good fit for PHP, as preserving easy greppability has influenced other syntax decisions as well (e.g. the placement of return types). > Other than that, I think it really comes down to a matter of taste. Some > people reacted to the `<<Foo>>` syntax the way they did to the Cats movie > trailer, and may react to this one better. That's fine; we can make a > decision for subjective reasons, but let's be honest and say that. Well, I guess the line between objective and subjective may sometimes be a bit subjective. :) Best regards, Theodore

Rowan Collins

6 years ago
Hi Theodore, Firstly, sorry if my previous e-mail came across overly negative, I wasn't in the best mood when I wrote it (gestures vaguely at the state of the world). I think this is possibly the best line I've read all week:
> Well, I guess the line between objective and subjective may sometimes > be a bit subjective. :)
Ultimately, it all comes down to judgement calls - is the double-angle-bracket syntax "too verbose", "too ugly" when nested, etc; and does the double-at syntax make it "better enough". So I'll try not to get into endless back-and-forth on every point, and just pick up on a couple of things. On 04/06/2020 23:20, Theodore Brown wrote:
> Also, grouped attributes would probably have to be special-cased to > be disallowed in nested attributes, since they don't make sense there.
I'm not entirely clear how they work in current implementations like Doctrine's, but I think nested attributes would have to have completely different rules anyway, because you don't access them directly through reflection in the same way. If <<Foo( <<Bar>> )>> means something like "new Foo( new Bar )", then I can imagine it being useful for <<Foo( <<Bar, Baz>> )>> to mean "new Foo( [new Bar, new Baz] )". That would actually be more convenient than the double-at version, where you'd have to write @@Foo( [ @@Bar, @@Baz ] ) or use a constructor with a ...$variadic parameter.
> I don't understand how it's disingenuous. The RFC refers to the shift > tokens as such because that's what they are (`T_SL` and `T_SR`). The > proposed `@@` syntax uses a new `T_ATTRIBUTE` token.
The "::" token in the parser is called T_PAAMAYIM_NEKUDOTAYIM, and personally I find T_SL and T_SR just as cryptic and irrelevant. The most common place I see those token names is when accidentally running code with conflict markers like "<<<<<<<<", or when messing up heredoc syntax; even if they weren't so abbreviated, my reaction would be "shift what now?" I've used bit-shifts maybe twice in the last ten years, so it's just not an immediate association to me. "Disingenuous" was probably too strong a word, but I do think it relates to a fundamental difference in viewpoint: to some people, << and >> are first and foremost the shift-left and shift-right operators, and so the immediate association on seeing them is so obvious it's not worth mentioning; to others, they just look like a new kind of brackets. That association might actually be a good reason to avoid that syntax, but if so it should be spelled out, rather than taken as a given. Regards,
-- Rowan Tommins (né Collins) [IMSoP]

Theodore Brown

6 years ago
Hi Rowan, On Sat, June 6, 2020 at 7:06 AM Rowan Tommins <rowan.collins@gmail.com> wrote: > The `::` token in the parser is called `T_PAAMAYIM_NEKUDOTAYIM`, and > personally I find `T_SL` and `T_SR` just as cryptic and irrelevant. The most > common place I see those token names is when accidentally running code > with conflict markers like "<<<<<<<<", or when messing up heredoc > syntax; even if they weren't so abbreviated, my reaction would be "shift > what now?" I've used bit-shifts maybe twice in the last ten years, so > it's just not an immediate association to me. > > "Disingenuous" was probably too strong a word, but I do think it relates > to a fundamental difference in viewpoint: to some people, `<<` and `>>` > are first and foremost the shift-left and shift-right operators, and so > the immediate association on seeing them is so obvious it's not worth > mentioning; to others, they just look like a new kind of brackets. > > That association might actually be a good reason to avoid that syntax, > but if so it should be spelled out, rather than taken as a given. That makes sense. I updated the RFC now to avoid usage of "shift tokens" in most places and instead refer to them as `<<` and `>>` tokens. I also added a sentence spelling out why the association with shift operators may be confusing for some developers. Additionally, the RFC more clearly lays out the issues with nested attributes now. > > Also, grouped attributes would probably have to be special-cased to > > be disallowed in nested attributes, since they don't make sense there. > > I'm not entirely clear how they work in current implementations like > Doctrine's, but I think nested attributes would have to have completely > different rules anyway, because you don't access them directly through > reflection in the same way. > > If `<<Foo( <<Bar>> )>>` means something like `new Foo( new Bar )`, then I > can imagine it being useful for `<<Foo( <<Bar, Baz>> )>>` to mean > `new Foo( [new Bar, new Baz] )`. That would actually be more convenient than > the double-at version, where you'd have to write `@@Foo( [@@Bar, @@Baz] )` > or use a constructor with a `...$variadic` parameter. In that example there are the same number of characters either way, so it's not clear the nested `<<>>` approach would be more convenient. And do you think it's a good idea to have an additional syntax for creating arrays like that? It seems like it could get confusing. > Ultimately, it all comes down to judgement calls - is the > double-angle-bracket syntax "too verbose", "too ugly" when nested, etc; > and does the double-at syntax make it "better enough". Yes, I agree that there's a judgment call to make. Out of curiosity, given these shortcomings of the double-angle-bracket syntax, do you think there are any objective reasons to prefer it over `@@` (other than the theoretical BC break of code like `@@@really_suppress_me()`)? Best regards, Theodore

Rowan Collins

6 years ago
On 07/06/2020 19:37, Theodore Brown wrote:
>> If `<<Foo( <<Bar>> )>>` means something like `new Foo( new Bar )`, then I >> can imagine it being useful for `<<Foo( <<Bar, Baz>> )>>` to mean >> `new Foo( [new Bar, new Baz] )`. That would actually be more convenient than >> the double-at version, where you'd have to write `@@Foo( [@@Bar, @@Baz] )` >> or use a constructor with a `...$variadic` parameter. > In that example there are the same number of characters either way, so > it's not clear the nested `<<>>` approach would be more convenient. > And do you think it's a good idea to have an additional syntax for > creating arrays like that? It seems like it could get confusing.
True, it doesn't make a huge amount of difference. My thinking was that passing a list of attributes as arguments to another would be quite a common case, and would add value to the special "nested attributes" syntax, which is otherwise just a weird spelling of "new" to work around implementation problems (if indeed it does actually work around them).
>> Ultimately, it all comes down to judgement calls - is the >> double-angle-bracket syntax "too verbose", "too ugly" when nested, etc; >> and does the double-at syntax make it "better enough". > Yes, I agree that there's a judgment call to make. Out of curiosity, > given these shortcomings of the double-angle-bracket syntax, do you > think there are any objective reasons to prefer it over `@@` (other > than the theoretical BC break of code like `@@@really_suppress_me()`)?
I'm not convinced there's any objective reasons to be found either way, but for the sake of "playing devil's advocate", here are a few that could be put forward: If grouped attributes are added, they're actually slightly less verbose than repeating a double-at prefix, once you have enough attributes in the set: Minimum spacing and punctuation requires n+3 chars vs 3n, so a saving even with 2 attributes: <<Foo,Bar>>class Bob{} vs @@Foo @@Bar class Bob{} More realistic spacing is 2n+3 vs 3n, giving a saving only with 4 or more: <<Foo, Bar, Baz, Quux>>class Bob{} vs @@Foo @@Bar @@Baz @@Quuxclass Bob{} Bracket-based syntaxes, particularly with grouping, are more clearly separated from the main code, particularly when used inline. For instance: $f = @@Something @@AnotherThing function(@@Special @@ReallyInt int $var) {}; vs $f = <<Something, AnotherThing>> function(<<Special, ReallyInt>> int $var) {}; Finally, typing up those examples, it occurs to me that @@ is quite a "heavy" symbol - it has a large proportion of black (or whatever colour) pixels - and inevitably a rather "fussy" one. I find it draws the eye more than the angle-brackets do, which feels unfortunate. Regards,
-- Rowan Tommins (né Collins) [IMSoP]

Theodore Brown

6 years ago
Hi Rowan, On Sun, June 7, 2020 at 5:32 PM Rowan Tommins <rowan.collins@gmail.com> wrote: > On 07/06/2020 19:37, Theodore Brown wrote: > > Yes, I agree that there's a judgment call to make. Out of curiosity, > > given these shortcomings of the double-angle-bracket syntax, do you > > think there are any objective reasons to prefer it over `@@` (other > > than the theoretical BC break of code like `@@@really_suppress_me()`)? > > I'm not convinced there's any objective reasons to be found either way, > but for the sake of "playing devil's advocate", here are a few that > could be put forward: > > If grouped attributes are added, they're actually slightly less verbose > than repeating a double-at prefix, once you have enough attributes in > the set: > > Minimum spacing and punctuation requires n+3 chars vs 3n, so a saving > even with 2 attributes: > `<<Foo,Bar>>class Bob{}` > vs > `@@Foo @@Bar class Bob{}` > > More realistic spacing is 2n+3 vs 3n, giving a saving only with 4 or more: > `<<Foo, Bar, Baz, Quux>>class Bob{}` > vs > `@@Foo @@Bar @@Baz @@Quux class Bob{}` Neither of these are realistic examples, though. In practice, you're not going to have an empty class definition on the same line as a bunch of short attributes like this. Based on the Use Cases section of the Attributes v2 RFC, [1] typically there would be three or fewer attributes applied to a given entity. The RFC only has one example with four attributes, which happens to be a flattened version of the nested attributes use case discussed in the Shorter Attribute Syntax RFC. But in this example, the attributes each have one or more parameters, which makes them long enough that they have to be on separate lines. And with sane formatting, the `<<>>` syntax version still ends up being more verbose: ```php // 170 characters for attributes (162 not counting leading whitespace) << ManyToMany(Phonenumber::class), JoinTable("users_phonenumbers"), JoinColumn("user_id", "id"), InverseJoinColumn("phonenumber_id", "id", JoinColumn::UNIQUE), >> private $phonenumbers; // 160 characters for attributes @@ManyToMany(Phonenumber::class) @@JoinTable("users_phonenumbers") @@JoinColumn("user_id", "id") @@InverseJoinColumn("phonenumber_id", "id", JoinColumn::UNIQUE) private $phonenumbers; ``` So the idea that the `<<>>` syntax with grouped attributes will be less verbose than the `@@` syntax turns out not to be the case in real-world use cases. > Bracket-based syntaxes, particularly with grouping, are more clearly > separated from the main code, particularly when used inline. For instance: > > `$f = @@Something @@AnotherThing function(@@Special @@ReallyInt int $var) {};` > vs > `$f = <<Something, AnotherThing>> function(<<Special, ReallyInt>> int $var) {};` To me there doesn't seem to be a big difference in readability between the function attributes in this example. And with syntax highlighting, the function keyword itself provides a very clear separation. For the parameter attributes, the `@@` syntax example is actually more readable to my eye. I can't help seeing the `>>` token as a shift operator at first glance in this context. > Finally, typing up those examples, it occurs to me that `@@` is quite a > "heavy" symbol - it has a large proportion of black (or whatever colour) > pixels - and inevitably a rather "fussy" one. I find it draws the eye > more than the angle-brackets do, which feels unfortunate. I guess this is somewhat dependent on the font you're using. But in general I don't think that the symbol being "heavy" is necessarily a bad thing. It can help attributes stand out better from function calls, generics, and other nearby syntax. Best regards, Theodore [1]: https://wiki.php.net/rfc/attributes_v2#use_cases

Larry Garfield

6 years ago
On Sun, Jun 7, 2020, at 11:36 PM, Theodore Brown wrote:
> > Bracket-based syntaxes, particularly with grouping, are more clearly > > separated from the main code, particularly when used inline. For instance: > > > > `$f = @@Something @@AnotherThing function(@@Special @@ReallyInt int $var) {};` > > vs > > `$f = <<Something, AnotherThing>> function(<<Special, ReallyInt>> int $var) {};` > > To me there doesn't seem to be a big difference in readability between > the function attributes in this example. And with syntax highlighting, > the function keyword itself provides a very clear separation. > > For the parameter attributes, the `@@` syntax example is actually > more readable to my eye. I can't help seeing the `>>` token as a > shift operator at first glance in this context. > > > Finally, typing up those examples, it occurs to me that `@@` is quite a > > "heavy" symbol - it has a large proportion of black (or whatever colour) > > pixels - and inevitably a rather "fussy" one. I find it draws the eye > > more than the angle-brackets do, which feels unfortunate. > > I guess this is somewhat dependent on the font you're using. But in > general I don't think that the symbol being "heavy" is necessarily > a bad thing. It can help attributes stand out better from function > calls, generics, and other nearby syntax. > > Best regards, > Theodore > > [1]: https://wiki.php.net/rfc/attributes_v2#use_cases
FWIW, I find both alternatives ugly to my eye. So, there's that. Given that @ is off the table for obvious reasons, my preference would frankly be for Rust's #[], which has the nice side effect of being a normal comment in earlier PHP versions and so attributes can be included as optional without breaking BC. I don't know if that's a big deal or not, but it's a benefit. And it should be no harder on the parser to differentiate than @ vs @@ is. (The only advantage of @@ in my mind is another obvious Star Wars joke.) Something that I don't think has been addressed explicitly in this thread yet is single line vs separate line attributes. Vis: <<Foo>> class Blah {} vs. <<Foo>> class Blah {} Syntactically both are legal AFAIK; I don't know which most people will do. The separate line version seems more likely, and cleaner to me, but for parameters people may want to inline it in shorter signatures. Or it may push people to always multi-line those function definitions, for better or worse. (I find that quite ugly myself, but I don't know if I'm in the majority on that view.) My gut feeling is that @@ is notably worse inline. It subjectively feels messier because there's no clear indication of where the end is. On separate lines, @@ and << >> seem about equally ugly to me. --Larry Garfield

Theodore Brown

6 years ago
On Mon, June 8, 2020 at 10:01 AM Larry Garfield <larry@garfieldtech.com> wrote: > FWIW, I find both alternatives ugly to my eye. So, there's that. > > Given that `@` is off the table for obvious reasons, my preference > would frankly be for Rust's `#[]`, which has the nice side effect > of being a normal comment in earlier PHP versions and so attributes > can be included as optional without breaking BC. I don't know if > that's a big deal or not, but it's a benefit. And it should be no > harder on the parser to differentiate than `@` vs `@@` is. > > (The only advantage of `@@` in my mind is another obvious Star Wars > joke.) Hi Larry, From the perspective of looks I don't have a strong preference between them. There are two main reasons I decided against borrowing the `#[]` syntax from Rust: 1. It's a much larger BC break. Disallowing comments from starting with a certain character could break a lot of code in the wild. From a quick search of grep.app, I found two examples on the first page of results using `#[` as a comment. [1] Is it worth breaking this code? 2. `#[]` is slightly more verbose, which works against one of the objectives of the RFC. Rust is the only language I found that uses three characters for its attribute syntax like this. I actually starting trying to draft an RFC which would propose the `#[]` syntax for attributes, but one thing I noticed while doing so is that (at least on my QWERTY keyboard) `#[` is noticeably harder to type - I kept typoing it as `#]` or `#\`. This is dependent on keyboard layout, of course, but being prone to accidental typos was also one of the arguments against the `@:` syntax in the original RFC. > Something that I don't think has been addressed explicitly in this > thread yet is single line vs separate line attributes. Vis: > > `<<Foo>> class Blah {}` > > vs. > > ```php > <<Foo>> > class Blah {} > ``` > > Syntactically both are legal AFAIK; I don't know which most people > will do. The separate line version seems more likely, and cleaner > to me, but for parameters people may want to inline it in shorter > signatures. Or it may push people to always multi-line those > function definitions, for better or worse. (I find that quite ugly > myself, but I don't know if I'm in the majority on that view.) > > My gut feeling is that `@@` is notably worse inline. It subjectively > feels messier because there's no clear indication of where the end > is. On separate lines, `@@` and `<< >>` seem about equally ugly to me. Personally I have the opposite reaction when it comes to inline parameter attributes - the closing `>>` always looks like a shift operator at first glance which makes it harder for me to read. And for an inline function or class attribute the function/class keyword already provides a strong indication of where the attribute ends. But for anything other than very short attributes, I expect most people will want to put the attribute on a separate line for optimal readability, regardless of the final syntax: ```php function foo( <<ExampleAttribute("foo", "bar")>> <<OtherAttribute(123, ["key" => "val"])>> Type $myParam, bool $param2, ) { ... } // vs. function foo( @@ExampleAttribute("foo", "bar") @@OtherAttribute(123, ["key" => "val"]) Type $myParam, bool $param2, ) { ... } ``` Best regards, Theodore [1]: https://grep.app/search?q=%23%5B&filter[lang][0]=PHP

Markus Fischer

6 years ago
Hi Theodore, On 08.06.20 06:36, Theodore Brown wrote:
> ```php > // 170 characters for attributes (162 not counting leading whitespace) > << > ManyToMany(Phonenumber::class), > JoinTable("users_phonenumbers"), > JoinColumn("user_id", "id"), > InverseJoinColumn("phonenumber_id", "id", JoinColumn::UNIQUE), >>> > private $phonenumbers; > > // 160 characters for attributes > @@ManyToMany(Phonenumber::class) > @@JoinTable("users_phonenumbers") > @@JoinColumn("user_id", "id") > @@InverseJoinColumn("phonenumber_id", "id", JoinColumn::UNIQUE) > private $phonenumbers; > ```
When your proposal came up, my first thought was this is great and should be supported; I simply had a liking for this terse syntax over the older. Until I read your email last night and saw some direct text comparison. I noticed that my `@` character did bleed/meld almost with the first character of the attribute name. I noticed this in my MUA so I figured a proper test in the IDE with my font of choice is more realistic; here's a plainly colored version first: https://i.imgur.com/tq7FzQz.png Notice how wide characters like the `M` almost touch the `@`. Same now in a best attempt PHP syntax highlighted source file (courtesy of PhpStorm, obviously not supporting this ATM): https://i.imgur.com/WVXL8S7.png But even a clearly distinct colored `@@` token did, for me personally, not increase the readability by much ("to me"). At this point I forgot if the following is a valid combination, but it wouldn't matter as I want to make comparison data point for my personally and even this version is by far more readable, to me at least: https://i.imgur.com/GI3HlsM.png Until I had this realization, I was absolutely in favour of `@@`. I'm not so much anymore. Since we humans read source more often then we write, I can only suggest to everyone to conduct their own "visual" testing first and not just judge on technical merits => I think it makes sense to consider both here, since we're already discussing a change here. (note: I'm not a voter here) I wonder what others think about this. thanks, - Markus

Rowan Collins

6 years ago
Hi Markus, On 08/06/2020 19:08, Markus Fischer wrote:
> Since we humans read source more often then we write, I can only > suggest to everyone to conduct their own "visual" testing first and > not just judge on technical merits => I think it makes sense to > consider both here, since we're already discussing a change here.
I was just thinking about how different fonts would affect this, and particularly those with ligatures - a lot of coding fonts already include ligatures for << and >> and some have something for #[ as well; I wonder how easy it would be to create a "nice" ligature for @@ In doing so, I found this site which lets you compare text in a long list of programming fonts, which is interesting to play with how the different syntaxes "feel": https://www.programmingfonts.org/ It doesn't have a save/share function, so here's a code sample of the main styles discussed so far for people to play with: // Currently implemented <<ManyToMany(Phonenumber::class)>> <<JoinTable("users_phonenumbers")>> <<JoinColumn("user_id", "id")>> <<InverseJoinColumn("phonenumber_id", "id", JoinColumn::UNIQUE)>> private $phonenumbers; // Proposed grouping <<   ManyToMany(Phonenumber::class),   JoinTable("users_phonenumbers"),   JoinColumn("user_id", "id"),   InverseJoinColumn("phonenumber_id", "id", JoinColumn::UNIQUE),
>>
private $phonenumbers; // Rejected alternative in original RFC @:ManyToMany(Phonenumber::class) @:JoinTable("users_phonenumbers") @:JoinColumn("user_id", "id") @:InverseJoinColumn("phonenumber_id", "id", JoinColumn::UNIQUE) private $phonenumbers; // Double-at proposal @@ManyToMany(Phonenumber::class) @@JoinTable("users_phonenumbers") @@JoinColumn("user_id", "id") @@InverseJoinColumn("phonenumber_id", "id", JoinColumn::UNIQUE) private $phonenumbers; // Rust-style #[ManyToMany(Phonenumber::class)] #[JoinTable("users_phonenumbers")] #[JoinColumn("user_id", "id")] #[InverseJoinColumn("phonenumber_id", "id", JoinColumn::UNIQUE)] private $phonenumbers; // Rust-style with grouping #[   ManyToMany(Phonenumber::class),   JoinTable("users_phonenumbers"),   JoinColumn("user_id", "id"),   InverseJoinColumn("phonenumber_id", "id", JoinColumn::UNIQUE), ] private $phonenumbers; Regards,
-- Rowan Tommins (né Collins) [IMSoP]

Theodore Brown

6 years ago
On Mon, June 8, 2020 at 1:08 PM Markus Fischer <markus@fischer.name> wrote: > I noticed that my `@` character did bleed/meld almost with the first > character of the attribute name...wide characters like the `M` almost > touch the `@`. Hi Markus, The first question that comes to my mind is, wouldn't this also be an issue in all the other languages that use the `@Attr` syntax? Personally I've used TypeScript decorators quite a bit, and the use of the `@` character hasn't been a readability problem there. I guess this mostly comes down to the font you use. E.g. here's how the example looks for me in VS Code with the JetBrains Mono font: https://imgur.com/a/qWQf6lz And it's probably safe to say that syntax support/highlighting in PhpStorm will be improved prior to the release of PHP 8.0. :) Best regards, Theodore

Marcio Almada

6 years ago
Hello!
> > Hi internals, > > I discussed the syntax for attributes further with Benjamin, Martin, > and several other internals developers off-list, and with their > feedback completed an RFC proposing to use the shorter `@@` syntax > instead of `<<>>` for attributes in PHP 8.
I'd also prefer any attribute syntax without the bracket-like pair of tokens. I'm just a bit confused about the RFC itself and the PR content at this point. The RFC is currently proposing `@@MyAttribute()` and the PR is currently implementing `@:MyAttribute()` as the sigil. The first brings a BC break and the second doesn't, being the important difference. I'm inclined to `@:` instead of `@@`. Which one will actually be on the ballot? :D Thanks, Márcio Almada

Theodore Brown

6 years ago
On Thu, June 4, 2020 at 3:28 PM Marcio Almada <marcio.web2@gmail.com> wrote: > I'd also prefer any attribute syntax without the bracket-like pair > of tokens. I'm just a bit confused about the RFC itself and the PR > content at this point. > > The RFC is currently proposing `@@MyAttribute()` and the PR > is currently implementing `@:MyAttribute()` as the sigil. The first > brings a BC break and the second doesn't, being the important > difference. > > I'm inclined to `@:` instead of `@@`. Which one will actually be > on the ballot? :D Hi Marcio, `@@` is the syntax that will be voted on. The linked PR is for the original `@:` implementation, but as the RFC notes switching this to `@@` just requires a single character to be changed in the lexer and a small grammar adjustment. If the proposal is accepted we'll submit a new PR with the updated implementation. Apologies for the confusion! Theodore

Benjamin Eberlei

6 years ago
On Thu, Jun 4, 2020 at 1:55 AM Theodore Brown <theodorejb@outlook.com> wrote:
> Hi internals, > > I discussed the syntax for attributes further with Benjamin, Martin, > and several other internals developers off-list, and with their > feedback completed an RFC proposing to use the shorter `@@` syntax > instead of `<<>>` for attributes in PHP 8. > > https://wiki.php.net/rfc/shorter_attribute_syntax > > The goal is not to bikeshed over subjective syntax preferences, > but to address several concrete shortcomings related to verbosity, > nested attributes, confusion with generics and other tokens, and > dissimilarity to other common languages. >
Larry's suggestion about #[Attr] makes an important argument about allowing to declare attributes in code in PHP 7 in a forward compatible way that has not been brought up before. /** @ORM\Entity */ #[ORM\Entity] class User {} This code would work on PHP 7 and 8. The #[] syntax would have about equally low breaking potential as @@. It would be the same syntax as Rusts, and close to C++/C# syntax. As such, instead of going through each alternative syntax one by one, with with each having a 2/3 requirement to overthrow the old one, I would be open to restart the secondary vote on Attributes syntax with <<>> (status quo), @@ and #[] using the same ranked voting algorithm that was used for the PHP 8 RM vote. @Sara @Gabriel I suppose this is something you two should be ok with (and Theodore of course). I would take on the work to write about the third syntax alternative then. The VoteRFC could just link to the three individual RFCs where each discusses their syntax.

Lynn

6 years ago
On Tue, Jun 9, 2020 at 1:55 PM Benjamin Eberlei <kontakt@beberlei.de> wrote:
> Larry's suggestion about #[Attr] makes an important argument about allowing > to declare attributes in code in PHP 7 in a forward compatible way that has > not been brought up before. > > /** @ORM\Entity */ > #[ORM\Entity] > class User {} > > This code would work on PHP 7 and 8. > > The #[] syntax would have about equally low breaking potential as @@. It > would be the same syntax as Rusts, and close to C++/C# syntax. >
Hi, The idea of making annotations forward compatible in php7 this way has a big + from me. I honestly don't mind the syntax too much. How would multiline notations work with this? #[ORM\Entity( arg1, arg2 )] This notation would obviously break in php7. Would it be possible (in this case) to do something like the following example? This would have php7 not care because they are comments, while php8 could filter the # out and make it a valid annotation. #[ORM\Entity( # arg1, # arg2 #)] I'm also okay with having everything on a single line, just wanted to point out this might cause issues. Regards, Lynn

Benjamin Eberlei

6 years ago
On Tue, Jun 9, 2020 at 2:07 PM Lynn <kjarli@gmail.com> wrote:
> > > On Tue, Jun 9, 2020 at 1:55 PM Benjamin Eberlei <kontakt@beberlei.de> > wrote: > >> Larry's suggestion about #[Attr] makes an important argument about >> allowing >> to declare attributes in code in PHP 7 in a forward compatible way that >> has >> not been brought up before. >> >> /** @ORM\Entity */ >> #[ORM\Entity] >> class User {} >> >> This code would work on PHP 7 and 8. >> >> The #[] syntax would have about equally low breaking potential as @@. It >> would be the same syntax as Rusts, and close to C++/C# syntax. >> > > Hi, > > The idea of making annotations forward compatible in php7 this way has a > big + from me. I honestly don't mind the syntax too much. How would > multiline notations work with this? > > #[ORM\Entity( > arg1, > arg2 > )] > > This notation would obviously break in php7. Would it be possible (in this > case) to do something like the following example? This would have php7 not > care because they are comments, while php8 could filter the # out and make > it a valid annotation. >
Good point. The forward compatible syntax would need to require single line declarations as you suggested, because the multiline syntax as you rightly show is not valid php7. The alternative would be requiring each attribute line to begin with #, which I don't particularly care for and would probably be a mistake.

Benas IML

6 years ago
+1 On Tue, Jun 9, 2020, 2:56 PM Benjamin Eberlei <kontakt@beberlei.de> wrote:

Sebastian Bergmann

6 years ago
Am 09.06.2020 um 13:55 schrieb Benjamin Eberlei:
> Larry's suggestion about #[Attr] makes an important argument about allowing > to declare attributes in code in PHP 7 in a forward compatible way that has > not been brought up before. > > /** @ORM\Entity */ > #[ORM\Entity] > class User {} > > This code would work on PHP 7 and 8.
This would be great!

Theodore Brown

6 years ago
Hi Benjamin, On Tue, June 9, 2020 at 6:55 AM Benjamin Eberlei wrote: > Larry's suggestion about `#[Attr]` makes an important argument about > allowing to declare attributes in code in PHP 7 in a forward compatible > way that has not been brought up before. > > ```php > /** @ORM\Entity */ > #[ORM\Entity] > class User {} > ``` > > This code would work on PHP 7 and 8. That's an interesting argument. After thinking about it more, though, I'm not sure I understand what the benefit would be. The docblock annotation needed for PHP 7 is *already* forward compatible with PHP 8. So wouldn't this just be duplicating the attribute and opening the possibility for them to be out of sync for no benefit? Rather than duplicating attributes, wouldn't libraries simply stick with docblock annotations until they need to depend on other PHP 8 features anyway (e.g. union types), and then switch completely to the native attribute syntax? Furthermore, even if there was some benefit to having an attribute in both docblock and native syntaxes, it seems like this is a very short term concern. In a few years once libraries are depending on other PHP 8 features, will this even matter anymore? So I'm really not convinced that this forward compatibility argument should influence the syntax choice. > The `#[]` syntax would have about equally low breaking potential as `@@`. Is this really the case? There's no benefit to adding extra suppression operators, but I have seen code in the wild using hash comments starting with an opening bracket (e.g. to comment out an array, or for making checkboxes like `#[x] Some comment here`). > As such, instead of going through each alternative syntax one by one, > with with each having a 2/3 requirement to overthrow the old one, > I would be open to restart the secondary vote on Attributes syntax > with `<<>>` (status quo), `@@` and `#[]` using the same ranked voting > algorithm that was used for the PHP 8 RM vote. I'm certainly open to holding a three-way ranked choice vote like this, if others are okay with it. > I would take on the work to write about the third syntax alternative > then. The VoteRFC could just link to the three individual RFCs where > each discusses their syntax. I added a section to the Shorter Attribute Syntax RFC discussing the pros and cons of the `#[]` syntax. Let me know if you feel it isn't worded fairly. I think it would be preferable to have the syntax choices and voting options presented in one document rather than spread out in different places if possible. Best regards, Theodore

Sebastian Bergmann

6 years ago
Am 09.06.2020 um 17:57 schrieb Theodore Brown:
> That's an interesting argument. After thinking about it more, though, > I'm not sure I understand what the benefit would be. The docblock > annotation needed for PHP 7 is *already* forward compatible with PHP 8. > So wouldn't this just be duplicating the attribute and opening the > possibility for them to be out of sync for no benefit?
This would allow the introduction of classes into PHPUnit such as namespace PHPUnit\Attribute; #[Attribute] final class Covers { private string $coverageTarget; public function __construct(string $coverageTarget) { $this->coverageTarget = $coverageTarget; } // ... } that can be used to encapsulate information that may come from a ... /** * @covers \Foo\Bar\Baz */ ... DocBlock-style annotation in PHP 7 but may also come from an ... #[Covers(Baz::class)] ... attribute when PHP 8 is used. This would make forward compatibility possible in code such as PHPUnit's that currently supports DocBlock-style annotations but wants to support PHP 8 attributes and to deprecate (and later remove) support for DocBlock-style annotations.

Theodore Brown

6 years ago
Hi Sebastian, On Wed, June 10, 2020 at 12:37 AM Sebastian Bergmann <sebastian@php.net> wrote: > Am 09.06.2020 um 17:57 schrieb Theodore Brown: > > That's an interesting argument. After thinking about it more, though, > > I'm not sure I understand what the benefit would be. The docblock > > annotation needed for PHP 7 is *already* forward compatible with PHP 8. > > So wouldn't this just be duplicating the attribute and opening the > > possibility for them to be out of sync for no benefit? > > This would allow the introduction of classes into PHPUnit such as > > namespace PHPUnit\Attribute; > > #[Attribute] > final class Covers > { > private string $coverageTarget; > > public function __construct(string $coverageTarget) > { > $this->coverageTarget = $coverageTarget; > } > > // ... > } > > that can be used to encapsulate information that may come from a ... > > /** > * @covers \Foo\Bar\Baz > */ > > ... DocBlock-style annotation in PHP 7 but may also come from an ... > > #[Covers(Baz::class)] > > ... attribute when PHP 8 is used. > > This would make forward compatibility possible in code such as PHPUnit's > that currently supports DocBlock-style annotations but wants to support > PHP 8 attributes and to deprecate (and later remove) support for > DocBlock-style annotations. So is the idea that PHPUnit 10 would still run on PHP 7.x, but would also support native attributes for people running PHP 8? Maybe I'm missing something, but wouldn't this be possible with the `@@` syntax as well? The new `Covers` class would only be loaded if someone is using attributes on PHP 8, so it's fine if it uses new PHP 8 syntax. A parent class could be used to encapsulate coverage info for PHP 7.x. To me it seems like the benefit of having (single-line-only) PHP 8 attributes treated as comments in PHP 7.x is being overblown. There is already an upgrade path for docblock annotations to attributes. Docblocks will continue working perfectly fine in PHP 8, so projects and libraries can wait as long as needed before migrating to the native attribute syntax. Using `#[]` as the attribute syntax actually runs the risk of making it *harder* for users to upgrade to PHP 8, since existing code that uses hash comments starting with a left bracket would break. Anyway, our plan is to hold a ranked-choice vote in the RFC between `@@`, `#[]`, and `<<>>` syntax options, so if people prefer the tradeoffs of borrowing Rust's syntax they can vote for it. Best regards, Theodore

Alexandru Pătrănescu

6 years ago
On Tue, Jun 9, 2020 at 6:57 PM Theodore Brown <theodorejb@outlook.com> wrote:
> Hi Benjamin, > > On Tue, June 9, 2020 at 6:55 AM Benjamin Eberlei wrote: > > > Larry's suggestion about `#[Attr]` makes an important argument about > > allowing to declare attributes in code in PHP 7 in a forward compatible > > way that has not been brought up before. > > > > ```php > > /** @ORM\Entity */ > > #[ORM\Entity] > > class User {} > > ``` > > > > This code would work on PHP 7 and 8. > > That's an interesting argument. After thinking about it more, though, > I'm not sure I understand what the benefit would be. The docblock > annotation needed for PHP 7 is *already* forward compatible with PHP 8. > So wouldn't this just be duplicating the attribute and opening the > possibility for them to be out of sync for no benefit? > > Rather than duplicating attributes, wouldn't libraries simply stick > with docblock annotations until they need to depend on other PHP 8 > features anyway (e.g. union types), and then switch completely to the > native attribute syntax? > > Furthermore, even if there was some benefit to having an attribute in > both docblock and native syntaxes, it seems like this is a very short > term concern. In a few years once libraries are depending on other > PHP 8 features, will this even matter anymore? So I'm really not > convinced that this forward compatibility argument should influence > the syntax choice. > > > The `#[]` syntax would have about equally low breaking potential as `@@`. > > Is this really the case? There's no benefit to adding extra suppression > operators, but I have seen code in the wild using hash comments starting > with an opening bracket (e.g. to comment out an array, or for making > checkboxes like `#[x] Some comment here`). > > > As such, instead of going through each alternative syntax one by one, > > with with each having a 2/3 requirement to overthrow the old one, > > I would be open to restart the secondary vote on Attributes syntax > > with `<<>>` (status quo), `@@` and `#[]` using the same ranked voting > > algorithm that was used for the PHP 8 RM vote. > > I'm certainly open to holding a three-way ranked choice vote like > this, if others are okay with it. > > > I would take on the work to write about the third syntax alternative > > then. The VoteRFC could just link to the three individual RFCs where > > each discusses their syntax. > > I added a section to the Shorter Attribute Syntax RFC discussing the > pros and cons of the `#[]` syntax. Let me know if you feel it isn't > worded fairly. I think it would be preferable to have the syntax > choices and voting options presented in one document rather than > spread out in different places if possible. > > Best regards, > Theodore > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > >
Hey, How about #@Attribute as a middle ground between #[Attribute] and @@Attribute Shorter as there is no end token and maybe directly compatible with old style docblock doctrine annotations. It's true that the advantage of compatibility fades away for the #-starting attributes when you think about having it inline as it would consider the rest of the line as a comment but I still think it should be evaluated, considering the current options. Alex

Michał Brzuchalski

6 years ago
wt., 9 cze 2020 o 13:56 Benjamin Eberlei <kontakt@beberlei.de> napisał(a):
> On Thu, Jun 4, 2020 at 1:55 AM Theodore Brown <theodorejb@outlook.com> > wrote: > > > Hi internals, > > > > I discussed the syntax for attributes further with Benjamin, Martin, > > and several other internals developers off-list, and with their > > feedback completed an RFC proposing to use the shorter `@@` syntax > > instead of `<<>>` for attributes in PHP 8. > > > > https://wiki.php.net/rfc/shorter_attribute_syntax > > > > The goal is not to bikeshed over subjective syntax preferences, > > but to address several concrete shortcomings related to verbosity, > > nested attributes, confusion with generics and other tokens, and > > dissimilarity to other common languages. > > > > Larry's suggestion about #[Attr] makes an important argument about allowing > to declare attributes in code in PHP 7 in a forward compatible way that has > not been brought up before. > > /** @ORM\Entity */ > #[ORM\Entity] > class User {} > > This code would work on PHP 7 and 8. > > The #[] syntax would have about equally low breaking potential as @@. It > would be the same syntax as Rusts, and close to C++/C# syntax. >
I just noticed a power of Rusts outer attributes which this syntax count follow in a future. Following outer attributes in Rust's we could introduce in a future syntax like <?php #![StrictTypes,Module("my_module"),Opcache(save_comments: true)] The last one used with recently proposed named arguments which could open a wide range of possibilities IMO. In Rust adding exclamation mark after hash `#!` imposes to take effect on the outer scope which inside a file would be the whole file. Going that path solution like that could possibly supersede `declare` statement in a future and allow to add compile-time attributes without breaking the language. I believe this is very important because any attribute which is not declared as a core and built-in is not taking an effect. This way it'd be possible to add new ones in future PHP versions. Even more with `zend_ast_process` it'd be possible to implement core attributes which take effect on whole file in extension. I can imagine this can possibly be discussed to allow attributes for eg. from ctor to take effect on class but am not 100% sure of it is useful. Going further with my imagination if we go that path with `#[Attribute]` we may think of adding error suppression. I know many don't like error-suppression but sometimes it's helpfull. In case of core attributes I can imagine a const value can be added renamed or removed, but the attribute remains the same then adding error suppression in a future allows to avoid crashing like for eg. #@[Jit(Jit::OPTIMISE_SOMETHING)] // where the const may exists or not, but the Jit attribute does function foo () {} In those cases we don't wanna crash the program, we may want it to continue rather without proper optimisation then not at all. I just see another use of current error-suppression operator @ to play nice with attributes. That's my 50 cents. Best regards, Michał Marcin Brzuchalski

Theodore Brown

6 years ago
On Wed, June 10, 2020 at 3:11 AM Michał Brzuchalski <michal.brzuchalski@gmail.com> wrote: > I just noticed a power of Rusts outer attributes which this syntax > count follow in a future. Following outer attributes in Rust's we > could introduce in a future syntax like > > <?php > #![StrictTypes,Module("my_module"),Opcache(save_comments: true)] > > The last one used with recently proposed named arguments which could > open a wide range of possibilities IMO. In Rust adding exclamation > mark after hash `#!` imposes to take effect on the outer scope which > inside a file would be the whole file. > > Going that path solution like that could possibly supersede > `declare` statement in a future and allow to add compile-time > attributes without breaking the language. I believe this is very > important because any attribute which is not declared as a core and > built-in is not taking an effect. This way it'd be possible to add > new ones in future PHP versions. Even more with `zend_ast_process` > it'd be possible to implement core attributes which take effect on > whole file in extension. > > I can imagine this can possibly be discussed to allow attributes for > eg. from ctor to take effect on class but am not 100% sure of it is > useful. Hi Michał, I'm really not certain it's a good thing to have another way of adding declares which would be ignored in older PHP versions. For instance, in your example if the code is designed to work with stricter types, what happens if it's unexpectedly run on an older version of PHP? Instead of erroring as it should, the code might keep running but produce unexpected results for certain inputs. > Going further with my imagination if we go that path with `#[Attribute]` > we may think of adding error suppression. > I know many don't like error-suppression but sometimes it's helpfull. > > In case of core attributes I can imagine a const value can be added > renamed or removed, but the attribute remains the same then adding > error suppression in a future allows to avoid crashing like for eg. > > #@[Jit(Jit::OPTIMISE_SOMETHING)] // where the const may exists or not, but the Jit attribute does > function foo () {} > > In those cases we don't wanna crash the program, we may want it to > continue rather without proper optimisation then not at all. > > I just see another use of current error-suppression operator @ to > play nice with attributes. Please, let's not add a new place where error suppression can be used. Yes, it's necessary when wrapping some old APIs that otherwise output warnings, but for new APIs I really don't think this is a good idea. Best regards, Theodore

Theodore Brown

6 years ago
On Wed, June 3, 2020 at 6:54 PM Theodore Brown wrote: > Hi internals, > > I discussed the syntax for attributes further with Benjamin, Martin, > and several other internals developers off-list, and with their > feedback completed an RFC proposing to use the shorter `@@` syntax > instead of `<<>>` for attributes in PHP 8. > > https://wiki.php.net/rfc/shorter_attribute_syntax > > The goal is not to bikeshed over subjective syntax preferences, > but to address several concrete shortcomings related to verbosity, > nested attributes, confusion with generics and other tokens, and > dissimilarity to other common languages. Just a heads up that the two week minimum discussion period expires tomorrow, and I'm planning to open voting soon. Best regards, Theodore

Marcio Almada

6 years ago
Hi,
> > Hi internals, > > > > I discussed the syntax for attributes further with Benjamin, Martin, > > and several other internals developers off-list, and with their > > feedback completed an RFC proposing to use the shorter `@@` syntax > > instead of `<<>>` for attributes in PHP 8. > > > > https://wiki.php.net/rfc/shorter_attribute_syntax > > > > The goal is not to bikeshed over subjective syntax preferences, > > but to address several concrete shortcomings related to verbosity, > > nested attributes, confusion with generics and other tokens, and > > dissimilarity to other common languages. > > Just a heads up that the two week minimum discussion period expires > tomorrow, and I'm planning to open voting soon. > >
Hi! Thanks for the notification. I'll probably vote for the `@@` syntax for three reasons: - It feels similar with at least other 5 or 6 languages that choose `@` as their attribute sigil; - The lack of closing brackets make it less verbose, both on nesting and non nesting cases; - BC breaking the stacking of the error suppression operator as in `@@@@some_call()` actually makes some sense. AFAIK there was no reason to allow it, and maybe it was just an implementation oversight? So if the new proposal comes with this nice "fix" attached, at least it feels like a fix to me, it's two good changes on the same package. If not I'd propose to disallow `@@@...` combos myself separately if there is time to do so.
> Best regards, > Theodore > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > >
Thank you for your work. Cheers, Márcio

Michał Brzuchalski

6 years ago
Hi Theodore, wt., 16 cze 2020 o 18:57 Theodore Brown <theodorejb@outlook.com> napisał(a):
> On Wed, June 3, 2020 at 6:54 PM Theodore Brown wrote: > > > Hi internals, > > > > I discussed the syntax for attributes further with Benjamin, Martin, > > and several other internals developers off-list, and with their > > feedback completed an RFC proposing to use the shorter `@@` syntax > > instead of `<<>>` for attributes in PHP 8. > > > > https://wiki.php.net/rfc/shorter_attribute_syntax > > > > The goal is not to bikeshed over subjective syntax preferences, > > but to address several concrete shortcomings related to verbosity, > > nested attributes, confusion with generics and other tokens, and > > dissimilarity to other common languages. >
Thanks for your work. I'm gonna take a vote on Rust syntax #[Attr] cause it's more than similar it's a copy of syntax which in Rust has other few extensions which we might consider in a future like for instance, a file scoped annotations. It has the benefit of reusing the same syntax as another language and allows the code works with both PHP 7 and PHP 8 which IMO is a huge benefit for a smooth migration. Cheers, Michał Marcin Brzuchalski