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
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.
Best regards,
Theodore
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
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
Hi Theodore,
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
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:
Hi Theodore,
On Thu, 4 Jun 2020 at 00:55, Theodore Brown theodorejb@outlook.com
wrote: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
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
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
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
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
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.
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?
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
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?
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.
Hey,
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.
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
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
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
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.
-
"@@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. -
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? -
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. -
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. -
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]
Hi Theodore,
Hi Rowan,
Thanks for the feedback. I added replies inline.
I find the "objective" reasons in this RFC to be greatly exaggerated.
@@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.
- 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:
<<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.
- 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).
- 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.
- 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
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.
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
andT_SR
). The
proposed@@
syntax uses a newT_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]
Hi Rowan,
The
::
token in the parser is calledT_PAAMAYIM_NEKUDOTAYIM
, and
personally I findT_SL
andT_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 likenew 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
If
<<Foo( <<Bar>> )>>
means something likenew 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]
Hi Rowan,
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:
// 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
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
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
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:
-
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? -
#[]
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.
<<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:
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
Hi Theodore,
// 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
Hi Markus,
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]
I noticed that my
@
character did bleed/meld almost with the first
character of the attribute name...wide characters like theM
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:
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
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
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
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.
Best regards,
Theodore
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
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.
#[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
+1
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.Best regards,
Theodore
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!
Hi Benjamin,
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.
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
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.
Hi Sebastian,
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
On Tue, Jun 9, 2020 at 6:57 PM Theodore Brown theodorejb@outlook.com
wrote:
Hi Benjamin,
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.
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--
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
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
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 withzend_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
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
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--
To unsubscribe, visit: https://www.php.net/unsub.php
Thank you for your work.
Cheers,
Márcio
Hi Theodore,
wt., 16 cze 2020 o 18:57 Theodore Brown theodorejb@outlook.com napisał(a):
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