원문: https://wiki.php.net/rfc/shorter_attribute_syntax
PHP 8.0에선 많은 내용들이 추가되면서, rfc들도 많이 요청되면서 다양한 토론들이 이루어지고 있습니다.
해당 rfc는 2020/06/03 23:24
에 최초로 생성된 rfc이며, 내부 검토를 마치고 토론중에 있습니다.
주장도 함리적이고, 내용들에 대해서 자세한 예시까지 해줘서 해당 rfc를 간단한게 정리해보았습니다.
PHP RFC: Shorter Attribute Syntax
Introduction
우리는 PHP 8.0에서 속성 구문을 <<Attr>>
대신 @@Attr
을 사용할 것을 제안합니다.
저번달 초, Attributes v2는 PHP 8.0적용되는 것이 승인되었으며, 투표 동안 <<Attr>>
과 @:Attr
의 구문중에서 <<Attr>>
구문이 3/4에게 선택 되었습니다.
하지만, 이 구문은 몇 가지 주목할만한 단점이 있습니다.
1. 장황함 (Verbosity)
아래의 RFC 예시에선 속성의 이름 보다 시프트 토큰(<<>>
)에 사용되는 문자가 더 많습니다.
<<Jit>> function foo() {}
특히 하나 이상의 속성이 필요할땐 이 구문은 한눈에 보기 어려울 수 있습니다.
이를 완화 하기위해 속성 수정 RFC에선 여러개의 속성에서 하나의 시프트 토큰을 사용하는 방법을 제안 했습니다.
<<Attr1("foo"), Attr2("bar")>> public function test() {}
하지만, 이 방법은 다른 문제가 있습니다. 속성을 추가, 삭제하려면 여러줄을 수정되어 diff에 노이즈가 생기게 됩니다.
다만, 이 제한은 후행 쉼표를 허용해 다음과 같이 작성 하여 해결 할 수 있습니다.
<< Attr1("foo"), Attr2("bar"), >> public function test() {}
하지만, 스프트 토큰에 두개의 추가 행이 필요하며, 속성끼리 서로 이동할 때에 여러 줄이 수정되어지게 됩니다.
2. 중접 된 속성의 부재 (Lack of nested attributes)
중접된 주석은 Doctrine에서 많이 이용 되고 있으며, 여기서 그 예를 볼 수 있다.
@JoinTable( name="User_Group", joinColumns={@JoinColumn(name="User_id", referencedColumnName="id")}, inverseJoinColumns={@JoinColumn(name="Group_id", referencedColumnName="id")} )
<<>>
구문(및 잠재적 속성 그룹화)으로 속성을 중접하는 방법은 새로운 Attr 표현식을 허용하는 것입니다.
하지만, 구현하기 쉽지 않으며, 혼란을 야기할수 있습니다. (예시로 new Foo()
는 허용되지만, Foo::create()는 작동되지 않습니다).
결국 이것은 const 표현식에 많은 변경이 필요하기에 구현 중 포기되었습니다.
3. 제너릭과의 혼동 (Confusion with generics)
속성과 제너릭의 구문간에 기술적으로 충돌은 없지만, PHP에서 제너릭이 지원되면 속성과 제너릭이 사용되는 위치를 한눈에 파악하기 더 여러울 수 있습니다.
4. 쉬프트 연산자와 const 인수와의 혼동 (Confusion with shift operators and const arguments)
시프트 토큰을 재사용 하면, 상수 표현식인지, 멀티 속성인지, 또는 쉬프트 토큰인지 식별하기 어려울 수 있습니다.
<<Bar(2 * (3 + 3)>>Baz, (4 + 5) * 2)>> function foo() {}
물론 이 이런 상황에서의 쉬프트 토큰은 거의 사용되지 않으므로 마니어너한 문제입니다만,
만약 그룹화 된 속성 제한이 승인되면, 쉼표로 구분된 속성과 속성인수간의 유사한 혼동이 있을 수 있습니다.
<<Attr1(2 * 3 + 3), Bar(4 + 5 * 2)>> <<Attr2(2 * (3 + 3), Baz, (4 + 5) * 2)>> function foo() {}
5. 다른 언어와 유사하지 않음 (Dissimilarity to other languages)
대부분의 C 패밀리 언어들은 속성 구문에 [Attr]
또는 @Attr
를 사용하며ㅡ, 4개가 아닌 1~2개의 문자만 필요합니다. (아래의 비교 참고)
Proposal
PHP8.0에서 <<Attr>>
구문 대신에 @@Attr
구문을 사용합시다.
그렇게하면 위의 문제가 해결되며, 속성이 있는 대부분읜 다른 언어와 비교하여 절반 정도의 문자만 필요하므로 장황함이 줄어들게 됩니다.
@@Jit function foo() {}
@@
구문은 충접된 속성과 충돌 하지않아, 원하는 경우 나중에 지원을 추가하는 것이 간단해집니다. (특이 케이스나 const 표션식을 변경할 필요없이)
@@JoinTable( "User_Group", @@JoinColumn("User_id", "id"), @@JoinColumn("Group_id", "id"), ) private $groups;
더 짧은 구문은 제너릭 또는 스프트 토큰과 달리 속성이 사용되는 위치를 쉽게 알 수 있어 코드 가독성을 향상 시킬 수 있습니다.
@@Attr1("foo") @@Attr2("bar") // 이 라인은 다른줄과 독립적으로 추가, 삭제할 수 있습니다. public function test() {}
Discussion
왜 “@:” 구문을 반대 합니까?
우선 “@;”와 같은 실수로 오타가 발생하기 쉽다는 것입니다.
일부 사람들의 경우 비대칭적인 문법을 싫어 하기 때문이기에 PHP의 토큰들과 잘 맞지 않기 때문입니다.@@
문법은 위 두가지 사항을 모두 해결합니다.
왜 키워드로 대신 사용하지 않습니까?
기호 대신 키워드를 사용하는것은 좋습니다.
attribute Foo(); function myFunc() {}
하지만, 제안의 목적은 덜 일반적이고 다른 언어들에서 공통적으로 사용되는 속성 구문과 더 잘맞는 구문에 도달 하는 것입니다.
키워드를 사용하게되면 이러한 목표를 충족하지 못하게됩니다.
구문의 선택은 우리가 주관이 아닌 익숙한것으로 해야하지 않습니까?
어느정도 동의합니다. 하지만 이 RFC가 간략화 하려는 짧은 구문을 선호하는 객관적인 이유도 있을 것입니다.
다른 언어들과의 비교
속성이 있는 다른 언어들은 구문에 [Attr]
혹은 @Attr
을 변형하여 사용합니다.
Hack은 <<Attr>>
을 사용하는 유일한 언어이지만 PHP와의 호환을 지향하지 않기 때문에 @Attr
로 이전 하는 것 같습니다.
- C#:
[Attr]
1 - C++:
[[attr]]
2 - Hack:
<<Attr>>
3 (하지만,@Attr
로 변경 중에 있습니다.) 4 - Java:
@Attr
5 - Kotlin:
@Attr
6 - Python:
@attr
7 - Rust:
#[attr]
8 - Swift:
@attr
9 - TypeScript/JS:
@Attr
10
Backward Incompatible Changes (이전 버전과 호환되지 않는 변경점)
이론적으로 BC(하위호환) 오류가 적습니다.
이후 다중 오차 억제 연산자들은 추가적인 영향이 추가될 수 있다. (예: @@@@@really_suppress_me()
). (의역)
하지만 이렇게 사용하는 것은 유용하지 않으며, 어느 곳에서도 사용되지 않을 것이다.
Vote
PHP 8.0에서 속성 구문으로 제안된 @@
를 사용 하시겠습니까? Yes/No [현재(2020/06/04)는 토론중입니다]
References
- Previous discussion about nested attributes: https://externals.io/message/108907#109623 and https://externals.io/message/108907#109688
- Previous comments in favor of
@@
: https://externals.io/message/109713#109742
내용이 재미 있어보이고 좋은 의견이여서 번역해 봤습니다만,
개인적인 의견으론 Hack처럼 @
연산자를 버리고 @Attr
로 가는것도 괜찮아 보이는것같습니다. ㅎㅎ